Every vendor you connect to returns its own error codes. If those raw codes reached your clients, each client would have to handle a different set of codes for every route you use, and switching a vendor would break their integration. Global Error Codes fix this. You define one catalog of codes, map each vendor’s codes to it, and your clients only ever see your catalog in their delivery reports.
Where to find it
Sidebar → Settings → Error Codes → Global
What each field controls
| Field | What it does | How aggregators use it |
|---|---|---|
| Product | SMS, WhatsApp, etc. | Keep separate catalogs per channel |
| Identifier | Unique name for the code | Use readable names like ABSENT_SUBSCRIBER |
| Source | OPERATOR or INTERNAL | INTERNAL fails the message on your platform without sending it to any vendor |
| Status | SUBMITTED, DELIVERED, FAILED, NOTSENT | The final status your client sees |
| Cause | Description text | Shown to clients, so write it for them |
| Charge to User | Yes/No | Whether your client pays for this outcome |
| Charge by Operator | Yes/No | Whether your vendor bills you for it |
Steps
- Open Manage Global Error Codes and click + (Add).
- Select the Product.
- Enter an Identifier and a client-friendly Cause.
- Set Source. If you pick INTERNAL, set Status to NOTSENT.
- Set Charge to User and Charge by Operator.
- Click Save Changes.
To add a similar code quickly, use the Clone action on an existing row. You can also export the whole catalog from the list screen.
Using the two charge flags for margin control
The two charge flags are commercial decisions, and they don’t have to match:
- Operator charges you, you charge the client (e.g. absent subscriber on a route that bills on submit): your margin is protected.
- Operator charges you, you don’t charge the client: you absorb the cost. Use this for failures caused by your own routing.
- Operator doesn’t charge you, you charge the client: check your client contracts before you set this up.
- INTERNAL rejections (blocked number, invalid series, missing template): usually Charge to User = No and Charge by Operator = No, because nothing left your platform.
Reconciliation reports only line up with vendor invoices if the Charge by Operator flag matches how each vendor actually bills.
Best practices
- Freeze code numbers once clients integrate. Clients write their retry and alert logic against your codes. Add new codes instead of renumbering old ones.
- Keep separate codes for failures that need different client action. “Invalid number” (don’t retry) and “network timeout” (retry) should never share a code.
- Clients can pull your catalog through the API. See Do you provide standard delivery error codes?
- Any vendor code without a mapping reaches clients as the default code or
UNDEFINED. Map every new vendor before sending live traffic.
Related articles
- How to Map Vendor Error Codes to Global Error Codes
- Do the Failed Messages Get Retried in SMPP Client?
- How to Read SMPP Delivery Receipt
