List enrollments for this cadence
https://myagentmail.com/cadences/{id}/enrollmentsReturns enrollments newest-first, with per-row step-run summary so
you can render a "3 of 5 ✅" progress + "Blocked: /v1/enrollments/{id}.
What you get per enrollment
Identity (set at enroll time, returned verbatim):
leadExternalId— your idempotency keyleadName,leadEmail,leadLinkedinUrl— whatever you sent on enrollment. Returned even if null.leadProfileUrn—urn:li:fsd_profile:…, set by the runner after the first LinkedIn invite resolves the profile. Null until then.sessionId— LinkedIn session the cadence runs through. May be auto-picked from the workspace pool if you didn't pass one (see commit f0d2ff1) — once picked, it's pinned to the enrollment.
State + progress:
state—active | paused | completed | replied | accepted | bounced | unenrolled | errorcurrentStep— 0-based index of the NEXT step duestepsCompleted— count of DISTINCT step indices that have fired withstatus='sent'. Visual: green checkmark count.nextStepDueAt— when the runner will next consider this row (ISO 8601). Past time = overdue + queued.lastStepFiredAt— ISO 8601 of the most recent step run.lastError— most recent FAILED step run (status=failed), or null if no failures. Keys:code,message,atStepIndex,firedAt. Thecodevalues match whatrunner.tswrites — most common today areNO_SESSION_AVAILABLE,WORKSPACE_QUOTA_EXHAUSTED,PINNED_SESSION_UNUSABLE,NO_TARGET,NO_INBOX,DRAFT_WEBHOOK_FAILED(your draft handler timed out, 5xx'd, or returned malformed JSON), andAI_STRATEGY_REMOVED(pre-existing step still ondraftStrategy: "ai"— update the step tostaticorwebhook). Skipped steps (a step whose condition didn't apply — e.g.after_accepton a rejected invite, or your draft handler returned{ skip: true }) are NOT counted as errors; they're a normal part of cadence execution.
Worked example response
{
"ok": true,
"enrollments": [
{
"id": "01HZ…",
"cadenceId": "01HY…",
"leadExternalId": "delegated:lead:abc-123",
"leadName": "Jane Doe",
"leadEmail": "jane@acme.com",
"leadLinkedinUrl": "https://www.linkedin.com/in/jane-doe-1a2b3c/",
"leadProfileUrn": "urn:li:fsd_profile:ACoAAA…aaaa",
"sessionId": "01HX…",
"inboxId": "01HW…",
"currentStep": 3,
"state": "active",
"stepsCompleted": 2,
"nextStepDueAt": "2026-05-21T14:00:00Z",
"lastStepFiredAt": "2026-05-19T14:00:00Z",
"lastError": null,
"enrolledAt": "2026-05-18T10:30:00Z",
"updatedAt": "2026-05-19T14:00:00Z"
},
{
"id": "01HZ…",
"cadenceId": "01HY…",
"leadExternalId": "delegated:lead:def-456",
"leadName": "John Smith",
"leadEmail": null,
"leadLinkedinUrl": "https://www.linkedin.com/in/john-smith/",
"leadProfileUrn": null,
"sessionId": null,
"inboxId": null,
"currentStep": 0,
"state": "active",
"stepsCompleted": 0,
"nextStepDueAt": "2026-05-19T13:00:00Z",
"lastStepFiredAt": "2026-05-19T13:00:00Z",
"lastError": {
"code": "NO_SESSION_AVAILABLE",
"message": "no_active_linkedin_session_in_workspace — connect a LinkedIn account from /dashboard/linkedin to start running cadence steps",
"atStepIndex": 0,
"firedAt": "2026-05-19T13:00:00Z"
},
"enrolledAt": "2026-05-19T12:00:00Z",
"updatedAt": "2026-05-19T13:00:00Z"
}
]
}
Drilling into one enrollment
For per-step ✅ render (the full stepRuns[] history, including
skipped steps, rendered message text, channel URNs), call
GET /v1/enrollments/{id} — that endpoint returns the same
enrollment fields plus a stepRuns array of the last 50 runs
ordered newest-first.
Path parameters
idrequired string |
Query parameters
state"active" | "paused" | "completed" | "replied" | "accepted" | "bounced" | "unenrolled" | "error" | Filter by enrollment state. |
limitinteger |
Responses
okboolean | |
enrollmentsobject[] | |
idstring | format: uuid |
cadenceIdstring | format: uuid |
leadExternalIdstring | |
leadNamestring | |
leadEmailstring | |
leadLinkedinUrlstring | |
leadProfileUrnstring | Set by the runner after the first LinkedIn invite resolves. Null until then. |
sessionIdstring | |
inboxIdstring | |
currentStepinteger | 0-based index of the NEXT step due. |
state"active" | "paused" | "completed" | "replied" | "accepted" | "bounced" | "unenrolled" | "error" | enum: "active" | "paused" | "completed" | "replied" | "accepted" | "bounced" | "unenrolled" | "error" |
stepsCompletedinteger | Count of DISTINCT step indices that have fired with `status='sent'`. Skipped + failed steps do NOT count. Visual: green-checkmark count. |
nextStepDueAtstring | format: date-time |
lastStepFiredAtstring | format: date-time |
lastErrorobject | Most recent FAILED step run, or null. `code` values come from the cadence runner — see the description above for the catalogue. |
codestring | |
messagestring | |
atStepIndexinteger | |
firedAtstring | format: date-time |
exitReasonstring | |
exitAtstring | format: date-time |
lastInvitationUrnstring | |
contextobject | |
enrolledAtstring | format: date-time |
updatedAtstring | format: date-time |
Authentication
Send your API key in the X-API-Key header (or Authorization: Bearer <key>). Any prefix accepted by this endpoint — tk_, wk_, ak_, or sa_ — is documented in the key prefix table.