Cadences

List enrollments for this cadence

Returns enrollments newest-first, with per-row step-run summary so you can render a "3 of 5 ✅" progress + "Blocked: <reason>" badge in one HTTP call — no N+1 fetch into /v1/enrollments/{id}.

What you get per enrollment

Identity (set at enroll time, returned verbatim):

  • leadExternalId — your idempotency key
  • leadName, 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 | error
  • currentStep — 0-based index of the NEXT step due
  • stepsCompleted — count of DISTINCT step indices that have fired with status='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. The code values match what runner.ts writes — most common today are NO_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), and AI_STRATEGY_REMOVED (pre-existing step still on draftStrategy: "ai" — update the step to static or webhook). Skipped steps (a step whose condition didn't apply — e.g. after_accept on 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.

get/cadences/{id}/enrollments

Request

  • Base URL: https://anjal.app
  • URL: https://anjal.app/cadences/{id}/enrollments
  • Auth: API key in header X-API-Key

Path parameters

idstring uuid required

Query parameters

state'active' | 'paused' | 'completed' | 'replied' | 'accepted' | 'bounced' | 'unenrolled' | 'error'

Filter by enrollment state.

limitinteger

Response

Enrollment list (with per-row step-run summary).

okboolean

Changes

No recorded changes to this operation across all 1 revision of this API.