Errors
How the Blooio API reports errors and the codes you may see.
The API uses conventional HTTP status codes. Errors return a flat envelope:
{
"error": "ApiError",
"message": "You can only reply to messages from the last 30 days",
"status": 400,
"code": "reply_target_expired"
}The code field is a stable, machine-readable identifier present on known error cases — branch on it rather than the human-readable message.
Status codes
| Status | Meaning |
|---|---|
400 |
Malformed request or validation failure. |
401 |
Missing or invalid API key. |
403 |
Authenticated but not allowed (plan/permission gate). |
404 |
Resource not found. |
409 |
Conflicting state (e.g. webhook limit reached). |
429 |
Rate limit exceeded. |
The API uses conventional HTTP status codes. Route handlers return a structured error envelope:
{
"error": {
"code": "invalid_content",
"message": "text must be a string",
"details": { }
}
}The code field is a stable, machine-readable identifier — branch on it rather than the human-readable message.
Status codes
| Status | Meaning |
|---|---|
400 |
Malformed request. |
401 |
Missing or invalid API key. |
403 |
Authenticated but not allowed (plan/permission gate), or a send blocked by messaging safety. |
404 |
Resource not found. |
409 |
Conflicting state (chat closed, channel not active, idempotency reuse). |
422 |
Validation failed. |
429 |
A conversation-state send limit was reached; the limit lifts when the recipient replies. |
501 |
Endpoint is defined but not implemented yet. |
Authentication failures (
401/403) use a flatter shape:{ "error", "message", "status" }.
Messaging safety codes
Sends can be rejected by the messaging safety system. These codes appear on send endpoints only:
| Code | Status | Meaning |
|---|---|---|
conversation_content_restricted |
403 |
Links, media, and attachments are not allowed before the recipient's first written reply (or in a re-engagement of an inactive conversation). An emoji reaction does not unlock them. Send plain text first. |
conversation_awaiting_reply |
429 |
Up to 3 messages may be sent to a new recipient before they respond. |
conversation_streak_limit |
429 |
Consecutive-message cap since the recipient's last response was reached. |
conversation_inactive_paused |
429 |
No response in 14+ days and the single re-engagement message was already sent. |
safety_new_conversations_paused |
403 |
Brand-new conversations from this number are temporarily paused; replies to existing conversations are unaffected. |
safety_reply_only |
403 |
Outbound from this number is restricted to conversations with prior inbound. |
safety_account_review |
403 |
The number is blocked pending account review. |
Every conversation_* body carries a conversation_state, and the streak errors also carry current_streak and limit, so you can tell exactly which rule you hit and how much headroom the thread has.
Emoji reactions count as a response. A tapback clears the consecutive-message counter and keeps a thread from going inactive, so these limits lift the moment the recipient reacts. A reaction is not a reply, though: only writing back raises the cap and unlocks links, media, and attachments.
Number-level actions (safety_*) clear automatically as the underlying sending pattern ages out; subscribe to the safety.state_changed webhook event to be notified when a number's state changes.