Skip to main content

Error Handling

The Conto SDK provides detailed error information to help you handle failures gracefully.

ContoError Contract

SDK failures use the exported ContoError or ContoAdminError TypeScript interfaces. Version 0.1.0 returns ordinary Error objects with these stable fields attached:
Do not use a runtime instanceof check for this type: it is a type-only interface in the published 0.1.0 package. Use an Error check plus the presence of code to narrow unknown caught values.

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 from POST /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

The pay() method throws on denial. For more control, use separate request/execute:

Handling Rate Limits

The SDK handles transient failures during its built-in retry budget for safe requests (see Retry Strategy below). If those retries are exhausted, inspect the thrown error’s code and status fields. Use that value to schedule a later retry only for a read or another operation that is safe to repeat:
Do not wrap 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, and 5xx
  • Retries payment authorization requests with the same stable idempotencyKey
  • Respects Retry-After headers from the server
  • Exponential backoff: 1s → 2s → 4s (capped at 10s)
  • Never automatically retries payment execution, protocol record calls, or ContoAdmin mutations
  • Does not retry client errors (4xx except retryable 429 responses) or auth failures
For workflows that require deterministic recovery, prefer the separate 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

Never let payment errors crash your application:
Don’t just catch generic errors:
Be careful with retries on payment execution:
Always log error details for debugging:

Next Steps

Examples

See complete integration examples

API Reference

View the REST API (Swagger UI)