Skip to main content
POST
Holds a single send or a bulk batch until a person approves it. Nothing is sent by this call. The flow is:
  1. The key calls this endpoint with the exact payload it would have sent. The response is the pending send with status: pending and an expires_at 24 hours out.
  2. A person opens Settings → Send Approvals in the dashboard, reads the recipients, the message and your note, and approves or rejects it.
  3. An authorized same-account, same-mode key polls the pending send until status is approved, then calls send. The immutable review contains rendered recipients, senders, message text, and link destinations. Allocated message and short-link IDs use display placeholders. Rendering or configuration changes require a new review before publication.
A key created with Require send approval cannot send SMS, email, or OTP directly (403 confirmation_required), or perform send-enabling schedule operations; this endpoint is its way to send approved SMS. Any key can use it voluntarily. Check api_key.send_policy.require_confirmation on Who Am I. Creation validates shape, allowed lists, and the rendered review without transport or quota consumption. Suppression, double opt-in, warmup, and current key policy run on execution; billing remains downstream. A send held by a sandbox key is marked sandbox: true and can only be executed by a sandbox key, as a simulation; a live hold can only be executed by a live key. Each account can have 100 unexpired open holds and create 500 holds in a rolling 24-hour window, shared across keys and modes. Rejection or cancellation does not refund the rolling creation limit. Admission atomically reserves capacity and the pending ID. The payload plus rendered review is limited to 4 MiB. Records contain recipient and message data and are subject to 30-day TTL retention; expiry after 24 hours prevents approval or execution but does not immediately delete the record. Use Idempotency-Key for creation retries; MCP requires it. Within the 24-hour reservation window, the same account, mode, idempotency header value, and exact body recover the reserved hold; changed payload returns 409 idempotency_conflict. On unknown_hold, read the pending ID when returned. A network timeout may omit it: replay the same header and body, then use a bounded recent-hold lookup if needed. Never change the key or create a replacement send to resolve uncertainty.

Body Parameters

Provide exactly one of message or messages.
object
One POST /v2/send request body: to, list_number, body, and optionally wrap_links, metadata, contact_data, linkOverrides.
object[]
A POST /v2/send/bulk batch of up to 1000 messages, held and approved as one unit.
string
Why this send should go out, shown to the approver next to the message. At most 500 characters.

Response Fields

string
Pending send ID; use it to poll, cancel, and send.
string
pending on creation. Later approved, executing, unknown_execution, sent, rejected, cancelled, or expired. sent means submitted, not delivered.
object
Publication attempt ID, attempted and confirmed counts, and per-message evidence on detail responses; null before execution. Uncertain outcomes require reconciliation using the same pending ID.
string
send or send_bulk.
integer
Messages in the held payload.
string
The note as submitted, or null.
string
The key that held it.
boolean
true when a sandbox key held it. Only a key in the same mode can execute it.
object
The held payload exactly as submitted: the message body, or { "messages": [...] }. Object keys anywhere in it (for example in metadata or contact_data.custom_fields) cannot start with $ or contain ..
string
ISO-8601, UTC.
string
When an undecided or unexecuted send lapses (ISO-8601, UTC), 24 hours after creation. An expired send cannot be approved or sent.
string
When it was approved, rejected, or cancelled; null until then.
string
user:<id> for a dashboard decision, api_key:<id> for a cancel; null until then.
string
The approver’s rejection reason, or null.
string
When execution was claimed; null before a claim. This timestamp does not establish submission or delivery.
string
The key that executed it; null until then.
object
The send response body once executed (message_id and status for a single send; queued_count, error_count, errors for a batch); null before.
object
The error body from the most recent failed send attempt, or null.

Errors

Also 401 invalid_credentials. Supports the Idempotency-Key header.

Examples