Per-contact run timeline
The ordered step history of one contact's run. A send_filtered event
carries filter_tier/filter_reason explaining why the send was skipped
(consent opt-out, global unsubscribe, suppression, or frequency cap).
A frequency-cap skip's detail says which cap stopped it and who
spent the budget, e.g. frequency cap reached (3 sends in 14d across workflows: New-Signup Onboarding ×2, Passive Interest ×1), frequency cap reached (2 sends in 14d in this workflow) for a workflow declaring
frequency cap N per D in this workflow, or org frequency cap reached (…) when such a workflow had room but the org-wide default,
which always counts every workflow's sends, did not.
A call webhook step writes webhook_called when it is dispatched and
then exactly one of webhook_delivered, webhook_failed or
webhook_skipped; webhook_held appears in between when the workflow
requires review before sending. Their detail is a JSON object rather
than a sentence — see the detail field. A webhook_shadowed event's
detail is reduced to {key, label} on this API: the recorded envelope
carries the contact's attributes and stays behind the dashboard.
Path parameters
id string required The workflow's UUID or, when the value does not parse as a UUID, its org-unique key. Unknown handles read as 404 not_found. Accepted on every workflow route, read and write alike.
runId string<uuid> required The run id.
Responses
Errors follow the RFC 7807 problem format — see the error reference.
run_id string<uuid> required events array<object> required Each entry in events:
node_path string required repeat_iteration integer optional split_arm integer optional event_type string required The run kinds: enrolled, step_entered, wait_started, wait_met, wait_timed_out, send_filtered, send_held, send_skipped, send_failed, send_deferred, exited, completed, failed.
The call webhook kinds: webhook_called (the call was dispatched), webhook_delivered (the endpoint answered 2xx), webhook_failed (it answered no, could not be reached, or the 30-minute deadline passed — the run takes the failed: arm), webhook_held (parked in the approvals queue) and webhook_skipped (a reviewer skipped it; the run continues after the whole statement, NOT into the failed: arm).
The shadow kinds, written by a workflow running in shadow mode, which records what it would have done and does none of it: send_shadowed, attr_set_shadowed, list_add_shadowed and webhook_shadowed.
exit_kind string optional exit_name string optional detail string optional Human-readable free-text context on most kinds. On the webhook_* kinds it is a JSON object serialised as a string: webhook_called carries {key, label, delivery_id}; webhook_delivered {key, label, status_code, attempts, response_time_ms}; webhook_failed {key, label, status_code, attempts, failure_reason}, with status_code absent when nothing answered; webhook_held and webhook_skipped {key, label}, the latter plus the reviewer's detail.
webhook_shadowed carries {key, label} on this API only. The recorded envelope a shadow run would have POSTed includes the contact's attributes, so it is not projected here; read it in the dashboard.
filter_tier string optional On a send_filtered event, the gate that dropped the send: frequency_cap, account, or topic.
filter_reason string optional On a send_filtered event, the specific cause: frequency_cap, suppressed, unsubscribed_all, or opted_out.
delivery_outcome string enum optional On the step_entered event of a send step whose email went out, what SES did with it afterwards. rendering_failed: SES accepted the send and then could not render the template, so nothing was delivered. bounced includes an SES reject. complained: delivered, then marked as spam. pending: no delivery outcome reported yet. When a message has several events the worst wins, in that order. Absent on every other event.
One of: delivered, bounced, complained, rendering_failed, pending
delivery_reason string optional With delivery_outcome: SES's rendering error for rendering_failed (for example "Attribute 'frontendUrl' is not present in the rendering data."), or the bounce type and sub-type for bounced.
occurred_at string<date-time> required code is internal_error. The
request_id field can be quoted to SendOps support to investigate.
application/problem+json