Skip to content

Update an automation

Platform module

PATCH/automations/{id}automations.update

An automation (Section 7.3, ADR 0047): when a domain event of the trigger type happens in the org and the conditions hold, the actions run in order as the owner through public API operations, so row level security and capabilities decide every write. The owner is whoever last changed what it does or turned it on. Needs the automations plan feature (Pro and above) to create, change or turn on (plan_feature_required: 422); without it an automation can still be turned off and deleted. Saving validates the documents as automation.schema.json does (automation_conditions_invalid, automation_actions_invalid: 422) and checks the actions fit the trigger (automation_action_needs_record, automation_action_needs_commentable_subject, automation_person_not_member, automation_webhook_unknown: 422). Updates the fields sent; omitted fields are unchanged. Requires `If-Match` with the current `ETag`: a stale tag returns 412 and a missing tag returns 428.

  • Requires the capability org.automations.write.
  • OAuth scopes: org.
  • Send If-Match with the ETag you read. A stale tag returns 412; a missing tag returns 428.
  • Error statuses: 400, 401, 404, 412, 422, 428, 429. Errors are RFC 9457 problem details.

Path and query parameters

automations.update: Path and query parameters
FieldTypeRequiredDescription
idstring (uuid)YesIdentifier of the automation.

Request body: AutomationUpdate

automations.update: AutomationUpdate
FieldTypeRequiredDescription
namestringNoName shown in Settings, Automations.Constraints: length 1 to 120
descriptionstring | nullNoWhat the automation is for.Constraints: length 1 to 500
trigger_event_typestringNoDomain event type that starts a run, from the catalog webhooks use (webhookEventTypes.list).Constraints: pattern ^[a-z][a-z_]*\.[a-z][a-z_]*$
enabledbooleanNoTrue while new events start runs.
conditionsAutomationConditionsNoAn automation's conditions: {"all": [...]} or {"any": [...]} of conditions and one-level groups, at most 20 in all. An empty list always holds.
actionsAutomationActionsNoAn automation's 1 to 10 actions, in the order they run.
{
  "name": "Pick up new tasks",
  "description": "Comments on every new task.",
  "trigger_event_type": "record.created",
  "enabled": true
}

Response 200: Automation

automations.update: Automation
FieldTypeRequiredDescription
idstring (uuid)YesIdentifier of the automation.
org_idstring (uuid)YesIdentifier of the owning organization, derived from the parent row and never accepted from the caller.
created_atstring (date-time)YesWhen the row was created.
created_bystring (uuid) | nullYesIdentifier of the person who created the row.
updated_atstring (date-time)YesWhen the row was last updated.
updated_bystring (uuid) | nullYesIdentifier of the person who last updated the row.
namestringYesName shown in Settings, Automations.Constraints: length 1 to 120
descriptionstring | nullYesWhat the automation is for.Constraints: length 1 to 500
trigger_event_typestringYesDomain event type that starts a run, from the catalog webhooks use (webhookEventTypes.list).Constraints: pattern ^[a-z][a-z_]*\.[a-z][a-z_]*$
condition_match"all" | "any"YesHow the top-level conditions combine; set from the conditions document.
owner_person_idstring (uuid)YesIdentifier of the person the actions run as.
enabledbooleanYesTrue while new events start runs.
paused_atstring (date-time) | nullYesWhen the engine turned the automation off because a run could not act as the owner; null otherwise. Turning it on again clears it.
pause_reasonstring | nullYesWhy the engine paused it: owner_left_org, owner_lost_capability, owner_cannot_sign_in or owner_access_refused.Constraints: pattern ^[a-z][a-z0-9_]*$
conditionsAutomationConditionsYesAn automation's conditions: {"all": [...]} or {"any": [...]} of conditions and one-level groups, at most 20 in all. An empty list always holds.
actionsAutomationActionsYesAn automation's 1 to 10 actions, in the order they run.
{
  "id": "0192f1e2-7c3a-7b4d-9e8f-1a2b3c4d5e6f",
  "org_id": "0192f1e2-7c3a-7b4d-9e8f-1a2b3c4d5e6f",
  "created_at": "2026-10-08T14:30:00Z",
  "created_by": "0192f1e2-7c3a-7b4d-9e8f-1a2b3c4d5e6f",
  "updated_at": "2026-10-08T14:30:00Z",
  "updated_by": "0192f1e2-7c3a-7b4d-9e8f-1a2b3c4d5e6f",
  "name": "Pick up new tasks",
  "description": "Comments on every new task.",
  "trigger_event_type": "record.created",
  "condition_match": "all",
  "owner_person_id": "0192f1e2-7c3a-7b4d-9e8f-1a2b3c4d5e6f",
  "enabled": true,
  "paused_at": "2026-10-08T14:30:00Z",
  "pause_reason": "owner_left_org",
  "conditions": {
    "all": [
      {
        "field": "data.record_kind",
        "operator": "eq",
        "value": "Task"
      }
    ]
  },
  "actions": [
    {
      "type": "add_comment",
      "body": "Picked up {{data.title}}."
    }
  ]
}

Code samples

curl -X PATCH "$XOS_BASE_URL/automations/0192f1e2-7c3a-7b4d-9e8f-1a2b3c4d5e6f" \
  -H "Authorization: Bearer $XOS_API_KEY" \
  -H 'If-Match: W/"etag-from-your-last-read"' \
  -H "Content-Type: application/json" \
  -d '{"name":"Pick up new tasks","description":"Comments on every new task.","trigger_event_type":"record.created","enabled":true}'
const { data, etag } = await xos.automations.update("0192f1e2-7c3a-7b4d-9e8f-1a2b3c4d5e6f", {
    "name": "Pick up new tasks",
    "description": "Comments on every new task.",
    "trigger_event_type": "record.created",
    "enabled": true
  }, { ifMatch: etag });
response = xos.automations.update("0192f1e2-7c3a-7b4d-9e8f-1a2b3c4d5e6f", {"name": "Pick up new tasks", "description": "Comments on every new task.", "trigger_event_type": "record.created", "enabled": True}, if_match=etag)
xos automations update 0192f1e2-7c3a-7b4d-9e8f-1a2b3c4d5e6f --data '{"name":"Pick up new tasks","description":"Comments on every new task.","trigger_event_type":"record.created","enabled":true}' --if-match auto