Reference

Sends

The primitive — every email Clement sends, whether one-off or campaign-driven, lands here. See the Send your first email guide for the typical flow.

List sends

get /v1/sends
curl -X GET "https://api.clement.so/v1/sends" \
  -H "Authorization: Bearer $CLEMENT_API_KEY"

Query parameters

  • limit integer
  • starting_after string
  • ending_before string
  • inbox_id string
  • state string
  • expand string

Response200

OK

Property Type Description
object required enum (1)
"list"
data required array<Send>
has_more required boolean
next_cursor required string | null
prev_cursor required string | null
Example response
{
  "object": "list",
  "data": [
    {
      "id": "snd_01HZ8X3J9K7P2QV6R5N4M3T2L4",
      "object": "send",
      "mode": "live",
      "inbox_id": "inb_01HZ8X3J9K7P2QV6R5N4M3T2L1",
      "to_email": "alice@example.com",
      "subject": "Quick question about Acme's data stack",
      "state": "sent",
      "failure_reason": null,
      "provider_message_id": "18f8a2b...",
      "provider_thread_id": "18f8a2b...",
      "rfc822_message_id": "<01HZ8X3J9K7P2QV6@mail.clement.so>",
      "attempt_count": 1,
      "scheduled_at": "2026-04-29T14:30:00Z",
      "sent_at": "2026-04-29T14:30:02Z",
      "created_at": "2026-04-29T14:30:00Z",
      "campaign_id": null
    }
  ],
  "has_more": false,
  "next_cursor": "string",
  "prev_cursor": "string"
}

Errors

  • 400 Invalid request
  • 401 Authentication failed
  • 403 Insufficient scope
  • 404 Not found
  • 409 Conflict
  • 422 Validation failed
  • 429 Rate limited

See Errors for the full envelope and per-code reference.

Send an email (single or fan-out across inboxes)

post /v1/sends

**The send primitive** (API-PLAN §6). Single recipient → returns the `Send`. Multi-recipient or `from_strategy` → returns a `BulkSendResult` with per-recipient outcomes.

curl -X POST "https://api.clement.so/v1/sends" \
  -H "Authorization: Bearer $CLEMENT_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  --data '{
      "to": "alice@example.com",
      "subject": "Quick question about your stack",
      "inbox_id": "inb_01HZ8X3J9K7P2QV6R5N4M3T2L1",
      "from_strategy": {
        "type": "single",
        "inbox_id": "inb_01HZ8X3J9K7P2QV6R5N4M3T2L1",
        "inbox_ids": [
          "string"
        ]
      },
      "body_html": "<p>Hi {{first_name}}, would love to chat — does Tuesday work?</p>",
      "body_text": "Hi {{first_name}}, would love to chat — does Tuesday work?",
      "variables": {},
      "thread_id": "thr_01HZ8X3J9K7P2QV6R5N4M3T2L6",
      "in_reply_to_message_id": "in__01HZ8X3J9K7P2QV6R5N4M3T2L1",
      "metadata": {},
      "append_signature": false
    }'

Request body

Property Type Description
inbox_id string Single-inbox shorthand. Equivalent to `from_strategy: { type: 'single', inbox_id }`.
from_strategy SendFromStrategy
Show properties
Property Type Description
type required enum (3)
"single""rotate""least_busy"
inbox_id string
inbox_ids array<string>
to required object
subject required string
body_html string
body_text string
variables object
send_at string (date-time) | null RFC-3339 timestamp; null/omitted = enqueue immediately.
thread_id string Public thread id (`thr_…`). Setting this turns the send into a reply in that thread: it must be sent from the thread's inbox (`inbox_id` or a `single` from_strategy), and `In-Reply-To` defaults to the thread's latest message.
in_reply_to_message_id string RFC 822 Message-ID (`<…@…>`) to cite in `In-Reply-To`. With `thread_id`, overrides the default (the thread's latest message).
metadata object Customer-supplied dict echoed back on every event for this send.
append_signature boolean Append the sending inbox's signature (`signature_html` / `signature_text`) to the body parts you supply. Default false: ad-hoc sends go out exactly as written.

Response201

Send(s) scheduled

Type: object.

Example response
{
  "id": "snd_01HZ8X3J9K7P2QV6R5N4M3T2L4",
  "object": "send",
  "mode": "live",
  "inbox_id": "inb_01HZ8X3J9K7P2QV6R5N4M3T2L1",
  "to_email": "alice@example.com",
  "subject": "Quick question about Acme's data stack",
  "state": "sent",
  "failure_reason": null,
  "provider_message_id": "18f8a2b...",
  "provider_thread_id": "18f8a2b...",
  "rfc822_message_id": "<01HZ8X3J9K7P2QV6@mail.clement.so>",
  "attempt_count": 1,
  "scheduled_at": "2026-04-29T14:30:00Z",
  "sent_at": "2026-04-29T14:30:02Z",
  "created_at": "2026-04-29T14:30:00Z",
  "campaign_id": null
}

Errors

  • 400 Invalid request
  • 401 Authentication failed
  • 403 Insufficient scope
  • 404 Not found
  • 409 Conflict
  • 422 Validation failed
  • 429 Rate limited

See Errors for the full envelope and per-code reference.

Retrieve a send

get /v1/sends/{id}
curl -X GET "https://api.clement.so/v1/sends/obj_01HZ8X3J9K7P2QV6R5N4M3T2L1" \
  -H "Authorization: Bearer $CLEMENT_API_KEY"

Path parameters

  • id string required

Query parameters

  • expand string

Response200

OK

Property Type Description
id required string
object required enum (1)
"send"
mode required enum (2)
"live""test"
inbox_id required string
inbox SendExpandInbox | null Present (possibly null if missing) when `?expand=inbox`.
Show properties
Property Type Description
id required string
email_address required string (email)
display_name required string | null
status required string
to_email required string (email)
subject required string
state required enum (4)
"scheduled""sending""sent""failed"
failure_reason required string | null
provider_message_id required string | null
provider_thread_id required string | null
rfc822_message_id required string | null
attempt_count required integer
scheduled_at required string (date-time)
sent_at required string (date-time) | null
created_at required string (date-time)
campaign_id required string | null
Example response
{
  "id": "snd_01HZ8X3J9K7P2QV6R5N4M3T2L4",
  "object": "send",
  "mode": "live",
  "inbox_id": "inb_01HZ8X3J9K7P2QV6R5N4M3T2L1",
  "to_email": "alice@example.com",
  "subject": "Quick question about Acme's data stack",
  "state": "sent",
  "failure_reason": null,
  "provider_message_id": "18f8a2b...",
  "provider_thread_id": "18f8a2b...",
  "rfc822_message_id": "<01HZ8X3J9K7P2QV6@mail.clement.so>",
  "attempt_count": 1,
  "scheduled_at": "2026-04-29T14:30:00Z",
  "sent_at": "2026-04-29T14:30:02Z",
  "created_at": "2026-04-29T14:30:00Z",
  "campaign_id": null
}

Errors

  • 400 Invalid request
  • 401 Authentication failed
  • 403 Insufficient scope
  • 404 Not found
  • 409 Conflict
  • 422 Validation failed
  • 429 Rate limited

See Errors for the full envelope and per-code reference.

Cancel a scheduled send

post /v1/sends/{id}/cancel

Only valid while the send is in state `scheduled`. Returns 409 once the worker has picked the job up (`sending` or beyond — the email may already be on its way to Gmail).

curl -X POST "https://api.clement.so/v1/sends/obj_01HZ8X3J9K7P2QV6R5N4M3T2L1/cancel" \
  -H "Authorization: Bearer $CLEMENT_API_KEY"

Path parameters

  • id string required

Response200

Canceled

Property Type Description
id required string
object required enum (1)
"send"
mode required enum (2)
"live""test"
inbox_id required string
inbox SendExpandInbox | null Present (possibly null if missing) when `?expand=inbox`.
Show properties
Property Type Description
id required string
email_address required string (email)
display_name required string | null
status required string
to_email required string (email)
subject required string
state required enum (4)
"scheduled""sending""sent""failed"
failure_reason required string | null
provider_message_id required string | null
provider_thread_id required string | null
rfc822_message_id required string | null
attempt_count required integer
scheduled_at required string (date-time)
sent_at required string (date-time) | null
created_at required string (date-time)
campaign_id required string | null
Example response
{
  "id": "snd_01HZ8X3J9K7P2QV6R5N4M3T2L4",
  "object": "send",
  "mode": "live",
  "inbox_id": "inb_01HZ8X3J9K7P2QV6R5N4M3T2L1",
  "to_email": "alice@example.com",
  "subject": "Quick question about Acme's data stack",
  "state": "sent",
  "failure_reason": null,
  "provider_message_id": "18f8a2b...",
  "provider_thread_id": "18f8a2b...",
  "rfc822_message_id": "<01HZ8X3J9K7P2QV6@mail.clement.so>",
  "attempt_count": 1,
  "scheduled_at": "2026-04-29T14:30:00Z",
  "sent_at": "2026-04-29T14:30:02Z",
  "created_at": "2026-04-29T14:30:00Z",
  "campaign_id": null
}

Errors

  • 400 Invalid request
  • 401 Authentication failed
  • 403 Insufficient scope
  • 404 Not found
  • 409 Conflict
  • 422 Validation failed
  • 429 Rate limited

See Errors for the full envelope and per-code reference.