Developer Documentation

Sequencer API

Programmatic Email Sequencer operations for campaigns and lead management.

Authentication

  • Method: Bearer API key (Authorization: Bearer <api_key>) or X-Api-Key.
  • Permission: sequencer on the API key.
  • Plan: sequencer_enabled must be true on the tenant's active plan.

Common errors:

Error Response

{ "status": "error", "reason": "Your current plan does not include the Email Sequencer." }

Error Response

{ "status": "error", "reason": "API key does not have sequencer permission." }

All routes are prefixed with /api/v1/sequencer and throttled via api-v1-sequencer (60 requests/min per API key).

Leads

GET /api/v1/sequencer/leads

List leads with cursor pagination.

Query parameters: status, list_id, tag, saved_filter_id, since, q, cursor.

Request Example

curl "$APP_URL/api/v1/sequencer/leads?q=acme" \
  -H "Authorization: Bearer $API_KEY"

POST /api/v1/sequencer/leads

Create or update a single lead by email.

Required: email. Optional: first_name, last_name, company, title, phone, timezone, source, custom_fields.

Request Example

curl -X POST "$APP_URL/api/v1/sequencer/leads" \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"email":"lead@example.com","first_name":"Alex"}'

POST /api/v1/sequencer/leads/webhook

Webhook-style lead ingestion with optional tags[] and list_id.

POST /api/v1/sequencer/leads/import

Bulk import via multipart file, raw csv string, or leads[] array (provide one).

  • file: multipart upload (csv/txt/xlsx/xls, max 10 MB). Example: curl -F "file=@leads.csv" -H "Authorization: Bearer $API_KEY" ...
  • csv: raw CSV string in JSON (max 10 KB). First row = headers; email column required.
  • leads: array of objects (max 1000), each with email.
  • Unknown CSV columns map to custom_fields.
  • ≤50 rows: synchronous 201 with counts.
  • >50 rows: 202 with task_id; poll GET /api/v1/sequencer/leads/import/{task}.

GET/PATCH/DELETE /api/v1/sequencer/leads/{lead}

Standard CRUD for individual leads.

Segmentation

Lead tags — /api/v1/sequencer/lead-tags

Request Example

curl -X POST "$APP_URL/api/v1/sequencer/lead-tags" \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"name":"hot","color":"#ff5500"}'

Lead lists — /api/v1/sequencer/lead-lists

Request Example

curl -X POST "$APP_URL/api/v1/sequencer/lead-lists" \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"name":"Q1 prospects","lead_ids":[1,2,3]}'

Lead notes — /api/v1/sequencer/lead-notes

Request Example

curl -X POST "$APP_URL/api/v1/sequencer/lead-notes" \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"lead_id":1,"body":"Called — interested in demo"}'

Saved filters — /api/v1/sequencer/saved-filters

Reusable filter definitions for the leads index (status, q, tag, list_id).

Request Example

curl -X POST "$APP_URL/api/v1/sequencer/saved-filters" \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"name":"Active hot leads","filters":{"status":"active","tag":"hot"}}'

Full CRUD: GET, POST, GET/{id}, PATCH/{id}, DELETE/{id}.

Sequences

GET/POST /api/v1/sequencer/sequences

List or create sequences. Steps can be nested on create/update.

PUT /api/v1/sequencer/sequences/{sequence}/steps

Sync all steps in one request. Step types: email, follow_up, wait, condition.

Request Example

curl -X PUT "$APP_URL/api/v1/sequencer/sequences/1/steps" \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "steps": [
      {"type":"email","position":1,"subject":"Hello","body":"Hi there"},
      {"type":"wait","position":2,"wait_days":2}
    ]
  }'

DELETE /api/v1/sequencer/sequences/{sequence}/steps/{step}

Remove a single step without replacing the full list.

Campaigns

GET /api/v1/sequencer/campaigns

List campaigns. Query: status, q, sort, dir, per_page.

POST /api/v1/sequencer/campaigns

Create a draft campaign.

Field Required Notes
name Yes Campaign name
sequence_id No Links an existing sequence; omitted values auto-provision a new sequence
mailbox_ids No Sender mailbox IDs for rotation; required before enroll
lead_list_id No Optional default list
settings No Send limits, tracking, schedule_mode
sending_window No Active days and hours
sending_timezone No IANA timezone (default UTC)

Request Example

curl -X POST "$APP_URL/api/v1/sequencer/campaigns" \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"name":"Outreach","mailbox_ids":[10]}'

PATCH /api/v1/sequencer/campaigns/{campaign}

Update campaign fields, mailboxes, schedule, or settings. Set status to active on a draft campaign to activate.

Activation checks (HTTP 422 with failures[] when not met):

  • At least one email or follow-up step in the sequence
  • At least one verified, exclusive sender mailbox
  • settings.daily_send_limit > 0
  • At least one enrolled lead (or non-empty linked lead list)
  • Valid sending_window with non-empty days and start/end hours

Request Example

curl -X PATCH "$APP_URL/api/v1/sequencer/campaigns/1" \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "settings": {"daily_send_limit": 50, "schedule_mode": "future"},
    "sending_timezone": "America/Chicago",
    "sending_window": {
      "days": [1,2,3,4,5],
      "start_hour": 9,
      "start_minute": 0,
      "end_hour": 17,
      "end_minute": 0
    },
    "status": "active"
  }'

POST /api/v1/sequencer/campaigns/{campaign}/enroll

Enroll leads by lead_ids[] or bulk via lead_list_id. Requires at least one mailbox on the campaign (HTTP 422 otherwise).

Request Example

curl -X POST "$APP_URL/api/v1/sequencer/campaigns/1/enroll" \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"lead_ids":[10,11]}'

Response: {"status":"completed","enrolled":2,"skipped":0} (HTTP 201).

POST /api/v1/sequencer/campaigns/{campaign}/pause|resume

Pause or resume an active/paused campaign.

GET /api/v1/sequencer/campaigns/{campaign}/analytics

Returns funnel metrics, engagement rates, and breakdowns:

Success Response

{
  "data": {
    "campaign_id": 1,
    "funnel": {
      "total_enrolled": 100,
      "sent": 80,
      "opened": 40,
      "clicked": 12,
      "replied": 5,
      "bounced": 2
    },
    "rates": {
      "open_rate": 50.0,
      "click_rate": 15.0,
      "reply_rate": 6.25,
      "bounce_rate": 2.5
    },
    "by_mailbox": [],
    "by_step": [],
    "by_domain": []
  }
}

Campaign settings reference

Key Type Description
daily_send_limit integer Starting sends per day (required > 0 to activate)
ramp_up_percent_per_day integer Optional daily ramp-up amount (percent or count per ramp_up_mode)
ramp_up_mode string percent (default) or count — compound increase from current daily limit
max_send_limit integer Optional ceiling for ramped daily limit
track_opens boolean Open tracking (default true on auto-provisioned campaigns)
track_clicks boolean Click tracking (default true on auto-provisioned campaigns)
schedule_mode string now or future

Sending window reference

Key Type Description
days integer[] ISO weekdays 1 (Mon) – 7 (Sun)
start_hour integer Window start hour (0–23)
start_minute integer Window start minute
end_hour integer Window end hour
end_minute integer Window end minute

Interpreted in sending_timezone.

Webhooks

Register sequencer events on existing webhooks (POST /api/v1/webhooks, webhook permission). See Webhooks for HMAC verification.

  • sequencer.email.sent
  • sequencer.email.opened
  • sequencer.email.clicked
  • sequencer.lead.replied
  • sequencer.lead.bounced
  • sequencer.lead.unsubscribed
  • sequencer.campaign.completed

MCP Tools

The Mails.now MCP server exposes:

  • list_sequencer_leads (read)
  • create_sequencer_lead (write + sequencer permission)
  • list_sequencer_campaigns (read)
  • enroll_sequencer_campaign (write + sequencer permission)
  • list_sequencer_sequences (read)
  • create_sequencer_sequence (write + sequencer permission)
  • sync_sequencer_sequence_steps (write + sequencer permission)

OpenAPI

Sequencer paths are included in /openapi.json under the Sequencer tag.

Interactive reference: API docs