Skip to content
On this site

Automations

A workflow that runs per contact. An event enrols someone at the trigger, and the graph carries them through sends, delays and branches until it runs out.

Lifecycle

An automation is an identity plus immutable versions. Creating one writes version 1. A PATCH carrying steps and connections writes the next one and points the automation at it — that PATCH is the publish. A run already in flight keeps the version it started on, so publishing never rewrites what someone is halfway through.

status gates enrolment and nothing else: disabled stops new runs starting and leaves live ones alone. POST /automations/{automation_id}/stop is the one that disables and cancels every run still going; deleting does the same and answers 404 from that moment.

Steps and connections

A graph is a list of steps, each with a key unique within the version, and a list of connections between those keys. Exactly one step is the trigger, every other step is reachable from it, and the whole thing is acyclic. At most 150 steps.

Automation step types
Step typeDoes
triggerThe one entry point. config.event_name is a custom event of yours, or a built-in one under the rasket: prefix.
send_emailSends a published template through the ordinary send transaction: quota, suppressions, unsubscribe headers and email.* events all behave as they do for POST /emails.
delayParks the run until a moment: { duration: "3 days" } or { until: "2026-10-01T09:00:00Z" }, at most 30 days out.
conditionA rule tree over the contact. Its two outgoing edges are condition_met and condition_not_met; it takes no default.
contact_updateSets first name, last name, unsubscribed or declared properties to literal values.
add_to_segmentAdds the contact to one of your segments.
topic_updateOpts the contact in or out of one topic.

A connection is { from, to, type }, where type is default, condition_met or condition_not_met and defaults to default. Every step but a condition has at most one outgoing edge; a condition has at most one of each branch.

The whole graph is checked at once, against your own team: every template, segment, topic, contact property and custom event it names has to resolve. A failure is 422 validation_error with one entry in errors[] per offending step key, so an editor can put each message on its own node rather than fixing one problem per round trip.

Two step types in the schema are not available in this release — wait_for_event and contact_delete — along with the timeout and event_received connections that belong to the first. A graph naming any of them is refused with that reason.

Runs

  • One run per contact per enrolling event. Two sends of the same event are two runs; one send redelivered internally is still one.
  • A run parked on a delay reports running, and ?status=running returns it. A delay is a timestamp the run wakes at, not a process holding a thread — so a worker restart mid-workflow loses nothing, and the public status enum needs no fifth word for it.
  • ?status= on the run list takes a comma-separated list of running, completed, failed and cancelled. A member outside those four is 422 invalid_parameter naming it.
  • A single run's steps[] come back in graph order — a walk from the trigger of the version that run pinned, taking condition_met before condition_not_met.

Endpoints

POST /automations

The workflow and version 1 of its graph, in one call.

Body

Body
FieldTypeDescription
name*stringA name for the dashboard.
statusstringenabled or disabled. Defaults to disabled, so nothing enrols yet.
steps*object[]The steps of the workflow, at most 150. Each is { key, type, config } with a key unique within the graph. Exactly one step must be a trigger.
connections*object[]The edges between steps: { from, to, type }, where from and to are step keys and type is default, condition_met or condition_not_met. Omitting type means default.
curl -X POST "https://api.rasket.com/automations" \
  -H "Authorization: Bearer $RASKET_API_KEY" \
  -H "User-Agent: acme-billing/1.0" \
  -H "Content-Type: application/json" \
  -d '{
  "name": "Trial nudge",
  "status": "disabled",
  "steps": [
    {
      "key": "start",
      "type": "trigger",
      "config": {
        "event_name": "trial.started"
      }
    },
    {
      "key": "welcome",
      "type": "send_email",
      "config": {
        "template": {
          "id": "0199d2f1-4c4e-7a20-9c31-6f2b8a0e5e05",
          "variables": {
            "plan": "pro"
          }
        }
      }
    },
    {
      "key": "wait",
      "type": "delay",
      "config": {
        "duration": "3 days"
      }
    },
    {
      "key": "check",
      "type": "condition",
      "config": {
        "type": "rule",
        "field": "properties.activated",
        "operator": "eq",
        "value": true
      }
    },
    {
      "key": "tag",
      "type": "contact_update",
      "config": {
        "properties": {
          "lifecycle": "activated"
        }
      }
    },
    {
      "key": "onboard",
      "type": "add_to_segment",
      "config": {
        "segment_id": "0199d2f1-4c4e-7a20-9c31-6f2b8a0e5e04"
      }
    }
  ],
  "connections": [
    {
      "from": "start",
      "to": "welcome"
    },
    {
      "from": "welcome",
      "to": "wait"
    },
    {
      "from": "wait",
      "to": "check"
    },
    {
      "from": "check",
      "to": "tag",
      "type": "condition_met"
    },
    {
      "from": "check",
      "to": "onboard",
      "type": "condition_not_met"
    }
  ]
}'

Response 201

{
  "object": "automation",
  "id": "0199d2f1-4c4e-7a20-9c31-6f2b8a0e5e01"
}
  • The whole graph is validated at once. A failure is 422 validation_error with one entry in errors[] per offending step key, not the first problem found.
  • Every template, segment, topic, contact property and custom event the graph names must already exist in your team.
  • wait_for_event and contact_delete are parsed and refused in this release: a graph naming either is 422 validation_error.

GET /automations

Every automation, newest first.

Query parameters

Query parameters
FieldTypeDescription
statusstringenabled or disabled. Anything else is 422 invalid_parameter.
limitintegerHow many items to return, 1–100. Defaults to 20.
afterstringReturn the page that follows this item ID. Mutually exclusive with before.
beforestringReturn the page that precedes this item ID. Mutually exclusive with after.
curl -X GET "https://api.rasket.com/automations?status=enabled&limit=20" \
  -H "Authorization: Bearer $RASKET_API_KEY" \
  -H "User-Agent: acme-billing/1.0"

Response 200

{
  "object": "list",
  "has_more": false,
  "data": [
    {
      "id": "0199d2f1-4c4e-7a20-9c31-6f2b8a0e5e01",
      "name": "Trial nudge",
      "status": "enabled",
      "created_at": "2026-09-11T12:00:00.000Z",
      "updated_at": "2026-09-11T12:00:00.000Z"
    }
  ]
}
  • Items carry no graph. Retrieve one automation for its steps and connections.

GET /automations/{automation_id}

With the active version's graph — the one new enrolments will run.

Path parameters

Path parameters
FieldTypeDescription
automation_id*stringThe automation's ID.
curl -X GET "https://api.rasket.com/automations/{automation_id}" \
  -H "Authorization: Bearer $RASKET_API_KEY" \
  -H "User-Agent: acme-billing/1.0"

Response 200

{
  "object": "automation",
  "id": "0199d2f1-4c4e-7a20-9c31-6f2b8a0e5e01",
  "name": "Trial nudge",
  "status": "enabled",
  "created_at": "2026-09-11T12:00:00.000Z",
  "updated_at": "2026-09-11T12:00:00.000Z",
  "steps": [
    {
      "key": "start",
      "type": "trigger",
      "config": {
        "event_name": "trial.started"
      }
    },
    {
      "key": "welcome",
      "type": "send_email",
      "config": {
        "template": {
          "id": "0199d2f1-4c4e-7a20-9c31-6f2b8a0e5e05",
          "variables": {
            "plan": "pro"
          }
        }
      }
    },
    {
      "key": "wait",
      "type": "delay",
      "config": {
        "duration": "3 days"
      }
    },
    {
      "key": "check",
      "type": "condition",
      "config": {
        "type": "rule",
        "field": "properties.activated",
        "operator": "eq",
        "value": true
      }
    },
    {
      "key": "tag",
      "type": "contact_update",
      "config": {
        "properties": {
          "lifecycle": "activated"
        }
      }
    },
    {
      "key": "onboard",
      "type": "add_to_segment",
      "config": {
        "segment_id": "0199d2f1-4c4e-7a20-9c31-6f2b8a0e5e04"
      }
    }
  ],
  "connections": [
    {
      "from": "start",
      "to": "welcome",
      "type": "default"
    },
    {
      "from": "welcome",
      "to": "wait",
      "type": "default"
    },
    {
      "from": "wait",
      "to": "check",
      "type": "default"
    },
    {
      "from": "check",
      "to": "tag",
      "type": "condition_met"
    },
    {
      "from": "check",
      "to": "onboard",
      "type": "condition_not_met"
    }
  ]
}
  • steps and connections come from the **active** version. A run already in flight keeps the version it started on.
  • Every connection carries a type, even the ones you created without one.
  • An automation that belongs to another team, or that has been deleted, is 404 not_found.

PATCH /automations/{automation_id}

Rename, enable, disable — or publish a new version of the graph.

Path parameters

Path parameters
FieldTypeDescription
automation_id*stringThe automation's ID.

Body

Body
FieldTypeDescription
namestringA new name.
statusstringenabled or disabled.
stepsobject[]The steps of the workflow, at most 150. Each is { key, type, config } with a key unique within the graph. Exactly one step must be a trigger.
connectionsobject[]The edges between steps: { from, to, type }, where from and to are step keys and type is default, condition_met or condition_not_met. Omitting type means default.
curl -X PATCH "https://api.rasket.com/automations/{automation_id}" \
  -H "Authorization: Bearer $RASKET_API_KEY" \
  -H "User-Agent: acme-billing/1.0" \
  -H "Content-Type: application/json" \
  -d '{
  "status": "enabled"
}'

Response 200

{
  "object": "automation",
  "id": "0199d2f1-4c4e-7a20-9c31-6f2b8a0e5e01"
}
  • Sending steps and connections writes the **next version** and points the automation at it. The two must be sent together; one without the other is 422 validation_error.
  • A PATCH with only name and/or status creates no version.
  • status: "disabled" stops new enrolments and leaves runs already in flight alone. To stop those too, use the stop endpoint.
  • An empty body is 422. Send at least one of name, status, or the graph pair.

DELETE /automations/{automation_id}

Cancels every live run, then removes it.

Path parameters

Path parameters
FieldTypeDescription
automation_id*stringThe automation's ID.
curl -X DELETE "https://api.rasket.com/automations/{automation_id}" \
  -H "Authorization: Bearer $RASKET_API_KEY" \
  -H "User-Agent: acme-billing/1.0"

Response 200

{
  "object": "automation",
  "id": "0199d2f1-4c4e-7a20-9c31-6f2b8a0e5e01",
  "deleted": true
}
  • Soft-deletes: the automation is 404 not_found from this moment, on every operation.
  • Each cancelled run raises automation.run.failed with the reason cancelled.

POST /automations/{automation_id}/duplicate

A disabled copy of the active version, at version 1.

Path parameters

Path parameters
FieldTypeDescription
automation_id*stringThe automation's ID.
curl -X POST "https://api.rasket.com/automations/{automation_id}/duplicate" \
  -H "Authorization: Bearer $RASKET_API_KEY" \
  -H "User-Agent: acme-billing/1.0"

Response 201

{
  "object": "automation",
  "id": "0199d2f1-4c4e-7a20-9c31-6f2b8a0e5e09"
}
  • The copy is named <name> (copy) and is always disabled, whatever the source's status.
  • The graph is copied verbatim and is not re-validated — what it copies was valid when it was published.
  • The source is untouched.

POST /automations/{automation_id}/stop

Disable it and cancel every run still going.

Path parameters

Path parameters
FieldTypeDescription
automation_id*stringThe automation's ID.
curl -X POST "https://api.rasket.com/automations/{automation_id}/stop" \
  -H "Authorization: Bearer $RASKET_API_KEY" \
  -H "User-Agent: acme-billing/1.0"

Response 200

{
  "object": "automation",
  "id": "0199d2f1-4c4e-7a20-9c31-6f2b8a0e5e01",
  "status": "disabled"
}
  • This is the difference between stop and PATCH { status: "disabled" }: the PATCH stops new enrolments, stop also cancels the runs already in flight.
  • Stopping an automation that is already disabled still cancels its live runs, and still answers 200.

GET /automations/{automation_id}/runs

One run per contact per enrolling event, newest first.

Path parameters

Path parameters
FieldTypeDescription
automation_id*stringThe automation's ID.

Query parameters

Query parameters
FieldTypeDescription
statusstringA comma-separated list of running, completed, failed and cancelled. A member outside those four is 422 invalid_parameter.
limitintegerHow many items to return, 1–100. Defaults to 20.
afterstringReturn the page that follows this item ID. Mutually exclusive with before.
beforestringReturn the page that precedes this item ID. Mutually exclusive with after.
curl -X GET "https://api.rasket.com/automations/{automation_id}/runs?status=running%2Cfailed&limit=20" \
  -H "Authorization: Bearer $RASKET_API_KEY" \
  -H "User-Agent: acme-billing/1.0"

Response 200

{
  "object": "list",
  "has_more": false,
  "data": [
    {
      "id": "0199d2f1-4c4e-7a20-9c31-6f2b8a0e5e02",
      "status": "running",
      "started_at": "2026-09-11T12:00:00.000Z",
      "completed_at": null,
      "created_at": "2026-09-11T12:00:00.000Z"
    }
  ]
}
  • A run parked on a delay is reported as running, and ?status=running returns it: a delay is a timestamp the run wakes at, not a process holding a thread.
  • Items carry no steps. Retrieve one run for its step log.

GET /automations/{automation_id}/runs/{run_id}

One contact's journey, step by step, in graph order.

Path parameters

Path parameters
FieldTypeDescription
automation_id*stringThe automation's ID.
run_id*stringThe run's ID.
curl -X GET "https://api.rasket.com/automations/{automation_id}/runs/{run_id}" \
  -H "Authorization: Bearer $RASKET_API_KEY" \
  -H "User-Agent: acme-billing/1.0"

Response 200

{
  "object": "automation_run",
  "id": "0199d2f1-4c4e-7a20-9c31-6f2b8a0e5e02",
  "status": "completed",
  "started_at": "2026-09-11T12:00:00.000Z",
  "completed_at": "2026-09-14T12:00:00.000Z",
  "created_at": "2026-09-11T12:00:00.000Z",
  "steps": [
    {
      "key": "start",
      "type": "trigger",
      "status": "completed",
      "started_at": "2026-09-11T12:00:00.000Z",
      "completed_at": "2026-09-11T12:00:00.000Z",
      "output": {
        "enrolled": true
      },
      "error": null,
      "created_at": "2026-09-11T12:00:00.000Z"
    },
    {
      "key": "welcome",
      "type": "send_email",
      "status": "completed",
      "started_at": "2026-09-11T12:00:00.000Z",
      "completed_at": "2026-09-11T12:00:00.000Z",
      "output": {
        "email_id": "0199d2f1-4c4e-7a20-9c31-6f2b8a0e5e0a"
      },
      "error": null,
      "created_at": "2026-09-11T12:00:00.000Z"
    }
  ]
}
  • steps is a breadth-first walk from the trigger of the version this run pinned, taking condition_met before condition_not_met — the order the editor draws them.
  • output and error are whatever the step produced; their shape depends on the step type.
  • A run of a different automation, or of another team, is 404 not_found.

GET /automations/{automation_id}/versions

Every published graph, newest first, and which one new enrolments run.

Path parameters

Path parameters
FieldTypeDescription
automation_id*stringThe automation's ID.
curl -X GET "https://api.rasket.com/automations/{automation_id}/versions" \
  -H "Authorization: Bearer $RASKET_API_KEY" \
  -H "User-Agent: acme-billing/1.0"

Response 200

{
  "object": "list",
  "has_more": false,
  "data": [
    {
      "id": "0199d2f1-4c4e-7a20-9c31-6f2b8a0e5e06",
      "version_number": 2,
      "active": true,
      "trigger_event_name": "trial.started",
      "trigger_segment_id": null,
      "steps": [],
      "connections": [],
      "created_by": {
        "type": "api_key",
        "id": "a4d2f0c8-5b31-4e7a-9c62-8f0b1d4e6a75"
      },
      "created_at": "2026-09-11T12:00:00.000Z"
    }
  ]
}
  • steps and connections are the graph as it was published; they are elided here.
  • To run an earlier version again, PATCH /automations/{automation_id} with its steps and connections. That publishes it as the next version.