# Errors

> The error format, every error code, and what to send support.

Errors use standard HTTP status codes and one JSON shape:

```json
{
  "error": {
    "code": "external_id_conflict",
    "message": "A payment with this external_id already exists for this business.",
    "param": "external_id",
    "request_id": "req_1df6dd76-0350-479c-a234-e16d63b0f78b"
  }
}
```

- `code` is stable and machine-readable — switch on it. New codes can be added, so keep a default branch.
- `message` is for humans and may change.
- `param` names the offending field when there is one.
- **`request_id` — include it when you contact support.** It lets us find the exact request.

The SDK raises typed errors (`DevzityValidationError`, `DevzityAuthenticationError`, `DevzityRateLimitError`, `DevzityIdempotencyError`, `DevzityAPIError`, `DevzityNetworkError`), each with `code`, `message`, `param`, `requestId` and `httpStatus`.

## Handling an error

```js
import { DevzityAPIError } from "@devzity/sdk"

try {
  await devzity.payments.create({ amount: 500 })
} catch (error) {
  if (error instanceof DevzityAPIError) {
    console.error(error.code, error.requestId)
  }
}
```

Not sure what a code means? See [Troubleshooting](https://docs.devzity.com/v1/troubleshooting.md).

## Error codes

Every error code, with its HTTP status and meaning, is in the OpenAPI document: https://docs.devzity.com/openapi/devzity-v1.yaml

## Retrying

Retry only what is safe. `429` (rate limit — wait for `Retry-After`) and `5xx` are retryable; other `4xx` errors are not — fix the request. Always retry a create with the **same** `Idempotency-Key` (the SDK does this for you). See [Idempotency](https://docs.devzity.com/v1/idempotency.md).
