Skip to main content

Errors, Rate Limits, And Idempotency

Use structured errors and idempotency keys to make your integration safe under retries, network failures, and duplicate requests.

Error shape

PayChain errors use a structured response:
{
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "Invalid request data",
    "details": [],
    "requestId": "req_..."
  }
}
Always log the requestId without logging secrets.

Common error categories

CategoryTypical HTTP statusRetry?
Validation error400No. Fix the request.
Authentication error401No. Check API key and environment.
Permission error403No. Check key type and policy.
Not found404No, unless the resource may be created later.
Conflict / idempotency conflict409Usually no. Inspect the existing request or resource.
Rate limited429Yes, after backoff.
Server or network error5xxYes, with backoff and idempotency.

Error code catalog

Use the machine-readable code field for integration logic and the message for operator-facing context. Codes can expand over time, so integrations should handle unknown codes gracefully.
CodeMeaningTypical action
VALIDATION_ERRORRequest body, query parameter, or field value is invalid.Fix the request before retrying.
UNAUTHORIZEDAPI key or session is missing or invalid.Check environment and key storage.
FORBIDDENThe key or user does not have permission for the action.Check key type, payout policy, or dashboard permission.
NOT_FOUNDResource does not exist or does not belong to the business.Check IDs and environment.
CONFLICTRequest conflicts with current resource state.Fetch the resource and resolve state before retrying.
DUPLICATE_REQUESTA duplicate create request was detected.Reuse idempotency keys and inspect the existing resource.
IDEMPOTENCY_REQUEST_IN_PROGRESSAnother request with the same key is still processing.Wait, then fetch the resource or retry safely.
IDEMPOTENCY_KEY_MISMATCHSame idempotency key was reused with a different payload.Use stable keys per unique business action.
RATE_LIMIT_EXCEEDEDToo many requests in a window.Back off and reduce polling.
INSUFFICIENT_BALANCEAvailable business balance is not enough for the action.Reconcile balance or reduce the amount.
WITHDRAWAL_AMOUNT_EXCEEDS_AVAILABLE_BALANCERequested withdrawal exceeds current withdrawable capacity after policy checks.Use a smaller amount, wait for pending_funds to clear where applicable, or resolve recovery-required funds.
SPONSORED_GAS_CREDIT_INSUFFICIENTSponsored outbound operation needs more gas credit.Top up gas credits or wait for the next included allowance.
WEBHOOK_EVENT_IN_FLIGHTWebhook delivery is already being processed.Wait for terminal delivery state.
WEBHOOK_EVENT_ALREADY_SCHEDULEDRetry or replay is already scheduled.Do not schedule another duplicate attempt.
WEBHOOK_EVENT_ALREADY_DELIVEREDWebhook already reached a delivered state.Treat as successful or replay only when supported.
WEBHOOK_EVENT_NOT_FOUNDWebhook event ID was not found.Check environment and event ID.
WEBHOOK_RETRY_COOLDOWNRetry is temporarily blocked by cooldown.Retry later.
WEBHOOK_REPLAY_NOT_SUPPORTEDThe event cannot be replayed.Use normal retry or fetch the resource directly.
WEBHOOK_REPLAY_REQUIRES_TERMINAL_STATEEvent must reach terminal state before replay.Wait for delivery to finish.
WEBHOOK_REPLAY_COOLDOWNReplay is temporarily blocked by cooldown.Retry later.
BILLING_INVOICE_NOT_FOUNDBilling invoice was not found.Check invoice ID and environment.
BILLING_UNDERPAYMENTBilling payment was lower than required.Pay the required invoice amount.
BILLING_INVOICE_NOT_PAYABLEBilling invoice is cancelled, expired, or not payable.Start a new billing or upgrade flow.
BILLING_PAYMENT_REPLAY_CONFLICTBilling payment conflicts with a prior payment record.Contact support with request ID.
REDIS_COORDINATION_UNAVAILABLETemporary coordination dependency is unavailable.Retry later with idempotency.
SERVICE_UNAVAILABLEPayChain dependency or service is temporarily unavailable.Retry later with backoff.
INTERNAL_SERVER_ERRORUnexpected PayChain error.Retry if safe, then contact support with request ID.
Support note: When contacting support, include the request ID, resource ID, environment, and timestamp. Do not send API keys, webhook secrets, or raw credential headers.

Idempotency keys

Send Idempotency-Key on mutating requests:
Idempotency-Key: order_123_invoice
Use stable keys based on your own business object:
  • order_123_invoice
  • payout_456
  • customer_789_invoice_001
Recommended formats:
ActionExample key
Create invoice for an orderorder_123_invoice
Create invoice with payout routeorder_123_route_invoice
Create dynamic-recipient invoiceorder_123_dynamic_payout_invoice
Quote withdrawalpayout_456_quote
Create withdrawalpayout_456_create
Execute approved contract actionorder_123_contract_action
Retry note: Do not automatically retry non-idempotent POST requests unless you sent an idempotency key.

Rate limits

Rate limits protect PayChain and merchants from accidental request bursts. Recommended behavior:
  • Back off on 429.
  • Respect retry headers if present.
  • Avoid tight polling loops.
  • Prefer webhooks for lifecycle changes.
  • Use list pagination for reconciliation jobs.

Safe retry policy

Retry:
  • Network timeouts.
  • 408.
  • 429.
  • 5xx.
Do not blindly retry:
  • Invalid request data.
  • Wrong API key type.
  • Rejected payout policy.
  • Insufficient balance.
  • Recovery-required balance that is not withdrawable.
  • Expired or cancelled invoices.
  • Webhook events already delivered.
If a valid withdrawal returns or emits pending_funds, do not create a replacement withdrawal. Keep the same idempotency key and wait for the existing withdrawal to continue after sweepable funds become available.

Operational logging

Log:
  • requestId.
  • PayChain resource ID.
  • Your order/customer reference.
  • HTTP status.
  • Error code.
Do not log:
  • API keys.
  • Webhook secrets.
  • Request headers containing credentials.
  • Raw payout destination secrets.
  • Full raw webhook payloads in shared logs.