Error Codes
When an API request fails, Sendiee returns a JSON response with a success: false flag, an error code, and a human-readable message. Use the error code for programmatic handling.
Error Response Format
JSON
{
"success": false,
"code": "ERROR_CODE",
"message": "Human-readable error description"
}Rate Limiting
| Error Code | HTTP | Meaning |
|---|---|---|
| RATE_LIMIT_EXCEEDED_PER_SECOND | 429 | Organisation exceeded the per-second request limit on their plan |
| RATE_LIMIT_EXCEEDED_PER_DAY | 429 | Organisation exceeded the daily request limit on their plan |
Authentication & Organisation
| Error Code | HTTP | Meaning |
|---|---|---|
| API_KEY_MISSING | 401 | No API key provided in the request |
| INVALID_API_KEY | 401 | The API key does not exist or is revoked |
| AUTHENTICATION_FAILED | 500 | Internal authentication error |
| ORG_INACTIVE | 403 | Your organisation account is inactive |
| DOMAIN_NOT_WHITELISTED | 403 | Request origin not in the allowed domains list |
| ORG_ID_MISSING | 400 | Internal: org ID could not be resolved |
| ORG_ID_REQUIRED | 400 | Organisation ID could not be resolved from the API key |
Plan Enforcement
| Error Code | HTTP | Meaning |
|---|---|---|
| LIMIT_EXCEEDED | 403 | A numeric plan limit (e.g. max contacts, max tags) has been reached. Response includes limitKey, current, and limit fields. |
| FEATURE_NOT_ENABLED | 403 | The requested feature is not available on the organisation's current plan |
WhatsApp & Messaging
| Error Code | HTTP | Meaning |
|---|---|---|
| BRAND_NUMBER_MISSING | 400 | brandNumber parameter not provided |
| WABA_NOT_FOUND | 404 | No active WhatsApp account for the given brandNumber |
| WABA_RETRIEVAL_FAILED | 500 | Internal error retrieving WhatsApp account |
| MISSING_RECIPIENT | 400 | The "to" field is required |
| INVALID_PHONE_NUMBER | 400 | Phone number failed validation |
| MISSING_TEMPLATE | 400 | Neither templateId nor templateName provided |
| TEMPLATE_NOT_FOUND | 404 | Template not found or not in APPROVED status |
| PARAMETER_VALIDATION_ERROR | 400 | Template parameters count mismatch |
| INVALID_SCHEDULE_TIME | 400 | Scheduled time is in the past |
| META_API_ERROR | 502 | Error returned by Meta's WhatsApp Cloud API |
| MESSAGE_SEND_FAILED | 500 | Internal error sending message |
| MISSING_CONTENT | 400 | Message content is empty or missing |
| MISSING_TEXT_BODY | 400 | Text message missing "body" field |
| MISSING_MEDIA_LINK | 400 | Media message missing "link" field |
| MESSAGE_NOT_FOUND | 404 | Message ID not found in this org |
| STATUS_FETCH_FAILED | 500 | Internal error fetching message status |
| SCHEDULE_NOT_CANCELLABLE | 400 | Message already sent or processing — cannot cancel |
Contacts
| Error Code | HTTP | Meaning |
|---|---|---|
| MISSING_PHONE | 400 | phone field is required but was not provided |
| INVALID_PHONE_NUMBER | 400 | The provided phone number failed validation or formatting |
| INVALID_CUSTOM_FIELDS | 400 | customFields is not a plain object |
| CONTACT_NOT_FOUND | 404 | No contact found for the given identifier |
| CONTACT_ALREADY_EXISTS | 409 | A contact with this phone number already exists (duplicate key) |
Contact Fields
| Error Code | HTTP | Meaning |
|---|---|---|
| INVALID_FIELD_TYPE_FILTER | 400 | The type query param is not one of "default", "custom", "all" |
| MISSING_FIELD_NAME | 400 | fieldName is required but was not provided |
| INVALID_FIELD_TYPE | 400 | fieldType is not one of: text, number, date, boolean, dropdown, multiselect, url, phone |
| MISSING_DROPDOWN_OPTIONS | 400 | options array is required and must be non-empty for dropdown and multiselect fields |
| INVALID_FIELD_KEY | 400 | A valid fieldKey could not be derived from the provided input |
| INVALID_FIELD_ID | 400 | The provided fieldId path param is not a valid MongoDB ObjectId |
| CUSTOM_FIELD_NOT_FOUND | 404 | No custom field found with the given fieldId for this organisation |
| CUSTOM_FIELD_ALREADY_EXISTS | 409 | A custom field with this fieldKey already exists for this organisation |
Contact Tags
| Error Code | HTTP | Meaning |
|---|---|---|
| MISSING_TAG_NAME | 400 | name is required but was not provided |
| INVALID_TAG_ID | 400 | The provided tagId path param is not a valid MongoDB ObjectId |
| TAG_NOT_FOUND | 404 | No tag found with the given tagId for this organisation |
| TAG_ALREADY_EXISTS | 409 | A tag with this name already exists for this organisation |
Wallet
| Error Code | HTTP | Meaning |
|---|---|---|
| WALLET_NOT_FOUND | 404 | No active wallet found for this organisation |
Channels
| Error Code | HTTP | Meaning |
|---|---|---|
| INVALID_CHANNEL | 400 | The channel query param is not one of "whatsapp", "instagram", "messenger" |
| NO_CHANNELS_FOUND | 404 | No active business accounts found for the organisation (or for the specified brandNumber) |
Teambox — Teams, Agents & Conversations
| Error Code | HTTP | Meaning |
|---|---|---|
| LOCATOR_REQUIRED | 400 | Neither conversationId nor phone was supplied to an assign / unassign / status / history call |
| ASSIGNEE_REQUIRED | 400 | Neither agentId nor teamId was supplied when assigning |
| TEAM_REQUIRED | 400 | The agent belongs to zero or several teams — send teamId as well |
| MANAGER_NOT_MEMBER | 400 | A team manager id is not also in the team's agentIds |
| STATUS_REQUIRED | 400 | No status key supplied when changing a conversation status |
| UNKNOWN_STATUS | 400 | That status key is not defined in this workspace — read GET /v2.0/conversations/statuses |
| NO_WHATSAPP_CHANNEL | 400 | A phone locator was used but the org has no active WhatsApp number |
| CHANNEL_AMBIGUOUS | 400 | The org has several WhatsApp numbers — pass businessNumber |
| CHANNEL_ID_REQUIRED | 400 | Instagram / Messenger locators always need an explicit businessNumber |
| INVALID_CONVERSATION_ID | 400 | conversationId is not a valid id |
| LIMIT_EXCEEDED | 403 | The plan max_teams (or agent seat) cap is reached |
| FORBIDDEN | 403 | The agent is not an active member of the org, or not on the target team |
| NO_AVAILABLE_AGENT | 409 | Team-only assignment, but the team has no assignable agent |
| LAST_TEAM | 409 | Removing an agent whose only team this is — add them to another team first |
| TEAMBOX_NOT_CONFIGURED | 503 | The realtime inbox backend is not enabled for this environment |
| UPSTREAM_ERROR | 502 | The inbox backend could not be reached — retry; it is not a problem with your payload |
Generic
| Error Code | HTTP | Meaning |
|---|---|---|
| INTERNAL_SERVER_ERROR | 500 | An unexpected server-side error occurred |
Handling Errors
- 400 errors — Check your request parameters. The
messagefield will explain what's wrong. - 401 errors — Verify your API key is correct and included in the Authorization header.
- 403 errors — Check your account status, domain whitelisting, or plan limits.
- 404 errors — The requested resource (template, contact, message, field, tag, etc.) was not found.
- 409 errors — A resource with that identifier (phone, fieldKey, tag name) already exists.
- 429 errors — Rate limit exceeded. Check the
Retry-Afterheader. - 500 errors — These are server-side issues. Retry with exponential backoff. If persistent, contact Sendiee support.