readyDocs Open the appOpen the app

Scheduled texts

Schedule one text to one contact for later. Nothing is charged until it sends. To send later what you would send with Send a message, call POST /sms/schedule with the same text in body or message and a send_at. It takes from as Send a message does, but not from_strategy.

#Schedule a text

Queues one text to one of your contacts for a later time. Nothing is sent or charged now. When the time comes, Ready sends it like any other text and charges your per-segment rate then. Needs the send_sms permission. Test keys can’t call it.

Parameters

messagestringRequired
The text to send. Merge fields are filled in for the contact when it sends. body is the same field, as on Send a message; when both come, body is used.
send_atISO 8601 stringRequired
When to send it, like 2026-11-20T15:00:00Z. Include Z or a time zone offset, such as 2026-11-20T15:00:00-06:00: a time without one is read as UTC, and a date alone as midnight UTC. It must be more than 30 seconds from now.
More parameters
contact_idinteger | string
The contact to text. Send this or to.
tostring
The contact’s phone number. Matched to your contacts on the last 10 digits. When no contact has that number, Ready adds one and schedules the text, as Send a message does.
conversation_idinteger | string
The conversation to put it in. Kept only when it’s your conversation with this contact.
fromE.164 string
One of your numbers to send it from. Leave it out and Ready picks when it sends.
media_urlstring
One web address that starts with http:// or https://, sent as a picture text. Get one from Upload a file.
confirm_empty_mergeboolean
Send true to schedule it even when a merge field is blank for this contact.

Any other field is refused with unknown_field.

Returns
data.idinteger
The scheduled text’s id. Use it to cancel it.
data.send_atstring
The send time, in UTC.
duplicateboolean
Only present, as true, when you sent the same text to the same contact for the same time again. Nothing new was queued; data.id is the first one.

When it sends

Ready checks for due texts about once a minute. Every check a normal send runs happens then, not when you schedule:

  • A contact who opted out by then doesn’t get it.
  • During the contact’s quiet hours it waits for the next allowed time. If that is too far off, it fails instead of going out late.
  • If your balance is too low, it isn’t sent and you aren’t charged. It either fails, or waits with status balance_held and sends by itself once you top up.
  • If your registration was suspended after you scheduled it, it fails.
  • A text more than 24 hours past its time, for example after an outage, fails instead of going out late.

Each of these leaves the text in List scheduled texts with an error that says why.

A blank merge field answers 200 with "success": false, error_code: "empty_merge_field" and empty_fields. Nothing was scheduled. Send again with "confirm_empty_merge": true to schedule it with the blank.

Errors
HTTPCodeWhen
400invalid_fieldmessage or send_at is missing or blank, or a field has the wrong type.
400unknown_fieldA field this endpoint doesn’t take.
400invalid_fromfrom isn’t one of your numbers. Nothing was scheduled.
400invalid_media_urlmedia_url isn’t one http:// or https:// address.
400no codesend_at isn’t a date, or it’s less than 30 seconds from now.
400NO_APPROVED_CAMPAIGNYour registration isn’t approved. Also NUMBER_SETUP_UNCONFIRMED, when Ready can’t confirm the number’s setup.
403permission_deniedYour role doesn’t have send_sms.
403test_key_not_allowedYou used a test key. Use a live key.
403number_not_assignedA team member picked a from number that isn’t assigned to them.
404no codeThe contact_id or conversation_id isn’t yours.
409duplicate_scheduleThe same text is being scheduled right now. Check your scheduled texts before you try again.
500contact_lookup_failedReady couldn’t check the contact. Nothing was scheduled; retry.
503from_check_unavailableReady couldn’t check the from number. Nothing was scheduled; retry.
503merge_check_failedReady couldn’t check the merge fields. Nothing was scheduled; retry.
503schedule_dedupe_unavailableReady couldn’t tell if this text was already scheduled, so it held this one. Check your scheduled texts before you retry.

#List scheduled texts

Your account’s scheduled texts that haven’t gone out yet, soonest first, plus the ones that failed in the last 3 days with the reason. Texts that were sent or cancelled aren’t listed. Returns up to 200.

Parameters

contact_idinteger, query
Only this contact’s scheduled texts.
Returns
data[].idinteger
The scheduled text’s id.
data[].contact_idinteger
The contact it goes to.
data[].to_numberstring
The number it goes to.
data[].conversation_idinteger | null
The conversation it goes in, when one was given.
data[].bodystring
The text as you wrote it, merge fields not filled in.
data[].send_atstring
When it sends. Quiet hours or a balance hold can move it later.
data[].statusenum
pending (waiting), sending (going out now), balance_held (waiting for you to top up) or failed.
data[].errorstring | null
Why it failed or is waiting, in a sentence you can show. The wording can change, so don’t match on it.
data[].cancelableboolean
true when Cancel a scheduled text would cancel it (pending or balance_held).
truncatedboolean
true when more scheduled texts wait past these 200. Filter by contact_id to see one contact’s texts in full.
Errors
HTTPCodeWhen
400invalid_fieldcontact_id isn’t a whole number.
500scheduled_list_failedThe list couldn’t be loaded. Retry before you schedule anything new, so you don’t schedule a text twice.

#Cancel a scheduled text

Cancels a scheduled text that hasn’t gone out. Only a pending or balance_held text can be cancelled. Nothing was charged, so there’s nothing to refund. Needs the send_sms permission. Test keys can’t call it.

Parameters

idinteger, pathRequired
The scheduled text’s id.
Returns

{ "success": true }. Canceling again answers 409 with status: "canceled".

Errors
HTTPCodeWhen
400invalid_fieldid isn’t a whole number.
403permission_deniedYour role doesn’t have send_sms.
403test_key_not_allowedYou used a test key. Use a live key.
404not_cancelableNo scheduled text with that id on your account. status is null.
409not_cancelableIt can’t be cancelled anymore. status says why: sending, sent, canceled or failed.
500cancel_failedIt wasn’t cancelled and is still scheduled. Retry.