Fundamentals

Errors and limits

Error format, HTTP codes, rate limits and API versioning.

Format

Every error has the same shape:

JSON
{  "error": {    "type": "invalid_request_error",    "code": "amount_invalid",    "message": "`amount` must have at most 2 decimals",    "param": "amount",    "requestId": "req_5f1a2b3c4d5e6f708192a3b4"  }}
  • Code against type and code. message is for humans and may change.
  • param points to the field that failed, when it applies.
  • Keep the requestId. It also comes in the X-Request-Id header. Include it when you contact support.

Codes

HTTPtypecode
400invalid_request_errorinvalid_json, body_required, amount_required, amount_invalid, currency_not_supported, description_too_long, reference_too_long, allowed_methods_invalid, metadata_invalid, metadata_too_large, expires_at_invalid, idempotency_key_too_long, cursor_invalid, limit_invalid, status_invalid, charge_invalid
401authentication_errormissing_api_key, invalid_api_key, api_key_expired, publishable_key_not_allowed, sandbox_not_supported
403permission_errorinsufficient_scope, merchant_not_active
404invalid_request_errorcharge_not_found, order_not_found, balance_not_found, statement_not_found, unknown_route
405invalid_request_errormethod_not_allowed
409invalid_request_errorreference_exists, idempotency_key_reused, idempotency_in_flight
413invalid_request_errorpayload_too_large
429rate_limit_errorrate_limited
500api_errorinternal_error

Note

Another merchant's resource returns 404, just like one that doesn't exist. A malformed id also returns 404.

What to retry

ResponseWhat to do
4xx (except 429)Don't retry as is. Fix the request.
429Wait the Retry-After seconds and retry.
500 or network errorRetry with the same Idempotency-Key.

Limits

  • 300 reads and 60 writes per minute, per key.
  • Above that, you get 429 rate_limited with Retry-After.
  • Ten failed authentication attempts per minute with the same key also return 429.

Versioning and scope

  • Every response has the TuCapi-Api-Version: 2026-09-15 header.
  • Objects only gain fields. They're never renamed or removed. A breaking change would be a /v2.
  • USD only.
  • There's no cancellation or refund through the API. Those are handled in the dashboard.