Errors

Every error returns a consistent JSON envelope and a matching HTTP status. Stack traces are never leaked.

Error envelope
{
  "error": "invalid_request",
  "message": "amount must be a positive decimal string",
  "request_id": "req_7s1jH9nRqYRvLW1U4K6x"
}

Always log request_id — quote it in support requests to trace the exact call.

Error codes

HTTPerrorMeaning
400invalid_requestMalformed or invalid parameters.
401unauthorizedMissing, invalid, or revoked API key.
402quota_exceededPlan quota reached — upgrade or wait for the next period.
403forbiddenAuthenticated but not allowed (role/ABAC).
404payment_not_foundThe resource doesn’t exist or isn’t in your scope.
409idempotency_conflictAn Idempotency-Key was reused with a different payload.
429rate_limit_exceededToo many requests — back off and retry.
5xxinternal_errorSomething went wrong on our side. Safe to retry idempotently.
502provider_errorThe upstream Bakong provider returned an error.

Handling errors well

  • Retry 429 and 5xx with exponential backoff; always send an Idempotency-Key on creates so retries are safe.
  • Treat 4xx (except 429) as terminal — fix the request, don’t retry.
  • Surface message to your developers, not end users; show a generic message to customers.