Skip to content

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.

EndpointMethodDescription
/sequencesPOSTCreate a sequence (with optional steps + channels)
/sequences/{id}/previewGETRead sequence + steps + channels (no enrollment)
/sequences/{id}PATCHUpdate sequence metadata
/sequences/{id}/steps/{step_id}PATCHUpdate a single step
/sequences/{id}/pausePOSTPause a live sequence
/sequences/{id}/resumePOSTResume a paused sequence
/sequences/{id}/analyticsGETComprehensive analytics report
/sequences/{id}DELETESoft-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

FieldTypeRequiredDescription
namestringYesSequence name
user_emailstringYesOwner email address
descriptionstringNoFree-form description
finish_on_replybooleanNo (default true)Stop contacting on reply
send_in_same_threadbooleanNoSend follow-ups in the same email thread
wait_for_new_contactsbooleanNoKeep sequence waiting for new enrollments
associated_list_idintegerNoContact list to associate
stepsobject[]NoStep configs - see Step config
channelsobject[]NoChannel configs - see Channel config
campaign_idstringNoAI Studio campaign to link

Step config

FieldTypeDescription
step_orderintegerOrder within the sequence
step_typestringEMAIL, PHONE, SMS, LINKEDIN, etc.
input_typestringON_DEMAND or TEMPLATE (default ON_DEMAND)
time_intervalintegerDelay in seconds after the previous step
step_dataobjectStep template/content data (subject, body, etc.)

Channel config

FieldTypeDescription
channel_idintegerResource ID (mailbox ID, phone ID, etc.)
channel_valuestringThe address/number itself
channel_typestringEMAIL, PHONE, SMS, LINKEDIN, WHATSAPP
channel_dataobjectOptional metadata

Example

Terminal window
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

StatusMeaning
400Invalid 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

Terminal window
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

FieldTypeDescription
namestringSequence name
descriptionstringDescription
is_sharedbooleanShare with the org
finish_on_replybooleanFinish on reply
send_in_same_threadbooleanSame-thread follow-ups
wait_for_new_contactsbooleanWait for new contacts
schedule_idstringSchedule ID
appointment_idintegerAppointment ID

Example

Terminal window
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

StatusMeaning
404Sequence not found
409Sequence 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

FieldTypeDescription
step_dataobjectTemplate/content data
time_intervalintegerDelay in seconds after previous step
step_typestringStep type
input_typestringON_DEMAND or TEMPLATE

Example

Terminal window
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

Terminal window
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

Terminal window
curl -X DELETE "https://be.graph8.com/api/v1/sequences/seq_abc" \
-H "Authorization: Bearer $API_KEY"

Errors

StatusMeaning
400Sequence is already archived
404Sequence not found
409Sequence cannot be archived in its current state