Reference
Errors
One shape, always. The code is stable and meant to be switched on; the message is for a human reading a log and may change.
{
"error": {
"code": "bad_request",
"message": "recipient must not be empty"
}
}| Status | What it means |
|---|---|
| 400 | The request is wrong in a way you can fix. The message says how. |
| 401 | No key, an unknown key, or a revoked one. |
| 404 | No such thing — or one your key may not see. We do not distinguish, because doing so would confirm it exists. |
| 409 | The same text went to the same person moments ago. Pass allow_duplicate if you meant it. |
| 413 | The upload is over the size limit. |
| 422 | The JSON parsed but a required field was missing or the wrong type. |
| 429 | Over 600 requests a minute. Retry-After says how long, in seconds. |
| 503 | The Mac holding that number is offline. Nothing was sent; retry. |
What to retry
429 and 503, after the delay each tells you about. A 4xx otherwise will fail the same way forever — the request is the problem, and repeating it only uses your rate limit.
A 5xx is ours and safe to retry. If you can make one happen with a request that is not obviously nonsense, we would like to know: that is a bug, not a limit. We fuzz the API for exactly this, and the last one it found was a null byte in a text field, which Postgres cannot store — it came back as 500 when it should always have been 400.
Not here yet
Listed so you find out now rather than halfway through building.
Asking Apple whether a handle is on iMessage
The obvious endpoint — give us a number, we say imessage or sms — needs the Messages.app integration the Mac bridge does not have linked yet. /v1/lookup answers from your own traffic instead and says plainly when it does not know. An endpoint that guessed would be worse than none, because the answer is exactly what a caller routes on.
Creating a group chat
You can send into a group that already exists by passing its chat_id as the recipient. Making a new one is a platform operation the bridge does not expose yet.
Contacts
Names for handles live in the console and belong to the person who set them. There is no project-wide address book for a key to read or write yet, so this is console-only rather than half-answered by the API.
Provisioning numbers
Numbers are provisioned by a person, usually within 36–48 hours of purchase. There is no self-serve API for it, because there is no self-serve process behind it to expose.