Error Codes
Every error code the platform returns, and the fix for each.
| HTTP | code | Meaning & fix |
|---|---|---|
| 401 | MISSING_KEY | Authorization header absent or malformed |
| 401 | EXPIRED_TIMESTAMP | Clock more than 5 minutes off — sync your server to NTP |
| 401 | INVALID_SIGNATURE | Check the full path and that you signed the exact bytes sent |
| 403 | INVALID_KEY | Key not found or revoked |
| 403 | IP_BLOCKED | Calling IP is not on the key's whitelist |
| 403 | FORBIDDEN | Key lacks the required permission for this product |
| 403 | SANDBOX_KEY | A sandbox key cannot move money — use a production key |
| 400 | MISSING_PARAM | A required field is absent — the message names it |
| 400 | INSUFFICIENT_BALANCE | Wallet too low for this amount |
| 400 | INVALID_TPIN | Wrong TPIN — locks after 5 consecutive failures |
| 400 | INVALID_NUMBER | Recharge: not a valid mobile number or DTH subscriber ID |
| 400 | INVALID_AMOUNT | Amount outside the product’s range, or not whole rupees for a recharge |
| 404 | OPERATOR_NOT_FOUND | Recharge: unknown or inactive operator_id — read GET /ext/v1/recharge/operators |
| 409 | BILLER_PARAMS_CHANGED | BBPS biller changed its fields; re-read /biller/{id} |
| 410 | INVALID_BILL_TOKEN | bill_token expired (15 min) or already spent — fetch again |
| 422 | BANK_NOT_SUPPORTED | Free DMT is not enabled for that bank — read GET /ext/v1/dmt/banks |
| 422 | AGT_UNSUPPORTED | Biller not enabled for the agent channel |
| 422 | BILL_FETCH_FAILED | Mandatory-fetch biller returned no bill |
| 422 | OPERATOR_UNAVAILABLE | Recharge: the operator cannot be recharged right now — nothing was debited; retry later |
| 400 | INVALID_PID | AEPS: the biometric capture is missing, malformed or reports an RD error — capture again and send the PidData XML unchanged |
| 400 | OTP_REQUIRED | AEPS: CW / AP above ₹5,000 needs otp_reference from POST /ext/v1/aeps/otp |
| 400 | AUTH_MODE_NOT_ALLOWED | AEPS: face is accepted for daily authentication only |
| 404 | MERCHANT_NOT_FOUND | AEPS: no outlet with that merchant_ref — onboard it first |
| 409 | DAILY_AUTH_REQUIRED | AEPS: the outlet has not done today’s daily authentication (AEPS or AP) |
| 409 | EKYC_REQUIRED / BANK_EKYC_REQUIRED | AEPS: finish the outlet’s eKYC / Bank eKYC first |
| 409 | REONBOARD_REQUIRED | AEPS: the outlet’s bank account could not be verified — re-submit POST /merchants with the same merchant_ref |
| 422 | ONBOARDING_FAILED / EKYC_FAILED / DAILY_AUTH_FAILED | AEPS: the step was not accepted; message says why |
| 429 | TRANSACTION_IN_PROGRESS | AEPS: one transaction per outlet at a time — retry when it completes |
| 422 | QR_NOT_CREATED | UPI Cash: the bank network refused the QR — failure_code says why (e.g. OUTLET_NOT_ENABLED) |
| 409 | SERVICE_CLOSED | UPI Cash: closed daily from 11:30 PM to 5:00 AM IST |
| 429 | TOO_MANY_OPEN_QRS | UPI Cash: the outlet already has 3 unpaid QRs — wait for them to settle |
| 429 | RATE_LIMITED | Per-minute quota exceeded for this key |
| 429 | BILLER_BUSY | Biller concurrency limit — retry after a few seconds |
| 429 | PAYMENT_IN_PROGRESS | BBPS: this bill is already being paid — read the status by client_reference before retrying |
| 503 | SERVICE_DISABLED | Category or service temporarily disabled by the operator |
Retrying a timeout
A request that times out may still have succeeded. Retry it with the same client_reference — every money endpoint (Free DMT /transfer, BBPS /bill/pay, Recharge /recharge, every AEPS transaction, UPI Cash /qr and each verification) returns the original transaction with duplicate: true rather than charging twice. Sending a new reference for the same intent is what double-charges, so keep one reference per business action and reuse it for every attempt.