Appearance
Errors
Every error has the same shape. Branch on error.code; it never changes.
json
{
"success": false,
"message": "Your balance is too low for this.",
"error": {
"code": "INSUFFICIENT_BALANCE",
"hint": "Top up your balance, then make a new quote.",
"docs_url": "https://docs.partners.xash.co.zw/errors#insufficient_balance"
}
}The API never answers 502 or 504. When a provider's answer is unknown, you get 202 with status pending, not an error.
| Code | HTTP | Meaning | What to do |
|---|---|---|---|
KEY_INVALID | 401 | The API key is missing, wrong, expired or revoked. | Send Authorization: Bearer xash_test_... or xash_live_... Create a new key in Developers → API keys if needed. |
KEY_ENVIRONMENT_MISMATCH | 401 | This key belongs to the other environment for this request. | Use a xash_test_ key for sandbox and a xash_live_ key for live. |
ABILITY_MISSING | 403 | This key is not allowed to do that. | Create a key that has the ability named in error.ability. |
IP_NOT_ALLOWED | 403 | Requests from this IP address are not allowed for this partner. | Add your server IP in Settings → Security, or call from an allowed IP. |
LIVE_NOT_ENABLED | 403 | Live sales are not enabled for this partner yet. | Finish go-live in the portal: turn on 2FA, accept the terms and make a first top-up. |
PARTNER_PAUSED | 403 | This partner is paused. | Check error.reason. If your balance is below zero, top up. Otherwise contact support. |
NOT_FOUND | 404 | Nothing exists at this address. | Check the path against https://docs.partners.xash.co.zw/openapi.json. |
METHOD_NOT_ALLOWED | 405 | This address does not accept that HTTP method. | Check the HTTP method against the API reference. |
VALIDATION_FAILED | 422 | Some fields are missing or invalid. | Fix the fields listed in errors and send the request again. |
RECIPIENT_INVALID | 422 | The provider rejected this phone number, meter or account. | Ask your customer to check the number, meter or account, then make a new quote. |
INSUFFICIENT_BALANCE | 402 | Your balance is too low for this. | Top up your balance, then make a new quote. |
LIMIT_EXCEEDED | 409 | This would go over one of your limits. | error.limit says which limit. Wait for it to reset, or ask support to raise it. |
QUOTE_EXPIRED | 409 | This quote has expired. | Make a new quote. Quotes last 5 minutes. |
QUOTE_USED | 409 | This quote has already been used. | Look up the existing transaction by your reference instead of buying again. |
IDEMPOTENCY_CONFLICT | 409 | This reference or Idempotency-Key was already used with different details. | Use a new reference for a new sale. To retry the same sale, send exactly the same body and key. |
IDEMPOTENCY_IN_PROGRESS | 409 | A request with this Idempotency-Key is still being processed. | Wait a second and send the same request again. |
PRODUCT_UNAVAILABLE | 409 | This product is paused right now. | Try again later, or offer your customer another product. |
COLLECTION_METHOD_UNAVAILABLE | 409 | This payment method is paused right now. | Try again later, or ask your customer to pay another way. |
OTP_INVALID | 422 | The OTP is wrong or has expired. | Ask your customer for the latest OTP and confirm again. |
RATE_LIMITED | 429 | Too many requests. | Wait for the Retry-After seconds, then retry. |
VELOCITY_LIMITED | 429 | Too many sales in a short time. | Wait for the Retry-After seconds, then retry. |
UPSTREAM_UNAVAILABLE | 503 | The provider could not be reached. Nothing was sent. | It is safe to send the same request again after Retry-After seconds. |
INTERNAL_ERROR | 500 | Something went wrong on our side. | Retry with the same Idempotency-Key. If it keeps failing, contact support with the X-Request-Id. |