HTTP status codes, error response format, and common error codes for the Danipa Payment API.
Error Response Format
All API errors return a consistent JSON structure:
{
"error": {
"code": "INVALID_AMOUNT",
"message": "Amount must be greater than zero",
"details": {
"field": "source.amount",
"constraint": "minimum",
"value": 0
}
},
"request_id": "req_abc123",
"timestamp": "2026-03-11T14:22:00Z"
}
HTTP Status Codes
Code
Meaning
When
200
OK
Successful GET request
201
Created
Resource successfully created
202
Accepted
Async operation accepted (e.g., remittance)
400
Bad Request
Invalid parameters or malformed JSON
401
Unauthorized
Missing or invalid API key
403
Forbidden
Valid API key but insufficient permissions
404
Not Found
Resource does not exist
409
Conflict
Duplicate X-Request-Id (idempotency)
422
Unprocessable
Valid JSON but business rule violation
429
Too Many Requests
Rate limit exceeded
500
Server Error
Unexpected server error
503
Service Unavailable
Maintenance or provider outage
Common Error Codes
Validation Errors (400)
Code
Description
INVALID_AMOUNT
Amount is zero, negative, or exceeds limits
INVALID_CURRENCY
Unsupported currency code
INVALID_MSISDN
Phone number is not valid E.164 format
INVALID_PROVIDER
Unsupported payout provider
MISSING_FIELD
Required field not provided
Business Errors (422)
Code
Description
INSUFFICIENT_BALANCE
Wallet balance too low for this transaction
DAILY_LIMIT_EXCEEDED
Transaction would exceed daily sending limit
RECIPIENT_NOT_FOUND
MoMo account not registered for this number
CORRIDOR_UNAVAILABLE
Currency pair not currently supported
KYC_REQUIRED
Higher KYC tier needed for this amount
Provider Errors (502/503)
Code
Description
PROVIDER_TIMEOUT
MoMo or bank API did not respond in time
PROVIDER_UNAVAILABLE
Payout provider is temporarily down
PROVIDER_REJECTED
Provider rejected the transaction
Retry Strategy
Error Type
Retry?
Strategy
400 (validation)
No
Fix the request and resubmit
401/403 (auth)
No
Check API key and permissions
404 (not found)
No
Verify the resource ID
409 (conflict)
No
Use a different X-Request-Id
429 (rate limit)
Yes
Wait for Retry-After header
500 (server)
Yes
Retry with exponential backoff
502/503 (provider)
Yes
Retry after 30-60 seconds
Idempotency
All POST requests require an X-Request-Id header. If you send the same X-Request-Id twice, the second request returns the original response without creating a duplicate transaction.
# First request — creates the transaction
curl -X POST .../remittance -H "X-Request-Id: req-001" ...
# => 202 Accepted, txn_abc123
# Retry with same ID — returns the same transaction
curl -X POST .../remittance -H "X-Request-Id: req-001" ...
# => 200 OK, txn_abc123 (no duplicate created)