Error Handling

Error responses, status codes, and error codes used by the Snippe API

Response Format

Success Response

{
  "status": "success",
  "code": 200,
  "data": {
    // Response data
  }
}

Error Response

{
  "status": "error",
  "code": 400,
  "error_code": "VAL_001",
  "message": "validation failed: email is required"
}

HTTP Status Codes

CodeNameDescription
200OKRequest successful
201CreatedResource created successfully
400Bad RequestInvalid request (validation errors, malformed JSON)
401UnauthorizedAuthentication required or failed
403ForbiddenAuthenticated but not authorized
404Not FoundResource doesn't exist
409ConflictResource already exists or state conflict
422Unprocessable EntityIdempotency key mismatch
429Too Many RequestsRate limit exceeded
500Internal Server ErrorServer-side error
503Service UnavailableExternal service temporarily down

Error Codes

Error codes follow the pattern PREFIX_NNN where the prefix indicates the category.

Authentication Errors (AUTH_xxx)

CodeDescriptionCommon Cause
AUTH_001UnauthorizedNo authentication provided
AUTH_002Invalid tokenMalformed or corrupted JWT
AUTH_003Token expiredJWT past expiration time
AUTH_004Invalid credentialsWrong email/password
AUTH_005Missing auth headerAuthorization header not sent
AUTH_006Invalid auth headerMalformed authorization header
AUTH_007Invalid API keyAPI key format or validation failed
AUTH_008API key expiredAPI key past expiration date
AUTH_009Invalid refresh tokenRefresh token invalid or expired

Authorization Errors (AUTHZ_xxx)

CodeDescriptionCommon Cause
AUTHZ_001ForbiddenAccess denied to resource
AUTHZ_002Insufficient scopeAPI key lacks required scope
AUTHZ_003Insufficient roleUser role insufficient for operation

Validation Errors (VAL_xxx)

CodeDescriptionCommon Cause
VAL_001Validation failedOne or more fields invalid
VAL_002Invalid requestRequest body parsing failed
VAL_003Missing fieldRequired field not provided
VAL_004Invalid formatField format doesn't match expected
VAL_005Invalid amountAmount outside allowed range
VAL_006Invalid currencyCurrency code not supported
VAL_007Invalid OTPWrong OTP code entered
VAL_008OTP expiredOTP expired or too many attempts

Resource Errors (RES_xxx)

CodeHTTPDescription
RES_001404Resource not found
RES_002409Resource already exists
RES_003409State conflict

Payment Errors (PAY_xxx)

CodeDescriptionCommon Cause
PAY_001Payment failedPSP processing error
PAY_002Payment expiredPayment window closed
PAY_003Payment cancelledUser or system cancelled
PAY_004Insufficient fundsUser balance too low
PAY_005Transfer failedFund transfer failed

Internal Errors (INT_xxx)

CodeDescription
INT_001Internal error
INT_002Database error
INT_003External service error
INT_004Service unavailable

Rate Limiting (RATE_xxx)

CodeDescription
RATE_001Rate limit exceeded

Common Error Scenarios

Invalid Request Body

{
  "status": "error",
  "code": 400,
  "error_code": "VAL_002",
  "message": "invalid request body"
}

Fix: Ensure you're sending valid JSON with correct Content-Type header.

Missing Required Fields

{
  "status": "error",
  "code": 400,
  "error_code": "VAL_001",
  "message": "validation failed: amount is required, phone_number is required"
}

Invalid Phone Number Format

{
  "status": "error",
  "code": 400,
  "error_code": "VAL_004",
  "message": "validation failed: phone_number must be a valid phone number"
}

Fix: Use format +255XXXXXXXXX or 255XXXXXXXXX.

Amount Out of Range

{
  "status": "error",
  "code": 400,
  "error_code": "VAL_005",
  "message": "amount 100 is below minimum of 500"
}

Missing Scope

{
  "status": "error",
  "code": 403,
  "error_code": "AUTHZ_002",
  "message": "API key does not have required scope: disbursement:create"
}

Fix: Create a new API key with the required scope.

Idempotency Conflict

{
  "status": "error",
  "code": 422,
  "error_code": "VAL_001",
  "message": "idempotency key already used with different request body"
}

Fix: Use a unique idempotency key for each unique request.


Validation Rules

Amounts

FieldRule
Minimum500 TZS (payments), 5,000 TZS (payouts)
MaximumVaries by account type
FormatInteger (smallest currency unit)

Phone Numbers

FormatExample
With country code+255712345678
Without plus255712345678

Currency

SupportedCode
Tanzanian ShillingTZS

URLs

  • Must be valid HTTPS URLs
  • Maximum 500 characters
  • Used for: webhook_url, redirect_url, cancel_url

On this page