Sequences
Create, review, and run personalized email sequences with automatic follow-ups.
#Use case
Create, review, and run personalized email sequences with automatic follow-ups.
#Endpoint
POST https://api-public.clodo.ai/api/public/v1/sequences/Send your API key in the x-api-key header. See Authentication.
This endpoint returns
202 Accepted. Poll the resource to follow its progress. Outreach does not require a webhook signing secret.
#Pricing
See Credits & Pricing for credit costs and charging behavior.
#Errors
For error responses and retry guidance, see Handling Errors.
Enroll up to 100 contacts in a multi-step drafted sequence — every step is drafted up front, you review the whole thing, and one approve sets it running. 2 credits per drafted email (e.g. 5 contacts × 3 steps = 30 credits), reserved when you create the sequence and settled when drafting finishes; failed drafts are released.
Sequences require a connected Google or Microsoft sending account (reply detection drives stop-on-reply; SMTP can't support it — you'll get a 409).
#How follow-ups behave
- Step timing is automatic: follow-ups go out 3 / 7 / 14 days after the previous step actually sends (tunable per-account in the web app), at a sensible hour, skipping weekends.
- A step only sends after the prior step has sent.
- A reply or bounce stops everything: remaining steps for that contact are cancelled automatically.
- Each enrolled contact becomes a lead in your workspace, and the whole sequence is visible on your Emails page in the app.
#Lifecycle
POST /sequences/ -> 202 status: drafting
GET /sequences/{id}/ -> poll until status: pending_review
PATCH /emails/{em_id}/ -> optional per-step edits (steps are regular em_ emails)
POST /sequences/{id}/approve/ -> status: active (steps queued on cadence)
POST /sequences/{id}/contacts/-> enroll more contacts, any time after drafting settles
GET /sequences/{id}/replies/ -> inbound replies as they arrive| Sequence status | Meaning |
|---|---|
drafting |
Steps are being written (~30–60s per email). |
pending_review |
All drafts ready — waiting for approve. |
active |
Approved and running. |
completed / cancelled / failed |
Terminal. Per-enrollment statuses carry the detail (replied, bounced, ...). |
#Create — POST /sequences/
| Field | Type | Notes |
|---|---|---|
contacts |
array, 1–100 | Same contact shape as Outreach Emails (email + first_name required; company_name, professional_url, context optional). |
instructions |
string, ≤2000 | What the sequence should pitch/do. |
name |
string, ≤200 | Optional label for your own bookkeeping (e.g. "LegalHR1"). Echoed on every sequence payload; not shown to recipients. |
steps |
int, 1–4 | Total steps including the intro. Default 3. |
from_account |
string | Optional ea_... sender pin. |
reply_to |
string | Optional Reply-To address for every step. Must be one of your connected email accounts (any of them — not just the sender); anything else is a 400. Replies routed there are still detected: the sequence stops on reply as usual. |
cc |
string[] | Optional CC recipients, max 3, applied to every step. Visible to everyone on the thread. A reply from a CC'd address does not stop the sequence — only the lead's reply does. |
bcc |
string[] | Optional BCC recipients, max 3, applied to every step (e.g. a CRM logging address). Never visible to the other recipients. |
review |
string | "required" (default) or "none" (auto-approve after drafting). |
curl -X POST https://api-public.clodo.ai/api/public/v1/sequences/ \
-H "x-api-key: ck_live_..." \
-H "Content-Type: application/json" \
-d '{
"contacts": [
{"email": "x@acme.com", "first_name": "Xola", "company_name": "Acme"},
{"email": "y@globex.com", "first_name": "Yuri", "company_name": "Globex"},
{"email": "z@initech.io", "first_name": "Zadie", "company_name": "Initech"}
],
"instructions": "3-step sequence pitching our outbound API. Casual tone, developer audience.",
"name": "DevRel-Q3-1",
"steps": 3
}'Returns 202:
{
"id": "sq_9c41d2...",
"name": "DevRel-Q3-1",
"status": "drafting",
"created_at": "2026-07-13T00:00:00Z",
"contacts_accepted": 3,
"contacts_rejected": [],
"total_emails": 9,
"drafted": 0
}Partial accept: ineligible contacts are skipped, not fatal — contacts_rejected lists each with a reason (already_in_automation — the person is in another active sequence; not_enriched; recently_contacted; invalid_contact). Only if no contact is eligible does the call fail.
#Add contacts — POST /sequences/{id}/contacts/
Enroll 1–100 additional contacts into an existing sequence — including after it's active. New enrollments inherit the sequence's original instructions and step plan and start at step 0 on their own cadence clock; existing enrollments are untouched. 2 credits per newly drafted email, reserved on the call and settled when the new drafts finish.
| Field | Type | Notes |
|---|---|---|
contacts |
array, 1–100 | Same contact shape as create. |
from_account |
string | Optional ea_... sender pin for the new enrollments. |
New enrollments also inherit the sequence's reply_to, cc, and bcc (if set at create time) — appended contacts' threads behave the same as everyone else's.
| review | string | "required" (default) or "none". "none" auto-approves every pending enrollment in the sequence once drafting finishes. |
curl -X POST https://api-public.clodo.ai/api/public/v1/sequences/sq_9c41d2.../contacts/ \
-H "x-api-key: ck_live_..." \
-H "Content-Type: application/json" \
-d '{"contacts": [{"email": "w@umbrella.co", "first_name": "Wren", "company_name": "Umbrella"}]}'Returns 202:
{
"id": "sq_9c41d2...",
"name": "DevRel-Q3-1",
"status": "drafting",
"contacts_accepted": 1,
"contacts_rejected": [],
"emails_added": 3
}Behavior notes:
- The sequence's top-level status returns to
draftingwhile the new enrollments draft, then settles back (per-enrollment statuses stay accurate throughout — poll the detail). - With
review: "required", callapprove/again after drafting — it activates only the newly drafted enrollments (already-active ones are skipped). Per-step copy edits viaPATCH /emails/{em_id}/work on the new drafts before approval, same as at create. 409while a drafting pass is running (retry shortly), and forcancelled/failedsequences (create a new one instead).- Contacts already enrolled in this sequence are rejected with reason
already_enrolled; the other rejection reasons match create. - A sequence holds at most 500 enrollments.
#Read — GET /sequences/{id}/
{
"id": "sq_9c41d2...",
"name": "DevRel-Q3-1",
"status": "pending_review",
"instructions": "3-step sequence pitching...",
"total_emails": 9,
"drafted": 9,
"failed": 0,
"enrollments": [
{
"contact": {"email": "x@acme.com", "name": "Xola"},
"status": "pending_review",
"emails": [
{"id": "em_...", "step": 0, "status": "pending_review", "subject": "...", "body_plain": "...", ...},
{"id": "em_...", "step": 1, ...},
{"id": "em_...", "step": 2, ...}
]
}
]
}Each step is a regular outreach email — the em_ ids work against GET /emails/{id}/ and PATCH /emails/{id}/ for per-step edits. Edits work before approving AND after — any step whose status is pending_review or queued accepts a PATCH, so you can rewrite upcoming follow-ups on a live sequence. Every other status (drafting, sending, sent, failed, cancelled) returns 409.
GET /sequences/ lists your sequences (paginated, no enrollments — fetch the detail).
#Approve — POST /sequences/{id}/approve/
Approves every drafted enrollment: step 0 queues at its computed best time, later steps follow the cadence after each prior send. 409 while still drafting.
#Cancel — POST /sequences/{id}/cancel/
Cancels all non-terminal enrollments and their unsent steps. Already-sent steps are unaffected. No refunds for drafted emails (the drafting work happened).
#Replies — GET /sequences/{id}/replies/
{
"replies": [
{
"email_id": "em_...",
"from_email": "x@acme.com",
"from_name": "Xola",
"subject": "Re: your outbound API",
"body_plain": "Interested — got time Thursday?",
"classification": "reply",
"received_at": "2026-07-16T14:03:00Z"
}
]
}classification is reply, bounce, or auto_reply. The corresponding enrollment will already show status replied/bounced with its remaining steps cancelled.
#Status mapping
| Outcome | HTTP | Charged |
|---|---|---|
| Sequence created | 202 |
2 credits × drafts that succeed |
| All contacts rejected | 400 invalid_request |
0 |
| No Google/Microsoft account | 409 conflict |
0 |
| Approve while drafting | 409 conflict |
0 |
Unknown sq_ id |
404 not_found |
0 |
#See also
- Outreach Emails — the one-off flow and per-step edit semantics
- Sending Accounts
- Credit Semantics