Skip to navigation

Errors

The developer API has 2 groups of endpoints, and their error bodies are not the same:

  • The send endpoint (POST .../developer/messages), the pre-call context endpoint (GET .../developer/precall_context), and the phone number contact endpoints. Their errors have a stable error code and a message.
  • The conversation and contact endpoints. Their errors have a text in error, or a message and a list of attributes.

Send and pre-call context errors

The send and pre-call context endpoints return this body for a 422 and a 404:

{
"error": "outside_messaging_window",
"message": "The customer service window is closed for this conversation. Send a template message instead."
}

error is a stable code for a program. Branch on it. message is for a person who reads your logs. It can change at any time.

422 Unprocessable Entity

The API understood the request but cannot do it.

CodeCauseWhat to do
phone_number_requiredThe request to a phone number contact endpoint had no phone_number.Send phone_number. See Contacts.
validation_failedThe create or update by phone number request has a field that is not valid. For example, another contact has the email address. message gives the reason.Correct the field. The API changed nothing.
identifier_requiredThe request had none of conversation_id, contact_id, or phone_number.Send exactly 1 of them.
inbox_id_requiredThe send request had no conversation_id and no inbox_id.Add inbox_id.
content_requiredcontent and template_params were both empty. Or content was empty and the inbox has no approved template with that name and language. A Twilio inbox always needs content.Send content, or fix the template name and language. See Templates.
invalid_phone_numberThe number is not in E.164 format.Send a +, the country code, then digits only.
unsupported_channelThe send request used phone_number on an inbox that has no phone numbers.Use phone_number only on WhatsApp, Twilio, and SMS inboxes. Use contact_id on other inboxes.
contact_not_messageableThe contact has no address that the channel of the inbox can reach.Add a phone number to the contact, or an email address for an email inbox.
outside_messaging_windowThe request had plain content and the service window has closed, or the customer never sent a message.Send a template. See Templates.
contact_conflictThe API could not save the contact fields of a new contact. Usually another contact has the email address already. An email address with a wrong format also causes this error.Send the request without contact.email, or correct the address. message names the field.

contact_conflict is strict on purpose. If the API used the contact that has that email address, it would send your message to the phone number of that contact. The API rejects the request instead.

A send can also fail with a 422 that has a message and attributes and no error code. An example is a send with template_params to the Phone inbox, which cannot deliver a message. A send with plain content to the Phone inbox fails first with outside_messaging_window. See Conversation and contact errors.

The phone number contact endpoints (GET .../developer/contacts/by_phone and POST .../developer/contacts/create_or_update) return the same body for a 422. They return 404 with the text body in Conversation and contact errors.

404 Not Found

{ "error": "not_found", "message": "Couldn't find Conversation" }

The conversation_id, contact_id, inbox_id, or phone_number is not in this account. An id from another account gives the same 404. The API never tells you that an id exists in another account.

Conversation and contact errors

The conversation, label, assignment, and contact endpoints return these bodies.

A 404 has 1 fixed text:

{ "error": "Resource could not be found" }

A 422 for a field that is not valid has a message and the names of the fields. An example is an email address that another contact has:

{ "message": "Email has already been taken", "attributes": ["email"] }

A 422 for a filter that is not valid, or for a message that the API cannot create, has the reason in error:

{ "error": "Query operator must be either \"AND\" or \"OR\"." }

401 Unauthorized

The API returns 401 for all authentication and account failures. It has no separate 403. When the request has a token, the body has only the error field:

{ "error": "Invalid Access Token" }
errorCause
Invalid Access TokenThe api_access_token header has a token that does not exist, or a deleted key.
Key is not authorized to access this accountThe key belongs to another account than the account_id in the path.
Access to this endpoint is not authorized for this tokenThe token is not an API key, for example the personal access token of a user.
You are not authorized to access this accountThe token is the token of a user who is not a member of the account in the path.
Account is suspendedThe account is not active.

A request with no api_access_token header also returns 401. Its body is a sign-in error with a different shape, not an error field.

A key reaches the whole account that created it: every inbox, conversation, and contact. It reaches nothing in other accounts.

Keep a key as secret as a password. Create 1 key for each integration, so that you can revoke 1 key and keep the others.

429 Too Many Requests

By default, a key can send 300 requests in 1 minute. The key sent more than its limit. Wait until the next minute. Then try again.

The rate limit applies before the application gets the request. The body is therefore plain text, not JSON:

Retry later