type and code in the body tell you the specifics.
Envelope
type and message. code is set when there’s a more specific failure mode within a type (most payment policy violations carry one). details carries structured context when relevant — typically the failed Zod issue list for validation errors.
Error types
The SDK maps each type to a typed exception class — see SDK errors. REST callers branch on
type and code directly.
Codes on POST /v1/payments
The payments endpoint is the only v1 route with structured code values today. Branch on error.type first, error.code second.
The
forbidden-typed codes are policy violations, not auth failures. Surface them in your UI as “this permission doesn’t permit that,” not “your credentials are bad.”
Recovery patterns
Always read
error.message for human context before deciding — the message often points at the specific field or constraint that failed.
Sample handlers
Branching on type and code
Logging unknown errors
When you encounter atype your handler doesn’t branch on, log the entire envelope and surface a generic failure to the user. Don’t drop the body — the details field often has exactly the info you need to diagnose later.