Error codes

All API errors use a consistent envelope inspired by Stripe. Check type, code, and param for programmatic handling.

Response envelope

Success

json
{
  "success": true,
  "data": { }
}

Error

json
{
  "success": false,
  "error": {
    "type": "validation_error",
    "message": "Human readable",
    "code": "invalid_amount",
    "param": "amount_minor",
    "details": []
  }
}

HTTP status codes

200 OK · 201 Created · 204 No Content · 400 Bad Request · 401 Unauthorized · 403 Forbidden · 404 Not Found · 409 Conflict · 422 Unprocessable · 429 Rate Limited · 500 Server Error

Error reference

CodeHTTPTypeMeaning
unauthorized401authentication_errorMissing or invalid API key / session
forbidden403authorization_errorValid auth but insufficient permission
merchant_not_verified403authorization_errorComplete verification before payment writes
project_not_found403authorization_errorProject id invalid or not owned
project_mismatch403authorization_errorURL project ≠ API key project
project_environment_mismatch400validation_errortp_test_ key on LIVE project (or vice versa)
project_required400validation_errorMissing project context
resource_not_found404not_found_errorOrder, webhook, or resource missing
resource_conflict409conflict_errorState conflict (e.g. order already paid)
invalid_json400validation_errorRequest body is not valid JSON
invalid_request400validation_errorSchema validation failed
invalid_amount400validation_erroramountMinor not a positive integer
unprocessable422validation_errorDomain rule violation
idempotency_key_in_use409conflict_errorSame key, different request body in flight
rate_limit_exceeded429rate_limit_errorToo many requests
test_mode_required403authorization_errorAction only in TEST (e.g. simulate payment)
internal_error500api_errorUnexpected server error

Idempotency

When a cached idempotent response is replayed, the response includes Idempotent-Replayed: true. Rate limit responses include X-RateLimit-Remaining and X-RateLimit-Reset.