Gary Club
Resource

Sequences

Multi-step SMS / email ladders. Enroll a contact and the worker fires the steps on schedule. Idempotent — re-enrolling an active contact returns the existing row.

Killer use case
Pair the contact created webhook from a fresh inbound call with POST /v1/sequences/{id}/enrollments in n8n — every new lead lands in nurture without a human hop.

List sequences#

List message sequences

GET/v1/sequences
Paginated. Each row includes the steps ladder so callers can preview before enrolling.

Query parameters

limitintegerdefault: 50
1–200
page_tokenstring
Cursor from prior page.
statusstring
Filter — draft, active, paused, archived.
Response
{
  "data": [
    {
      "id": "seq_EXAMPLE_aaaa",
      "name": "Post-call nurture",
      "description": "Sent to leads after their first inbound call",
      "status": "active",
      "steps": [
        { "kind": "sms", "wait_minutes": 60, "body": "Hey {{first_name}}, …" },
        { "kind": "sms", "wait_minutes": 1440, "body": "Quick follow-up …" }
      ],
      "created_at": "2026-04-12T17:21:01.000Z",
      "updated_at": "2026-04-25T18:02:00.000Z"
    }
  ],
  "next_page_token": null,
  "total": 1
}

Read one sequence#

Single sequence with steps

GET/v1/sequences/{id}

Path parameters

iduuidrequired
Sequence id.

Enroll a contact#

Idempotent enrollment

POST/v1/sequences/{id}/enrollments
Creates an active enrollment that the worker fires step-by-step. If the contact is already actively enrolled in this sequence, the existing row is returned with idempotent: true. The first step runs on the next cron tick (every minute).

Path parameters

iduuidrequired
Sequence id.

Body parameters

contact_iduuid
Required. Must belong to the same tenant.
metadataobject
Free-form attribution / context. Stored as-is on the enrollment row.
Request
curl -X POST \
  https://agency.gary.club/api/public/v1/sequences/seq_EXAMPLE_aaaa/enrollments \
  -H "Authorization: Bearer gc_live_EXAMPLE_AbCdEfGhIj0123456789" \
  -H "Content-Type: application/json" \
  -d '{ "contact_id": "con_EXAMPLE_bbbb", "metadata": { "source": "post_inbound_call" } }'
Response
{
  "enrollment": {
    "id": "enr_EXAMPLE_aaaa",
    "sequence_id": "seq_EXAMPLE_aaaa",
    "contact_id": "con_EXAMPLE_bbbb",
    "current_step": 0,
    "status": "active",
    "next_run_at": "2026-04-28T01:30:00.000Z",
    "enrolled_at": "2026-04-28T01:30:00.000Z"
  },
  "idempotent": false
}

List enrollments#

Enrollments for a sequence

GET/v1/sequences/{id}/enrollments
Paginated. See who's currently in the ladder, what step they're on, when the next message fires.

Path parameters

iduuidrequired
Sequence id.

Query parameters

statusstring
Filter — active, paused, completed, cancelled.
limitintegerdefault: 50
page_tokenstring

Auto-pause on reply#

When a contact replies to an SMS sent by a sequence step, their enrollment is paused automatically (status=paused, paused_reason=reply_received) so the next scheduled step doesn't fire over their conversation. This is sequence-engine behavior, not something callers need to configure.

Webhooks for sequences#

  • sequence.enrollment.created — a new contact joined the ladder.
  • sequence.enrollment.completed — final step fired.
  • sequence.enrollment.paused — auto-paused on reply, or manually paused.