Error Handling
Error responses, status codes, and error codes used by the Snippe API
All API errors follow a consistent format to help you handle them gracefully.
Response Format
{
"status": "success",
"code": 200,
"data": {
// Response data
}
}{
"status": "error",
"code": 400,
"error_code": "validation_error",
"message": "amount is required"
}HTTP Status Codes
| Code | Name | Description |
|---|---|---|
| 200 | OK | Request successful |
| 201 | Created | Resource created successfully |
| 400 | Bad Request | Invalid request (validation errors, malformed JSON) |
| 401 | Unauthorized | Authentication required or failed |
| 403 | Forbidden | Authenticated but not authorized |
| 404 | Not Found | Resource doesn't exist |
| 409 | Conflict | Resource already exists or state conflict |
| 422 | Unprocessable Entity | Idempotency key mismatch |
| 429 | Too Many Requests | Rate limit exceeded |
| 500 | Internal Server Error | Server-side error |
| 503 | Service Unavailable | External service temporarily down |
Common Error Scenarios
Invalid API Key (401)
{
"status": "error",
"code": 401,
"error_code": "unauthorized",
"message": "invalid or missing API key"
}Fix: Check that your API key is correct and included in the
Authorization header.
Insufficient Scope (403)
{
"status": "error",
"code": 403,
"error_code": "insufficient_scope",
"message": "API key does not have required scope: disbursement:create"
}Fix: Create a new API key with the required scope from the Dashboard.
Missing Required Fields (400)
{
"status": "error",
"code": 400,
"error_code": "validation_error",
"message": "amount is required"
}Invalid Phone Number (400)
{
"status": "error",
"code": 400,
"error_code": "validation_error",
"message": "phone_number must be a valid phone number"
}Fix: Use format 255XXXXXXXXX or +255XXXXXXXXX for Tanzanian numbers.
Amount Out of Range (400)
{
"status": "error",
"code": 400,
"error_code": "validation_error",
"message": "amount 100 is below minimum of 500"
}Payment Not Found (404)
{
"status": "error",
"code": 404,
"error_code": "not_found",
"message": "payment not found"
}Insufficient Balance (500)
{
"status": "error",
"code": 500,
"error_code": "payment_failed",
"message": "insufficient balance: available 5000, required 6500"
}Fix: Top up your account balance before creating payouts.
Idempotency Conflict (422)
{
"status": "error",
"code": 422,
"error_code": "validation_error",
"message": "idempotency key already used with different request body"
}Fix: Use a unique idempotency key for each unique request.
Rate Limit Exceeded (429)
{
"status": "error",
"code": 429,
"error_code": "rate_limit_exceeded",
"message": "Too many requests"
}Fix: Implement exponential backoff and respect the X-Ratelimit-Reset header.
Error Codes Reference
Authentication Errors
| Code | Description |
|---|---|
unauthorized | Invalid or missing API key |
insufficient_scope | API key lacks required scope |
Validation Errors
| Code | Description |
|---|---|
validation_error | One or more fields invalid |
Resource Errors
| Code | Description |
|---|---|
not_found | Resource doesn't exist |
conflict | Resource state conflict |
Payment Errors
| Code | Description |
|---|---|
payment_failed | Payment processing error |
Validation Rules
| Rule | Value |
|---|---|
| Minimum | 500 TZS (payments), 5,000 TZS (payouts) |
| Maximum | Varies by account type |
| Format | Integer (smallest currency unit) |
| Format | Example |
|---|---|
| With country code | +255712345678 |
| Without plus | 255712345678 |
Phone numbers must be valid Tanzanian mobile numbers.
- Must be valid HTTPS URLs
- Maximum 500 characters
- Used for:
webhook_url,redirect_url,cancel_url
Best Practices
Log All Errors Log the full error response including error_code and
message for debugging.
Implement Retries For 5xx errors and network failures, implement
exponential backoff.