Error Reference
All errors follow a consistent structure:
{
"error": {
"type": "error_type_slug",
"message": "Human-readable description."
}
}Validation errors include a detail map with per-field errors:
{
"error": {
"type": "validation_error",
"message": "Could not perform the request with the provided parameters.",
"detail": {
"body": ["can't be blank"],
"to": ["is not a valid E.164 phone number"]
}
}
}Authentication and authorization
| Type | HTTP status | Description |
|---|---|---|
missing_api_key | 401 | No Authorization header was provided |
invalid_api_key | 401 | The API key doesn't exist or has been revoked |
demo_api_key | 403 | The action requires a live key but a demo key was used |
platform_locked | 403 | The platform has been locked due to a policy violation |
Resource errors
| Type | HTTP status | Description |
|---|---|---|
not_found | 404 | The requested resource doesn't exist |
account_not_found | 404 | The account ID in the path doesn't exist or isn't accessible |
account_archived | 410 | The account has been archived and no longer accepts mutating operations |
bad_request | 400 | The request body is malformed (unparseable JSON, wrong content type, etc.) |
Validation errors
| Type | HTTP status | Description |
|---|---|---|
validation_error | 422 | One or more fields failed validation. Check the detail map for field-level errors |
invalid_pagination | 422 | The cursor value is invalid or the pagination parameters are out of range |
State and business rule errors
| Type | HTTP status | Description |
|---|---|---|
account_not_ready | 422 | The account doesn't have enough information to perform this action (e.g., create a campaign) |
accounts_limit_exceeded | 422 | The platform has reached its maximum number of accounts |
link_size_limit | 422 | The message contains too many URLs |
opted_out | 422 | The recipient has opted out; sending is not permitted |
campaign_locked | 422 | The campaign cannot be updated in its current status |
Rate and quota errors
| Type | HTTP status | Description |
|---|---|---|
demo_message_limit | 403 | The demo number's 25-message limit has been reached |
Server errors
| Type | HTTP status | Description |
|---|---|---|
internal_server_error | 500 | Something went wrong on Surge's side. These are logged automatically; contact support if they persist |
Messaging-layer errors
These errors appear as failure_reason in message.failed webhook events after a message was accepted. They come from the carrier network or Surge's delivery pipeline, not from the Surge API directly.
| Type | Description |
|---|---|
account_archived | The sending account was archived before the message could be dispatched |
account_locked | The platform was locked due to a policy violation |
attachment_retrieval_error | Surge couldn't fetch the attachment URL to build the MMS |
blocked | The number has been explicitly blocked at the carrier level |
carrier_error | A transient error from the carrier network |
configuration_error | The account's carrier credentials are misconfigured |
daily_message_cap_reached | The campaign's daily T-Mobile volume cap was exceeded |
geo_not_enabled | The destination country is not in the platform's allowed regions |
invalid_attachment_url | The attachment URL is malformed or not publicly accessible |
invalid_content_type | The MMS attachment type isn't supported by the recipient's carrier |
invalid_mobile_number | The destination is not a valid mobile number (permanently undeliverable) |
matching_sender_and_receiver | The sending and receiving number are identical |
message_filtered | The carrier's spam filter or Surge's content policy blocked the message |
message_too_big | The message body exceeds the 1,600-character limit |
mms_not_supported | The recipient's carrier or handset doesn't support MMS |
opted_out | The conversation is opted out; the message was not dispatched |
premium_rate_number | The destination is a premium-rate number |
suspected_fraud | Surge's fraud detection system flagged the send |
unknown_destination | The destination number doesn't exist on any carrier (permanently undeliverable) |
unknown_error | An unclassified error occurred |
unreachable_carrier | The destination carrier network is unreachable (permanently undeliverable) |
unreachable_destination | The recipient's number is disconnected or out of service |
unregistered_number | The sending number isn't registered with the carrier for this message type |
unsupported_route | No valid carrier route exists for this number pair |
Permanently undeliverable numbers. When Surge records invalid_mobile_number, unknown_destination, or unreachable_carrier for a destination, that number is flagged globally. All future sends to it — from any account — are cancelled immediately without reaching the carrier. This prevents wasted volume quota. The flag clears automatically if a future send to that number succeeds.
See Handle Failures for per-reason remediation guidance.
Phone number purchase errors
| Type | Description |
|---|---|
no_matching_numbers | No numbers match the requested type and area code |
phone_numbers_limit_exceeded | The account has reached its phone number limit |