API reference

Automations

Start an automation from your own system — an order, a signup, a form — and track what happened next. Build the flow in the MYWA app; the API decides who goes through it and when.

List automations

GET/automations

Requires automations:read. Returns every automation you can start, with how many people it has enrolled and when it last ran. Archived automations aren’t listed.

bash
curl "$MYWA_API/automations" -H "Authorization: Bearer $MYWA_KEY"
json
{
  "automations": [
    {
      "id": "wf_9f2",
      "name": "Order follow-up",
      "description": "Thank the customer, then ask for a review after delivery",
      "status": "ACTIVE",
      "trigger": "From another app",
      "enrolled": 412,
      "lastRunAt": "2026-08-27T09:14:02.000Z"
    }
  ]
}

Start an automation for a contact

POST/automations/:id/enroll

Requires automations:write. Identify the person by phone or contactId — one of them is required.

Body parameters

FieldTypeDescription
phone
stringE.164 phone number. A number that is new to your workspace creates the contact. Required unless you send contactId.
contactId
stringAn existing contact id. Required unless you send phone.
name
stringContact display name.
attributes
objectKey→value pairs (string, number, or boolean). Merged into the contact, not replaced.
vars
objectData for this run only — not saved on the contact. Steps read it as {{vars.hook.<key>}}.

Unknown fields are rejected with 400 validation_error, so a typo never silently drops data.

curl -X POST "$MYWA_API/automations/wf_9f2/enroll" \
  -H "Authorization: Bearer $MYWA_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "phone": "+15551234567",
    "name": "Jane Doe",
    "attributes": { "city": "Austin" },
    "vars": { "orderId": "A-1049", "amount": 49.99 }
  }'

Returns 202 Accepted — the run is queued, not finished. contactCreated tells you whether the phone number was new.

json
{ "runId": "run_7c1", "contactId": "cts_31a…", "contactCreated": true }

Using vars in your steps

Anything under vars is available to the automation’s steps. With the request above, a message step can say Thanks for order {{vars.hook.orderId}}!.

The automation must be live

It has to be published and have an active trigger. Otherwise the request fails with 409 not_published or 409 no_trigger. Your workspace’s guardrails (re-entry, opt-outs, plan limits) still apply — see automation errors for which ones are worth retrying.

List runs

GET/automations/:id/runs

Requires automations:read. Test runs from the builder aren’t included.

Query parameters

FieldTypeDescription
status
stringOne of PENDING, RUNNING, WAITING_REPLY, SLEEPING, WAITING_EVENT, COMPLETED, FAILED, CANCELLED.
contactId
stringOnly runs for this contact.
limit
number1–100. Defaults to 25.
cursor
stringThe nextCursor from the previous page.
bash
curl "$MYWA_API/automations/wf_9f2/runs?status=COMPLETED&limit=25" \
  -H "Authorization: Bearer $MYWA_KEY"
json
{
  "runs": [ { "id": "run_7c1", "status": "COMPLETED", "…": "…" } ],
  "nextCursor": "run_6b0…"
}

Pass cursor=<nextCursor> to fetch the next page. nextCursor is null on the last page.

Get one run

GET/automation-runs/:runId

Requires automations:read. Fetch a run by the runId you got when you started it — no need to know which automation it belongs to.

bash
curl "$MYWA_API/automation-runs/run_7c1" -H "Authorization: Bearer $MYWA_KEY"
json
{
  "id": "run_7c1",
  "workflowId": "wf_9f2",
  "contactId": "cts_31a…",
  "conversationId": "cnv_88b…",
  "status": "COMPLETED",
  "currentNodeId": null,
  "error": null,
  "exitReason": "end_node",
  "goal": {
    "name": "Left a review",
    "reachedAt": "2026-08-27T09:31:44.000Z",
    "value": null,
    "currency": null
  },
  "startedAt": "2026-08-27T09:14:02.000Z",
  "finishedAt": "2026-08-27T09:31:45.000Z"
}
FieldTypeDescription
status
stringWhere the run is now: still going (PENDING, RUNNING), paused (WAITING_REPLY, SLEEPING, WAITING_EVENT), or done (COMPLETED, FAILED, CANCELLED).
currentNodeId
string | nullThe step the run is on. null once it has finished.
error
string | nullWhy the run failed. null unless status is FAILED.
exitReason
string | nullHow a finished run ended, e.g. end_node when it reached the end of the flow.
goal
object | nullnull until the run passes a "Goal reached" step; then the goal name, when it was reached, and an optional value and currency.
startedAt
stringISO-8601 time the run started.
finishedAt
string | nullISO-8601 time the run ended. null while it is still going.
const run = await mywa.get(`/automation-runs/${runId}`);

if (run.goal) console.log('goal reached:', run.goal.name);
else if (run.status === 'FAILED') console.error('run failed:', run.error);
else console.log('status:', run.status);

See it in a real flow

The Use cases guide starts an order follow-up from a checkout and connects a website form through Zapier.
MywaHey 👋 got a question? Say hi, a real human replies here.now