Error Codes
Every error response from the Textingline API follows a consistent structure:
{
"code": 33001,
"message": "Authentication failed",
"status": 401,
"moreInfo": "https://docs.smsfactory.com/docs/error-codes"
}| Field | Description |
|---|---|
code | Numeric error code specific to the Textingline API |
message | Human-readable description of the error |
status | HTTP status code |
moreInfo | Link to this error reference page |
details | (optional) Structured error details when additional context is available |
Some errors include a details object with machine-parseable information about the failure. For example, the Recipients Not Opted In error includes the list of phone numbers that failed the check:
{
"code": 33028,
"message": "One or more recipients are not opted in to any group",
"status": 400,
"moreInfo": "https://docs.smsfactory.com/docs/error-codes",
"details": {
"notOptedIn": ["+18005551234", "+18005559876"],
"totalNotOptedIn": 2
}
}The details field is only present for errors that provide it — most errors return only the four standard fields.
Error code reference
Authentication & Authorization
| Code | HTTP Status | Description |
|---|---|---|
33001 | 401 | Authentication failed — Invalid or missing API credentials |
33004 | 403 | Number not owned — The from number is not assigned to your account |
33020 | 403 | Account not configured — Account is missing required configuration (e.g., whitelabel) |
33021 | 403 | User not active — The user account is suspended, deactivated, or pending |
33022 | 403 | API not enabled — API access has not been enabled for this account |
33027 | 429 | Authentication locked — Too many failed auth attempts from this IP; temporarily locked out |
33001 — Authentication Failed
The provided API credentials are invalid, missing, or the account is disabled. Common causes include a missing or malformed Authorization header, incorrect credentials, or a revoked API key. See Authentication for setup details.
33004 — Number Not Owned
The from number in the request is not assigned to the authenticated account. You can only send messages from numbers that have been provisioned and assigned to your account.
33020 — Account Not Configured
The account is not fully configured for messaging. This typically means the sender number has no associated whitelabel configuration. Contact support to complete account setup.
33021 — User Not Active
The user account is suspended, deactivated, or pending activation. Contact support to restore access.
33022 — API Not Enabled
API access has not been enabled for this account. Contact support to enable API access.
33027 — Authentication Locked
Too many failed authentication attempts have been made from your client IP. The IP is temporarily locked out — every subsequent request returns 33027 until the lockout window expires, regardless of whether the credentials are valid. Wait and retry; once the window elapses, normal authentication resumes.
This is distinct from 33002 Rate Limit Exceeded: 33002 is per-API-key and reflects a legitimate caller exceeding their plan throughput, while 33027 is per-IP and reflects repeated authentication failures (typically a credential bug or a brute-force attempt). If you're hitting 33027 from a production integration, double-check that your Key ID and Key Secret are correct — see Authentication.
Request Validation
| Code | HTTP Status | Description |
|---|---|---|
33003 | 400 | Invalid phone number — A phone number is not in valid E.164 format or short code |
33005 | 400 | Missing required field — A required field is missing from the request |
33006 | 400 | Invalid message type — The message type is not supported |
33016 | 400 | Invalid message content — The message body contains unsupported characters |
33024 | 400 | Request validation failed — The request body failed validation (e.g., duplicate recipients) |
33003 — Invalid Phone Number
The to or from phone number is not in a valid format. Phone numbers must be in E.164 format — starting with + followed by the country code and subscriber number (e.g., +18005551234). The from field also accpts short codes (5-6 digits, e.g., 12345).
33005 — Missing Required Field
A required field in the request body is missing. For send message: to, from, and body (when no mediaUrl is provided). For broadcast: recipients, from, and body (when no mediaUrl). For batch: recipients and from (each recipient must have at least body or mediaUrl).
33006 — Invalid Message Type
The messageType field must be either SMS or MMS. This error is returned when an unsupported value is provided.
33016 — Invalid Message Content
The message body contains characters that are not supported for SMS transmission. The error response may include an additionalInfo field listing each invalid character and its position in the body.
33024 — Request Validation Failed
The request body failed general validation. This includes issues such as duplicate phone numbers in the recipients array for broadcast and batch requests, or batch recipients missing both body and mediaUrl.
Sender & Recipient
| Code | HTTP Status | Description |
|---|---|---|
33008 | 400 | Sender number not available — The from number is not available for sending |
33009 | 400 | Sender number not active — The from number exists but is not in an active state |
33010 | 403 | Recipient blocked — The recipient number is on the block list |
33011 | 403 | Sender blocked — The sender number is on the block list |
33025 | 400 | Unsupported carrier — The recipient's carrier is not supported |
33028 | 400 | Recipients not opted in — One or more recipients are not opted in to any group |
33029 | 400 | Recipients hard-opted-out — One or more recipients have explicitly refused messages |
33008 — Sender Number Not Available
The from number is not provisioned or not currently available for sending. The number may not have been set up, has been released, or is temporarily unavailable.
33009 — Sender Number Not Active
The from number exists in the system but is not in an active state. Possible states include pending, suspended, or deactivated. Contact support to activate the number.
33010 — Recipient Blocked
The recipient (to) phone number has been blocked. This may occur because the recipient has opted out or the number appears on a block list. Note: in broadcast and batch sends, blocked recipients are silently skipped rather than returning this error.
33011 — Sender Blocked
The sender (from) phone number has been blocked or suspended. Contact support to resolve this issue.
33025 — Unsupported Carrier
The recipient's carrier is not supported for messaging. This occurs when the carrier associated with the destination phone number cannot be used for message delivery. Try a different recipient number or contact support if you believe this is an error.
33028 — Recipients Not Opted In
None of the recipients in the request are opted in to a group owned by your account. Every recipient must be an active contact with at least one group membership before a message can be sent.
The error response includes a details object listing the phone numbers that failed the check:
{
"code": 33028,
"message": "All recipients are not opted in to any group",
"status": 400,
"moreInfo": "https://docs.smsfactory.com/docs/error-codes",
"details": {
"notOptedIn": ["+18005551234", "+18005559876"],
"totalNotOptedIn": 2
}
}| Detail field | Description |
|---|---|
notOptedIn | Array of phone numbers that are not opted in |
totalNotOptedIn | Total count of phone numbers that are not opted in |
For single messages: The request fails if the recipient is not opted in.
For broadcasts and batches: Non-opted-in recipients are filtered out and the send proceeds for the remaining recipients. The response's totalRecipients reflects the post-filter count. This error is returned only when every recipient in the request is not opted in.
33029 — Recipients Hard-Opted-Out
The recipient (or every recipient in a broadcast / batch) has explicitly refused to receive messages — typically by texting STOP, opting out at a kiosk, or being flagged via carrier propagation. This is a permanent compliance signal and cannot be overridden from your account. Re-engaging these contacts requires fresh consent: the contact must text in again, opt in via a hosted form, or otherwise affirmatively opt back in.
The error response includes a details object listing the phone numbers that triggered the refusal:
{
"code": 33029,
"message": "All recipients are hard-opted-out and cannot be re-engaged without fresh consent from the contact.",
"status": 400,
"moreInfo": "https://docs.smsfactory.com/docs/error-codes",
"details": {
"hardOptedOut": ["+18005551234", "+18005559876"],
"totalHardOptedOut": 2
}
}| Detail field | Description |
|---|---|
hardOptedOut | Array of phone numbers that have explicitly refused messages |
totalHardOptedOut | Total count of phone numbers that have explicitly refused messages |
For single messages: The request fails if the recipient is hard-opted-out.
For broadcasts and batches: Hard-opted-out recipients are filtered out and the send proceeds for the remaining recipients. The response's totalRecipients reflects the post-filter count. This error is returned only when every recipient in the request is hard-opted-out.
Content & Compliance
| Code | HTTP Status | Description |
|---|---|---|
33019 | 400 | Non-compliant content — Message body violates carrier compliance rules (SHAFT, phishing, etc.) |
33019 — Non-Compliant Message Content
The message body violates messaging compliance rules. All outbound messages are screened against industry standards including SHAFT content (Sex, Hate, Alcohol, Firearms, Tobacco), phishing, fraud indicators, and regulated industries. See Compliance for full details.
Media
| Code | HTTP Status | Description |
|---|---|---|
33014 | 413 | Media too large — The media file exceeds the 600 KB size limit |
33015 | 400 | Media type not supported — The file MIME type is not allowed |
33017 | 400 | Media upload failed — The media file could not be downloaded or processed |
33018 | 400 | Media URL not allowed — The URL failed security validation |
33026 | 400 | Media download failed — The media file could not be downloaded from the provided URL |
33014 — Media Too Large
The media file exceeds the maximum allowed size of 600 KB (614,400 bytes). Reduce the file size or use a lower-resolution version before retrying.
33015 — Media Type Not Supported
The media file has a MIME type that is not supported. See MMS & Media for the full list of accepted types.
33017 — Media Upload Failed
The media file could not be downloaded or processed. Common causes include an unreachable URL, server timeout, or a corrupted file. Verify the URL is publicly accessible and returns a valid media file.
33018 — Media URL Not Allowed
The mediaUrl failed security validation. The URL must use http:// or https://, point to a publicly accessible resource, and must not resolve to a private or internal IP address.
33026 — Media Download Failed
The media file could not be downloaded from the provided URL. Common causes include the URL returning a 404 (file not found), the remote server being unreachable, or a connection timeout. Verify the URL is publicly accessible and returns a valid media file before retrying.
Rate Limits & Quotas
| Code | HTTP Status | Description |
|---|---|---|
33002 | 429 | Rate limit exceeded — Too many requests in the current window |
33012 | 429 | Daily quota reached — Account has reached its daily messaging limit |
33023 | 402 | Insufficient credits — Not enough credits to send the message |
33002 — Rate Limit Exceeded
The account has exceeded the allowed number of requests within the current rate-limit window. Check the X-RateLimit-* response headers and wait until the Retry-After period has elapsed. See Rate Limits for default limits per endpoint.
33012 — Daily Quota Reached
The account has reached its daily messaging quota. The quota resets at midnight UTC. Contact support if you need a higher daily limit.
33023 — Insufficient Credits
The account does not have enough credits to send the requested message. See MMS & Media for credit costs per message type.
Contact Management
| Code | HTTP Status | Description |
|---|---|---|
33030 | 404 | Contact not found — No contact at the given phone number for your account |
33031 | 404 | Group not found — No group with the given grp_* ID for your account |
33032 | 400 | Phone number immutable — Reserved; not currently surfaced (body validation rejects phoneNumber via the standard envelope) |
33033 | 400 | Invalid custom field — A customFields write failed validation. See details.reason for the cause |
33034 | 400 | Invalid public ID — A con_* / grp_* / tag_* ID in the URL is malformed |
33035 | 409 | Contact hard opted-out — Contact has explicitly refused messages and cannot be re-enrolled by the operator |
33036 | 409 | Contact pending — Contact has pending memberships in other groups; resolve those before adding to a new group |
33037 | 409 | Contact already exists — A contact at this phone number is already on file. Use GET + PATCH to merge |
33030 — Contact Not Found
No contact exists at the given phone number for your account. The phone number must be a contact you've previously created or imported. To create a new contact, see Contacts — POST.
33031 — Group Not Found
No group exists at the given grp_* ID in your account. Discover your account's groups via Groups — LIST. Groups are managed in the dashboard — the API cannot create them.
33032 — Phone Number Immutable
Reserved error code. Not currently surfaced — the contact PATCH endpoint rejects a phoneNumber in the body via the standard whitelist-validation envelope rather than emitting this code. Documented for forward compatibility.
33033 — Invalid Custom Field
A value in customFields failed validation. The error response includes a details object with the offending label and a machine-readable reason:
{
"code": 33033,
"message": "Invalid custom field \"Age\": type_mismatch",
"status": 400,
"moreInfo": "https://docs.smsfactory.com/docs/error-codes",
"details": {
"label": "Age",
"reason": "type_mismatch"
}
}details.reason | What it means |
|---|---|
unknown_label | The label doesn't match any visible field on your schema. The customer-supplied label is echoed verbatim in details.label (typos surface clearly). |
duplicate_label_input | The body has two keys that normalize to the same label (e.g. "Favorite Color" and "FAVORITE COLOR"). Pick one canonical key. |
type_mismatch | Value type doesn't match the schema field's type (e.g. sending a string to a NUMBER field). |
unknown_option | SINGLE_SELECT / MULTI_SELECT value isn't in the field's options. Match is case-sensitive. |
duplicate_option | MULTI_SELECT array contains the same option twice. |
invalid_date_format | DATE value doesn't match YYYY-MM-DD. |
invalid_calendar_date | DATE value matches the format but isn't a real calendar date (e.g. 2026-02-30). |
length_exceeded | TEXT value exceeded the per-field maximum length enforced server-side. |
See Custom Fields for the schema-discovery endpoint and field-type reference.
33034 — Invalid Public ID
A con_*, grp_*, or tag_* ID in the URL is malformed. IDs are returned by the API on previous responses — do not hand-construct them.
33035 — Contact Hard Opted-Out
The contact has explicitly refused messages (texted STOP, opted out at a kiosk, or was flagged via carrier propagation). This is a permanent compliance signal and cannot be overridden by the operator. Adding the contact to a group via Group Membership — POST returns this error.
Re-engaging a HARD-opted-out contact requires fresh consent from the contact themselves — replying YES to a new opt-in or opting back in via a hosted form.
{
"code": 33035,
"message": "Contact is HARD opted-out and cannot be re-enrolled",
"status": 409,
"moreInfo": "https://docs.smsfactory.com/docs/error-codes"
}33036 — Contact Pending
The contact has pending memberships in groups other than the one you're trying to enroll them in. Pending memberships are created when an enrollment uses optInMode: CONFIRM and the contact has not yet replied YES. To resolve, either wait for the contact to respond to the pending opt-in or DELETE the pending membership before adding them to a new group.
{
"code": 33036,
"message": "Contact has pending memberships in other groups",
"status": 409,
"moreInfo": "https://docs.smsfactory.com/docs/error-codes"
}33037 — Contact Already Exists
A contact at this phone number is already on file. POST is non-destructive — to merge new data into the existing contact, GET it and then PATCH the fields you want to change. See Upsert a contact from a CRM for the worked pattern.
Delivery & Processing
| Code | HTTP Status | Description |
|---|---|---|
33013 | 409 | Duplicate idempotency key — A request with this key is already being processed |
33007 | 500 | Message send failed — The message could not be submitted to the messaging gateway |
33000 | 500 | Unexpected error — An internal error occurred. Contact support if this persists. |
Note: Provider delivery failures (e.g., recipient opted out, invalid destination) do not return an HTTP error. Instead, the API returns a
201response withstatus: failedalong witherrorTypeanderrorMessagefields describing the reason. See Send a Message for the full list of error types.
33013 — Duplicate Idempotency Key
A message with the same idempotencyKey is currently being processed or a conflict was detected. When an idempotent request completes successfully and is retried, the original response is returned — this error only occurs when a conflict prevents the lookup. See Idempotency for best practices.
33007 — Message Send Failed
The request was accepted and validated, but the messaging gateway returned an unmapped failure when the API attempted to submit the message. This is a catch-all for downstream send failures that don't match a more specific code (33008, 33009, 33019, 33028, etc.) — typically a transient platform issue.
Safe to retry with the same idempotencyKey — if the original send actually succeeded, the original response is returned; otherwise the retry submits a fresh send. See Idempotency. If 33007 recurs across retries with backoff, contact support with the request details and timestamps.
33000 — Unexpected Error
An unhandled internal error occurred. This is a catch-all for errors that do not match a more specific code. If you receive this error repeatedly, contact support with the request details and timestamps.
Message error types
When a message is accepted but fails at the provider or carrier level, the API returns a 201 response with status: failed (or a webhook event with status failed / undelivered). The errorType field classifies the failure reason and the errorMessage field provides a human-readable description.
These error types are distinct from HTTP error codes — they represent delivery-level failures, not request-level errors.
errorType | Description |
|---|---|
unknown | An unspecified error occurred during message processing |
platform_error | An internal platform error prevented the message from being sent |
provider_error | The upstream provider encountered an internal processing error |
carrier_error | The destination carrier reported a general failure |
invalid_destination | The destination number is invalid, unreachable, or not mobile-capable |
invalid_sender | The sender identity is not valid or not authorized for this destination |
sender_unregistered | The sender's registration with the destination carrier or aggregator is missing or pending (e.g. US A2P 10DLC brand/campaign not registered) |
numeric_sender_not_provisioned_on_carrier | The numeric sender ID (typically a short code) is not provisioned on the destination carrier's network. This is a carrier-side provisioning gap, not a customer registration issue |
sender_blocked | The sender has been blocked or suspended |
destination_blocked | The destination number is blocked from receiving messages |
opted_out | The recipient has opted out from receiving messages from this sender |
spam_filtered | The message was filtered as spam by the carrier |
invalid_content | The message content is invalid or exceeds allowed limits |
media_error | The media attachment could not be delivered |
routing_error | The message could not be routed to the destination |
geographic_restriction | The message was blocked due to geographic restrictions |
service_restricted | The requested service type is not supported for this destination |
destination_unavailable | The destination is temporarily unavailable |
destination_rejected | The destination rejected the message |
too_many_recipients | The message exceeds the maximum number of recipients |
message_expired | The message expired before it could be delivered |
volume_throttled | The message was rejected due to volume or rate limits |
toll_free_not_verified | The toll-free number has not been verified for messaging |
account_error | The message was rejected due to an account-level issue |
Handling errors
- 4xx errors indicate a problem with your request. Check the
codeandmessagefields, fix the issue, and retry. - 429 errors mean you've hit a rate limit. Wait for the duration indicated by the
Retry-Afterheader before retrying. - 5xx errors indicate a server-side issue. Retry with exponential backoff. Use idempotency keys to prevent duplicates on retries.