Errors

Ching uses standard HTTP status codes and wraps every response in a success envelope. Non-2xx responses always include a machine-readable error code you can branch on.

Response Envelope

Every response has the same shape:

{
  "success": true,
  "data": {
    "id": "cus_..."
  }
}
{
  "success": false,
  "error": {
    "status": 400,
    "code": "INVALID_FIELD",
    "message": "Field validation failed",
    "issues": [
      {
        "path": [
          "amount"
        ],
        "message": "Amount must be positive"
      }
    ]
  }
}

HTTP Status Codes

CodeMeaningWhen
200OKRequest succeeded
400Bad RequestValidation failed or a business rule was broken
401UnauthorizedMissing, malformed, or invalid API key
402Payment RequiredCard charge was declined
403ForbiddenLive key not yet activated, or 2FA required on a JWT session
404Not FoundResource does not exist in the current project + mode
409ConflictDuplicate email, duplicate tax ID, etc.
422UnprocessableValid JSON but a semantic rule failed (e.g. no access to the requested project)
500Server ErrorUnexpected server error - safe to retry after a delay

Common Error Codes

CodeWhat happened
INVALID_FIELDA request body field failed Zod validation. Check error.issues for the specific field.
NO_ACCESSThe Authorization header is missing or the key is invalid.
LIVE_KEY_INACTIVEYou used a live key before the project has an active payment provider.
NOT_FOUNDResource doesn't exist in this project and mode.
CHARGE_FAILEDThe card was declined by the payment provider.
SESSION_NOT_PENDINGA checkout or setup session was already completed, canceled, or expired.
SESSION_EXPIREDThe session is past its expiry window.
PROJECT_NOT_FOUNDJWT session references a project the user has no role on.
EMAIL_EXISTSA customer with that email already exists in this project.

Retries

Ching does not yet honor an Idempotency-Key header, so retrying a POST may create duplicate resources. For charges and subscriptions, wait for the response before retrying. For reads, retry with exponential backoff (1s, 2s, 4s...) on 5xx responses.