Error Handling
The Conto SDK provides detailed error information to help you handle failures gracefully.ContoError Class
SDK failures use the exportedContoError or ContoAdminError classes. They include stable error
metadata alongside the standard Error fields:
error instanceof ContoError for agent-scoped calls and error instanceof ContoAdminError for
organization-scoped calls. The structured fields are preserved from the API response when present.
Error Codes
Authentication Errors
Payment Errors
Validation Errors
System Errors
Handling Errors
Basic Error Handling
Handling Specific Error Codes
Enriched Denial And Error Responses
Some SDK responses include additional context to help agents recover programmatically. Policy denials fromPOST /api/sdk/payments/request are normal 200 responses with status: "DENIED", plus
hint, context, and nextSteps fields. Execution failures are non-2xx error responses with an
error and code.
Denial Response Structure
Example: Manual Execution Required
When trying to/execute a payment assigned to an external wallet:
Example: Policy Denial With Recovery Context
Handling Enriched Errors
Using Request and Execute for Better Control
Thepay() method throws on denial. For more control, use separate request/execute:
Handling Rate Limits
The SDK handles rate limits during its built-in retry budget for safe requests (see Retry Strategy below). If those retries are exhausted, the thrownContoError exposes retryAfter in seconds when the server supplied that guidance.
Use that value to schedule a later retry only for a read or another operation that is safe to repeat:
payments.pay() or payments.execute() in a generic retry loop. If execution has an ambiguous failure, reconcile the known requestId with payments.status(requestId) before deciding whether another execution attempt is safe. Prefer separate request() and execute() calls, with a stable idempotencyKey, whenever the workflow needs deterministic recovery.
Handling Timeouts
For long-running requests, handle timeouts:Retry Strategy
Built-in Automatic Retry
The SDK automatically retries transient failures only when repeating the request cannot create an additional side effect. Built-in behavior:- Retries read-only requests up to 3 times on network failures,
429, and5xx - Retries payment authorization requests with the same stable
idempotencyKey - Treats x402 and MPP pre-authorization as retryable, non-mutating policy checks
- Respects
Retry-Afterheaders from the server - Exponential backoff: 1s → 2s → 4s (capped at 10s)
- Never automatically retries payment execution, protocol record calls, or
ContoAdminmutations - Does not retry client errors (
4xxexcept retryable429responses) or auth failures
request and execute
methods over the pay convenience method so the application retains the requestId.
Custom Retry for Application Logic
For application-level retry logic (e.g., re-requesting after a denial), use a custom wrapper:Logging Errors
Best Practices
Always Catch Errors
Always Catch Errors
Never let payment errors crash your application:
Check Specific Error Codes
Check Specific Error Codes
Don’t just catch generic errors:
Don't Retry Payment Execution
Don't Retry Payment Execution
Be careful with retries on payment execution:
Log for Debugging
Log for Debugging
Always log error details for debugging:
Next Steps
Examples
See complete integration examples
API Reference
View the REST API (Swagger UI)