Sending messages
Every send goes through one endpoint:
Three ways to address a message
Supply exactly one identifier. When a request carries more than one, the API reads them in the order below and ignores the rest.
conversation_id: reply in a thread you already know
The conversation supplies the inbox, so inbox_id is not needed. An id that belongs to another
account returns 404.
contact_id: message a contact you already have
The API reuses the most recent unresolved conversation on that inbox, and opens a new one when
there is none. The contact needs an address the channel can reach: a phone number for WhatsApp,
an email address for email. Without one, the request returns contact_not_messageable. A
channel that cannot be addressed from a contact record at all returns the same code.
phone_number: message someone who may not exist yet
The number must be in E.164 format: a leading +, then the country code, then digits, with no
spaces or dashes. When no contact has that number, the API creates one, and only then does it
use the optional contact attributes. This path works on WhatsApp, Twilio, and SMS inboxes. Any
other inbox returns unsupported_channel.
content is always required, even for a template send. It is what your agents read in the thread.
The messaging window
WhatsApp lets a business send free-form text only within 24 hours of the customer’s last message. Outside that window, only an approved template goes through. Facebook, Instagram, TikTok, Twilio WhatsApp, and API inboxes configured with a reply-time window have their own equivalents.
The API checks the window before it accepts the request, so the failure is immediate and explicit rather than a silent drop later:
A conversation that has never received an inbound message has no open window at all. The first
message to a new contact is always a template. Plain content to a number you have not heard from
returns outside_messaging_window every time.
Some channels have no window: website, email, SMS, and API inboxes with no configured reply-time window. The check never affects them.
template_params skips the window check on every channel, including channels that do not support
templates. On a channel that ignores the field, the API sends the free-form content instead, and
the provider alone enforces the window. Send template_params only on a channel where you have
an approved template.
Conversation reuse
An API send lands in the same thread as the customer’s replies. The API reuses the most recent conversation that is not resolved. When the last one was resolved, a new conversation opens. An inbox configured to lock to a single conversation always reuses the latest one, resolved or not.
A follow-up send to the same number therefore continues the existing thread instead of splitting your agents’ view.
Authorization scope
A key is authorized for a whole account and can send through any inbox in it. Read Errors for the full statement and how to store these keys.
Rate limit
The API accepts 600 requests per minute per key. Each key has its own budget, so one busy
integration does not starve the others on the account. Over that limit it returns 429. See
Errors.