Send later — schedule an Inbox reply end to end
Send later lets an agent write a reply to a conversation now and have it dispatched at a future timestamp, without building a macro or a campaign. The reply parks on the scheduled-outbound pipeline until the dispatcher picks it up, and you can list what’s pending or pull it back at any point before it fires. This guide walks the feature end to end: when it applies, the three endpoints behind it, the validation rules that decide what gets accepted, and a worked example you can paste.1
Know what send later does
Compose now, dispatch later, parked on the scheduled outbound pipeline.
2
Schedule, list, cancel — the three endpoints
POST to schedule, GET to list pending, DELETE to cancel before dispatch.
3
Know when it isn't a macro
Standalone single-shot vs the macro’s scheduleFollowUp step.
4
Front-load the validation rules
Future timestamp, inside the 35-day horizon, body within limits.
5
Handle the no-destination failure
A conversation with no contact phone or email rejects with 422.
6
Understand the channel behavior
Defaults to the conversation’s channel; routed by your standard sender setup.
7
Run the worked example (SMS and email)
Schedule a reply, list pending, watch it promote, cancel before dispatch.
8
Know when NOT to use send later
Cadence belongs in macros; bulk and drip belong in campaigns.
1. What send later does
Send later is an Inbox composer affordance, not a separate sending system. The flow:- An agent composes the reply exactly as they would for an immediate send.
- Instead of dispatching now, the reply is stored with a future
scheduled_attimestamp and ascheduledstatus. - The scheduled-message dispatcher fires roughly once a minute and promotes any reply whose
scheduled_athas passed, sending it through the same channel path an immediate reply would take. - Until dispatch, the reply is fully visible and fully cancellable: list the pending replies on the conversation, delete one to pull it back.
2. The three endpoints
Everything the composer’s Send later affordance does routes through three endpoints under the Inbox API. You can drive the same behavior from an integration.Schedule a reply
POST /api/v1/inbox/conversations/{convId}/scheduled-replies
A successful schedule returns 201 with the parked row:
List pending scheduled replies
GET /api/v1/inbox/conversations/{convId}/scheduled-replies
scheduled — dispatched and cancelled rows drop out. Entries are ordered by scheduled_at, earliest first, and the server caps the response at 50 pending replies per conversation, with the cap echoed back as limit so you know when it bit. Each entry carries the recipient, body, media URL, and both author and macro attribution (scheduled_by_user_id, source_macro_id). Point your “Pending sends” drawer at this endpoint; it polls happily on a 30-second cadence.
Cancel a pending scheduled reply
DELETE /api/v1/inbox/scheduled-replies/{id}
cancelled, but only while it’s still parked. Once the dispatcher has promoted the row (queued, sending, sent, failed, or already cancelled), the endpoint returns 404 — by design, there’s no difference between “no such reply” and “too late to cancel” in the response you get, so a caller can’t probe for the moment a reply dispatches. There is no credit to refund at cancel time: balance is debited on the send path after the dispatcher promotes the row, so a still-parked reply has no charge posted against it.
3. Send later vs a macro’s scheduleFollowUp step
A macro can also schedule a follow-up — itsscheduleFollowUp step rides the same scheduled-outbound pipeline. The difference is scope:
- Send later is a standalone, single-shot schedule. One reply, one timestamp, no macro definition to author. This is the composer’s “Send at 9 AM tomorrow” case.
- A macro’s scheduleFollowUp step is one step inside a multi-step run — it can sit alongside steps that change the conversation status, add tags, or create a task, and the whole chain runs as one run-log entry.
4. Validation rules, front-loaded
The schedule endpoint validates before anything is stored, so an invalid timestamp comes back as a 422 the composer can render inline, not a 500 after persistence. Three checks:scheduled_atmust be an ISO-8601 timestamp in the future. A past or malformed value rejects with codeINVALID_SCHEDULED_ATand the messagescheduled_at must be in the future.scheduled_atmust be within the 35-day platform horizon. Anything farther out rejects with the same code and amust be within 35 daysmessage. The composer-side picker enforces the same window, so the API and the dashboard agree on what counts as far enough.- The body must be 1–8,000 characters. An empty or over-long body rejects with
INVALID_BODYand the field issues attached.
5. The no-destination failure
Scheduling needs somewhere to send. The endpoint resolves the destination from the conversation: foremail it uses the conversation’s email address; for every other channel it prefers the phone number and falls back to the email address. If the conversation has neither a contact phone nor a contact email, the request rejects with 422 and code NO_DESTINATION — so a missing destination never parks a reply that can never deliver. If you hit it in a workflow, enrich the contact record on the conversation first, then re-schedule.
6. Channel behavior
By default the reply goes out on the conversation’s own channel — a WhatsApp conversation schedules a WhatsApp reply, an email conversation schedules an email reply. You can override per-request with thechannel field (for example, schedule an SMS on an email conversation), and the list is the full Inbox channel set, not just SMS and email.
Either way, the send rides your workspace’s standard sender stack: the numbers, senders, and providers you configured under Inbox settings pick up the reply at dispatch exactly as if the agent had pressed send immediately. Nothing about scheduling changes carrier or sender selection — it only changes when the send leaves.
7. Worked example: schedule, list, watch, cancel
Two snippets — SMS and email.(a) SMS — schedule a morning follow-up
status: "scheduled" and the reply’s id. Keep the id — it’s what cancel and the list entry reference.
(b) Email — schedule a subject/cc-recipient summary for after hours
List what’s still pending on the conversation
status: scheduled. Poll it (the dashboard does this on a 30-second cadence).
Watch it promote
The dispatcher fires about once a minute. Once the scheduled time passes, the row dispatches, and it disappears from the pending list. In the dashboard the composer drawer updates on its next poll; over the API the next GET simply returns without that entry.Cancel before dispatch
status: "cancelled". If you instead get 404, the row already dispatched (or was already cancelled) — there is no window where a cancel races a dispatch silently; the 404 tells you the moment has passed.
8. When to NOT use send later
Send later is deliberately narrow. Three cases it is the wrong tool for:- A per-conversation cadence. If every conversation needs “follow up 48 hours after close”, encode it once as a macro with a
scheduleFollowUpstep, or a ticket-automation rule — not as an agent remembering to schedule each reply by hand. - Bulk or drip delivery. The same message to many contacts, or a multi-touch sequence over days, belongs in Campaigns, where audiences, throttling, and per-contact consent tracking live. Send later addresses one reply on one conversation.
- Workflow gating. If the reply should wait for a human decision rather than a clock — a supervisor’s approval — use the reply-approval queue, which gates content. Send later gates only timing.
See also
- Inbox API reference — the endpoint reference for the three send-later routes, including headers and idempotency behavior.
- Macros — canned responses and multi-step runs — where the scheduleFollowUp step lives, and how a scheduling step composes with status changes and tagging.
- Pending replies — supervisor approval queue — the human-gated variant: hold a reply for sign-off rather than for a timestamp.
- Inbox setup — channels, senders, and routing, which a scheduled reply inherits at dispatch.
- Scheduled sending model — how the scheduled-outbound pipeline works when a reply parks and promotes.