Sequence Lifecycle
The Sequences page covers basic operations (list, get, run, pause/resume, manage enrolled contacts). This page covers the lifecycle endpoints used to author and inspect a sequence end-to-end - typically what a CLI or build tool needs.
All endpoints share the /sequences prefix and require a Bearer API key.
| Endpoint | Method | Description |
|---|---|---|
/sequences | POST | Create a sequence (with optional steps + channels) |
/sequences/{id}/preview | GET | Read sequence + steps + channels (no enrollment) |
/sequences/{id} | PATCH | Update sequence metadata |
/sequences/{id}/steps/{step_id} | PATCH | Update a single step |
/sequences/{id}/pause | POST | Pause a live sequence |
/sequences/{id}/resume | POST | Resume a paused sequence |
/sequences/{id}/analytics | GET | Comprehensive analytics report |
/sequences/{id} | DELETE | Soft-delete (archive) a sequence |
A sequence in a transitional status (scheduling, pausing, resuming, terminating) cannot be PATCHed - you’ll get 409 Conflict. Wait for the operation to settle.
For machine-readable schemas see the interactive API docs.
Create Sequence
POST /sequences
Create a sequence in drafted status. You can optionally include steps[] and channels[] in the same call.
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Sequence name |
user_email | string | Yes | Owner email address |
description | string | No | Free-form description |
finish_on_reply | boolean | No (default true) | Stop contacting on reply |
send_in_same_thread | boolean | No | Send follow-ups in the same email thread |
wait_for_new_contacts | boolean | No | Keep sequence waiting for new enrollments |
associated_list_id | integer | No | Contact list to associate |
steps | object[] | No | Step configs - see Step config |
channels | object[] | No | Channel configs - see Channel config |
campaign_id | string | No | AI Studio campaign to link |
Step config
| Field | Type | Description |
|---|---|---|
step_order | integer | Order within the sequence |
step_type | string | EMAIL, PHONE, SMS, LINKEDIN, etc. |
input_type | string | ON_DEMAND or TEMPLATE (default ON_DEMAND) |
time_interval | integer | Delay in seconds after the previous step |
step_data | object | Step template/content data (subject, body, etc.) |
Channel config
| Field | Type | Description |
|---|---|---|
channel_id | integer | Resource ID (mailbox ID, phone ID, etc.) |
channel_value | string | The address/number itself |
channel_type | string | EMAIL, PHONE, SMS, LINKEDIN, WHATSAPP |
channel_data | object | Optional metadata |
Example
curl -X POST "https://be.graph8.com/api/v1/sequences" \ -H "Authorization: Bearer $API_KEY" \ -H "Content-Type: application/json" \ -d '{ "name": "Q2 Outbound", "user_email": "rep@graph8.com", "associated_list_id": 5, "steps": [ { "step_order": 1, "step_type": "EMAIL", "input_type": "TEMPLATE", "time_interval": 0, "step_data": {"subject": "Quick intro", "body": "Hi {{first_name}}..."} } ], "channels": [ { "channel_id": 12, "channel_value": "rep@graph8.com", "channel_type": "EMAIL" } ] }'Response 201 Created
{ "data": { "id": "seq_abc", "name": "Q2 Outbound", "status": "drafted", "created_at": "2026-04-15T10:00:00Z" }}Errors
| Status | Meaning |
|---|---|
400 | Invalid step or channel config |
Preview Sequence
GET /sequences/{sequence_id}/preview
Read-only view of a sequence with all steps and channels. Does not enroll anyone.
Example
curl "https://be.graph8.com/api/v1/sequences/seq_abc/preview" \ -H "Authorization: Bearer $API_KEY"Response
{ "data": { "id": "seq_abc", "name": "Q2 Outbound", "status": "drafted", "description": null, "steps": [ { "id": "stp_1", "step_order": 1, "step_type": "EMAIL", "input_type": "TEMPLATE", "time_interval": 0, "step_data": {"subject": "Quick intro", "body": "..."} } ], "channels": [ {"id": "ch_1", "channel_id": 12, "channel_value": "rep@graph8.com", "channel_type": "EMAIL"} ] }}Update Sequence
PATCH /sequences/{sequence_id}
Update sequence metadata. Send only the fields you want to change.
Request Body
| Field | Type | Description |
|---|---|---|
name | string | Sequence name |
description | string | Description |
is_shared | boolean | Share with the org |
finish_on_reply | boolean | Finish on reply |
send_in_same_thread | boolean | Same-thread follow-ups |
wait_for_new_contacts | boolean | Wait for new contacts |
schedule_id | string | Schedule ID |
appointment_id | integer | Appointment ID |
Example
curl -X PATCH "https://be.graph8.com/api/v1/sequences/seq_abc" \ -H "Authorization: Bearer $API_KEY" \ -H "Content-Type: application/json" \ -d '{"name": "Q2 Outbound v2", "send_in_same_thread": true}'Errors
| Status | Meaning |
|---|---|
404 | Sequence not found |
409 | Sequence is in a transitional status (scheduling, pausing, resuming, terminating) |
Update Step
PATCH /sequences/{sequence_id}/steps/{step_id}
Update a single step. The same 409 rule applies if the parent sequence is transitioning.
Request Body
| Field | Type | Description |
|---|---|---|
step_data | object | Template/content data |
time_interval | integer | Delay in seconds after previous step |
step_type | string | Step type |
input_type | string | ON_DEMAND or TEMPLATE |
Example
curl -X PATCH "https://be.graph8.com/api/v1/sequences/seq_abc/steps/stp_1" \ -H "Authorization: Bearer $API_KEY" \ -H "Content-Type: application/json" \ -d '{"step_data": {"subject": "Quick intro v2", "body": "Updated..."}}'Pause / Resume
POST /sequences/{sequence_id}/pause
POST /sequences/{sequence_id}/resume
Pause a live sequence (or resume a paused one). Returns the number of contacts affected.
Response
{ "data": { "sequence_id": "seq_abc", "status": "paused", "contacts_affected": 150 }}Analytics
GET /sequences/{sequence_id}/analytics
Returns a comprehensive analytics report - overview KPIs, performance over time, engagement breakdown, contact distribution, per-step metrics, and sender distribution. The shape mirrors the internal SequenceReports model.
Example
curl "https://be.graph8.com/api/v1/sequences/seq_abc/analytics" \ -H "Authorization: Bearer $API_KEY"Response
{ "data": { "overview": {"sent": 320, "opened": 180, "replied": 22}, "performance": {"open_rate": 0.56, "reply_rate": 0.07}, "engagement": {"by_day": [...]}, "timeline": [...], "contact_distribution": {"active": 150, "completed": 100, "stopped": 70}, "step_breakdown": [ {"step_id": "stp_1", "sent": 320, "opened": 180} ], "step_creation_methods": [...], "sender_distribution": [...] }}The full schema lives at /api/v1/docs under SequenceAnalyticsResponse.
Delete (Archive)
DELETE /sequences/{sequence_id}
Soft-deletes a sequence by setting is_archived = true. Already-archived sequences return 400. Sequences in certain non-terminal states cannot be archived and return 409.
Example
curl -X DELETE "https://be.graph8.com/api/v1/sequences/seq_abc" \ -H "Authorization: Bearer $API_KEY"Errors
| Status | Meaning |
|---|---|
400 | Sequence is already archived |
404 | Sequence not found |
409 | Sequence cannot be archived in its current state |