Analytics and run replay
These endpoints power the flow builder's analytics. They are read-only, need the flows:read scope, and only ever return data from your own workspace. Members who may only see some contacts get a 404 for a run of a contact they can't see, and analytics leave out those contacts' runs and failures. Totals still count every run.
Time window
Every analytics endpoint takes optional since and until query parameters (ISO 8601, UTC). The default is the last 30 days. Detailed run data is kept for 30 days, so the step endpoints never reach further back. Each response's window shows the range that was actually used.
Step stats are rounded to the minute and cached for 60 seconds. The step stats endpoint allows 30 requests per minute per user; above that it returns 429 with a Retry-After header.
Step stats
curl "https://api.sendseven.com/api/v1/flows/FLOW_ID/observability/steps?since=2026-10-01T00:00:00Z" \
-H "Authorization: Bearer YOUR_TOKEN"
{
"window": {"since": "2026-10-01T00:00:00Z", "until": "2026-11-01T00:00:00Z"},
"steps": [
{"node_id": "ask_email", "reached": 120, "completed": 112, "failed": 0,
"waiting": 6, "dropped": 2, "drop_off_pct": 1.7}
],
"edges": [
{"from": "ask_email", "to": "save_lead", "branch": "default", "count": 112}
]
}
The counts cover runs that started in the window, and each run counts once per step:
| Field | Meaning |
|---|---|
reached | Runs that got to the step |
completed | Runs where the step finished successfully |
failed | Runs where the step failed |
waiting | Runs waiting on the step right now |
dropped | Runs that ended on the step even though it has a next step (for example, canceled) |
drop_off_pct | dropped / reached × 100, one decimal place |
steps lists the steps of the current flow. edges lists the connections of the current flow, and count is the number of runs that took each one.
Recent failures of a step
curl "https://api.sendseven.com/api/v1/flows/FLOW_ID/observability/steps/save_lead/failures?limit=20" \
-H "Authorization: Bearer YOUR_TOKEN"
{
"items": [
{"run_id": "RUN_ID", "at": "2026-10-28T09:12:44Z",
"reason_code": "delivery_failed", "reason_label": "Message could not be delivered",
"message": "Message could not be delivered: ...",
"contact": {"id": "CONTACT_ID", "display_name": "Ada Lovelace"}}
]
}
Failures are listed newest first. limit runs from 1 to 100 and defaults to 20. In message, secrets, credentials and URLs are masked, and long text is shortened. contact is null when the run has no contact. display_name needs the contacts:read scope; without it, it shows the contact id. Failures of contacts you are not allowed to see are left out.
reason_code | Meaning |
|---|---|
delivery_failed | The message could not be delivered |
step_crashed | The step stopped with an unexpected error |
node_missing | The step no longer exists in the flow |
engine_error | The flow could not continue from this step |
step_error | The step reported an error (for example, an API call that failed) |
Needs attention
curl "https://api.sendseven.com/api/v1/flows/FLOW_ID/observability/attention" \
-H "Authorization: Bearer YOUR_TOKEN"
{
"window": {"since": "2026-10-02T00:00:00Z", "until": "2026-11-01T00:00:00Z"},
"groups": [
{"node_id": "save_lead", "node_name": "API Call · POST example.com",
"kind": "failed", "reason_code": "step_error", "reason_label": "The step reported an error",
"count": 14, "sample_run_ids": ["RUN_ID", "RUN_ID_2"]}
]
}
Groups are sorted by count, highest first, and each one carries up to 5 example run ids.
kind: "failed"groups the failures in the window by step andreason_code(same codes as above).kind: "stuck"looks at runs that are active right now, whatever the window. A run counts as stuck when it:- has waited on a step for more than 7 days (
waiting_too_long), - has been stuck in the middle of a step (
running_too_long), or - waits on a step that was removed from the flow (
node_removed).
- has waited on a step for more than 7 days (
Replaying a run
GET /api/v1/flows/{id}/runs/{run_id}/replay returns the contact, the run, and a time-ordered events list.
- Message events are
message_sent/message_received. Theirbodyis only filled with theconversations:readscope; without it, it isnull. - Step events are
type: "node_executed"and also carry:branch: the branch the step took, for example"yes","default"or"success". It isnullwhen the step did not branch or is still waiting.variables: the flow variables this step set or changed, as{name: value}. Secrets are masked and long values are shortened.
To find a contact's runs, list them with GET /api/v1/flows/{id}/runs?contact_id=CONTACT_ID.