Outcome
Read sequence history, the current draft and latest published version.
Before you start
- Verify the environment, credential, authorized organization and the published action permission workspace:read.
- Discover an accessible Engage workspace and bind resourceType=workspace and its resourceId separately from action input. Fixture identifiers grant no access.
Discover the target
- Discover the sequence through sequences.list using the retained campaignId, then read sequences.get in the same authorized workspace. Inspect sequence.status, draft, published and versions before planning.
topolo whoami --json
topolo actions get app_topolo_engage.sequences.get --json
topolo workspaces list topolo-engage --json
Input fields
| Field | Required | Meaning and constraints |
|---|---|---|
id | Yes | Required sequence identifier discovered through sequences.list in the selected workspace, trimmed non-empty string up to 128 characters. |
Validate, plan and execute
Set ENGAGE_WORKSPACE_ID to the identifier of your selected workspace. Prepare payload.json from the current input schema and discovered identifiers. Use the same payload for validation, planning and execution.
: "${ENGAGE_WORKSPACE_ID:?Set ENGAGE_WORKSPACE_ID to your selected workspace identifier}"
topolo actions validate app_topolo_engage.sequences.get --data @payload.json --json
topolo actions plan app_topolo_engage.sequences.get --resource-type workspace --resource-id "$ENGAGE_WORKSPACE_ID" --data @payload.json --json
Execute the unchanged validated read in the selected workspace.
: "${ENGAGE_WORKSPACE_ID:?Set ENGAGE_WORKSPACE_ID to your selected workspace identifier}"
topolo actions call app_topolo_engage.sequences.get --resource-type workspace --resource-id "$ENGAGE_WORKSPACE_ID" --data @payload.json --json
For MCP, use topolo_get_action, topolo_validate_action, topolo_plan_action and topolo_call_action. Pass the selected resource context separately; confirm:true is required for mutations.
Worked requests and responses
Captured sequences.get · HTTP 200
Action input
{
"id": "eng_seq_1"
}
Actual local response
{
"sequence": {
"id": "eng_seq_1",
"campaignId": "eng_cmp_1",
"name": "Main",
"status": "active",
"createdAt": "2026-10-06T08:30:00.000Z",
"updatedAt": "2026-10-06T08:30:00.000Z"
},
"versions": [
{
"id": "eng_seqv_1",
"version": 1,
"status": "published",
"publishedAt": "2026-10-06T08:30:00.000Z"
}
],
"draft": null,
"published": {
"id": "eng_seqv_1",
"sequenceId": "eng_seq_1",
"version": 1,
"status": "published",
"publishedAt": "2026-10-06T08:30:00.000Z",
"createdAt": "2026-10-06T08:30:00.000Z",
"steps": [
{
"id": "eng_stp_1",
"position": 1,
"type": "linkedin_task",
"delayDays": 0,
"subjectTemplate": "",
"bodyTemplate": "",
"threadWithPrevious": false,
"instructions": "Send a connection request mentioning the webinar.",
"dueDays": 2
},
{
"id": "eng_stp_2",
"position": 2,
"type": "email",
"delayDays": 3,
"subjectTemplate": "Hello {{first_name}}",
"bodyTemplate": "Hi {{first_name}}",
"threadWithPrevious": false,
"instructions": "",
"dueDays": 0
},
{
"id": "eng_stp_3",
"position": 3,
"type": "call_task",
"delayDays": 2,
"subjectTemplate": "",
"bodyTemplate": "",
"threadWithPrevious": false,
"instructions": "Call the main office.",
"dueDays": 0
}
]
}
}
Source test: task steps in sequences > stores linkedin_task and call_task steps with instructions and a due offset, and copies them into a new version. Actual route handlers with SQLite repositories; synthetic identity/workspace grants and provider ports.
Captured sequences.get · HTTP 200
Action input
{
"id": "eng_seq_1"
}
Actual local response
{
"sequence": {
"id": "eng_seq_1",
"campaignId": "eng_cmp_1",
"name": "Main",
"status": "active",
"createdAt": "2026-10-06T08:30:00.000Z",
"updatedAt": "2026-10-06T08:30:00.000Z"
},
"versions": [
{
"id": "eng_seqv_2",
"version": 2,
"status": "draft",
"publishedAt": null
},
{
"id": "eng_seqv_1",
"version": 1,
"status": "published",
"publishedAt": "2026-10-06T08:30:00.000Z"
}
],
"draft": {
"id": "eng_seqv_2",
"sequenceId": "eng_seq_1",
"version": 2,
"status": "draft",
"publishedAt": null,
"createdAt": "2026-10-06T08:30:00.000Z",
"steps": [
{
"id": "eng_stp_3",
"position": 1,
"type": "email",
"delayDays": 0,
"subjectTemplate": "Quick question, {{first_name}}",
"bodyTemplate": "Hi {{first_name}},\n\nHow is {{company}} handling outreach?\n\n{{sender_name}}",
"threadWithPrevious": false,
"instructions": "",
"dueDays": 0
},
{
"id": "eng_stp_4",
"position": 2,
"type": "email",
"delayDays": 4,
"subjectTemplate": "",
"bodyTemplate": "Following up, {{first_name}}.",
"threadWithPrevious": true,
"instructions": "",
"dueDays": 0
}
]
},
"published": {
"id": "eng_seqv_1",
"sequenceId": "eng_seq_1",
"version": 1,
"status": "published",
"publishedAt": "2026-10-06T08:30:00.000Z",
"createdAt": "2026-10-06T08:30:00.000Z",
"steps": [
{
"id": "eng_stp_1",
"position": 1,
"type": "email",
"delayDays": 0,
"subjectTemplate": "Quick question, {{first_name}}",
"bodyTemplate": "Hi {{first_name}},\n\nHow is {{company}} handling outreach?\n\n{{sender_name}}",
"threadWithPrevious": false,
"instructions": "",
"dueDays": 0
},
{
"id": "eng_stp_2",
"position": 2,
"type": "email",
"delayDays": 4,
"subjectTemplate": "",
"bodyTemplate": "Following up, {{first_name}}.",
"threadWithPrevious": true,
"instructions": "",
"dueDays": 0
}
]
}
}
Source test: sequence routes > creates a sequence with an empty draft, edits steps, publishes and freezes the version. Actual route handlers with SQLite repositories; synthetic identity/workspace grants and provider ports.
Captured sequences.get · HTTP 200
Action input
{
"id": "eng_seq_1"
}
Actual local response
{
"sequence": {
"id": "eng_seq_1",
"campaignId": "eng_cmp_1",
"name": "Main",
"status": "draft",
"createdAt": "2026-10-06T08:30:00.000Z",
"updatedAt": "2026-10-06T08:30:00.000Z"
},
"versions": [
{
"id": "eng_seqv_1",
"version": 1,
"status": "draft",
"publishedAt": null
}
],
"draft": {
"id": "eng_seqv_1",
"sequenceId": "eng_seq_1",
"version": 1,
"status": "draft",
"publishedAt": null,
"createdAt": "2026-10-06T08:30:00.000Z",
"steps": [
{
"id": "eng_stp_1",
"position": 1,
"type": "email",
"delayDays": 0,
"subjectTemplate": "Hi {{first_name}}",
"bodyTemplate": "Hello {{first_name}}, see bit.ly/x",
"threadWithPrevious": false,
"instructions": "",
"dueDays": 0
}
]
},
"published": null
}
Source test: sequences.copy_check and publish enforcement > refuses to publish a version with copy errors and allows warnings. Actual route handlers with SQLite repositories; synthetic identity/workspace grants and provider ports.
Captured sequences.get · HTTP 200
Action input
{
"id": "eng_seq_1"
}
Actual local response
{
"sequence": {
"id": "eng_seq_1",
"campaignId": "eng_cmp_1",
"name": "Main",
"status": "active",
"createdAt": "2026-10-06T08:30:00.000Z",
"updatedAt": "2026-10-06T08:30:00.000Z"
},
"versions": [
{
"id": "eng_seqv_1",
"version": 1,
"status": "published",
"publishedAt": "2026-10-06T08:30:00.000Z"
}
],
"draft": null,
"published": {
"id": "eng_seqv_1",
"sequenceId": "eng_seq_1",
"version": 1,
"status": "published",
"publishedAt": "2026-10-06T08:30:00.000Z",
"createdAt": "2026-10-06T08:30:00.000Z",
"steps": [
{
"id": "eng_stp_1",
"position": 1,
"type": "email",
"delayDays": 0,
"subjectTemplate": "Hello {{first_name}}",
"bodyTemplate": "Hi {{first_name}}, a short note about the webinar.",
"threadWithPrevious": false,
"instructions": "",
"dueDays": 0
},
{
"id": "eng_stp_2",
"position": 2,
"type": "whatsapp_template",
"delayDays": 1,
"subjectTemplate": "",
"bodyTemplate": "",
"threadWithPrevious": false,
"instructions": "",
"dueDays": 0,
"whatsappTemplate": {
"templateName": "webinar_invite",
"language": "en_GB",
"variables": [
"first_name"
]
}
}
]
}
}
Source test: WhatsApp template steps in sequences > stores the template with its variables, copies it into a new version and gets no email copy findings. Actual route handlers with SQLite repositories; synthetic identity/workspace grants and provider ports.
Effects and response meaning
- Returns sequence, versions[] ordered by version descending, draft and published. Either draft or published may be null. Each detailed version includes steps ordered by position; published is the latest published version, not every enrollment’s pinned version.
- Direct reads include archived sequences. This does not restore them, mutate steps or send messages.
Verify the result
- Check sequence.id and campaignId. Retain exact versions[].id or draft.id/published.id for sequences.versions.get; inspect status and publishedAt before any edit. Existing enrollments may pin older versions.
Recover
Retry the read in the same verified workspace with the exact discovered identifiers. Use status=archived for discovery when appropriate; do not create a replacement sequence or guess another version after not_found.
Refused responses
Captured sequences.get · HTTP 404
Action input
{
"id": "eng_seq_1"
}
Actual local response
{
"error": {
"code": "not_found",
"message": "Sequence was not found in this workspace."
}
}
Source test: sequence routes > lists, filters, renames and scopes sequences. Actual route handlers with SQLite repositories; synthetic identity/workspace grants and provider ports.
Error recovery
- HTTP 403
permission_denied: Stop and inspect the permission required by this action in the current credential. Do not broaden permissions or switch organization automatically. - HTTP 422
invalid_action_input: Correct required fields, enums and nested step bounds against the current input schema, then validate the exact intended payload again. - HTTP 404
not_found: Rediscover the sequence using sequences.list in the same workspace and campaign; use status=archived when needed. Discover versionId from sequences.get and confirm it belongs to the same sequence. Do not guess another workspace or version.
Related actions
Evidence and limits
-
contracts/sequences.mjs -
apps/api/src/sequences/sequences-handlers.ts -
apps/api/src/sequences/sequences-domain.ts -
apps/api/src/sequences/sequences-repository.ts -
apps/api/src/copy-qa/version-steps.ts -
apps/api/src/copy-qa/copy-qa.ts -
Actual route handlers with SQLite repositories; synthetic identity/workspace grants and provider ports.
-
Widget/bootstrap use actual app handler but mocked worker runtime and app identity.
-
No gateway execution, live permissions, external delivery or deployed proof.
The examples are local route captures with synthetic context and simulated providers. They do not prove live authorization, CLI/MCP gateway execution, production state or delivery.