> ## Documentation Index
> Fetch the complete documentation index at: https://alguna.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Errors

> Error response shape, status codes, typed SDK errors, request IDs, and which failures are safe to retry.

Every failed request returns a JSON body with a `status` and a `detail`:

```json theme={null}
{
  "status": 400,
  "detail": "Validation failed: name is required"
}
```

`status` repeats the HTTP status code. `detail` is a human-readable explanation intended for logs and developers — it is not a stable identifier, so **do not branch on the text of `detail`**. Branch on the HTTP status, or on the typed error the SDK raises.

***

## Status codes

| Status | Meaning                                                            | What to do                                                                                    |
| ------ | ------------------------------------------------------------------ | --------------------------------------------------------------------------------------------- |
| `400`  | Invalid parameters                                                 | Fix the request. Retrying unchanged will fail again.                                          |
| `401`  | Missing or invalid API key                                         | Check the `Authorization` header and that the key belongs to the environment you are calling. |
| `404`  | Resource does not exist                                            | Check the id. Note that a resource in another environment reads as missing.                   |
| `409`  | A request with this idempotency key is still being processed       | Wait and retry with the **same** key. See [Idempotency](/docs/api-reference/v2/idempotency).       |
| `422`  | Validation error — well-formed request, but it cannot be processed | Fix the request. Retrying unchanged will fail again.                                          |
| `429`  | Rate limited                                                       | Back off and retry. See [Retrying](#retrying) below.                                          |
| `500`  | Internal error                                                     | Safe to retry idempotent requests; use an idempotency key for writes.                         |

<Note>
  `400` and `422` both indicate the request will not succeed as sent. Broadly, `400` means the request itself was malformed, and `422` means it parsed correctly but violates a rule — for example a value that is well-formed but not valid for the current state of the resource.
</Note>

***

## Request IDs

Every response carries an `X-Request-Id` header — a UUID generated per request. Log it.

When you contact support about a failed request, the request ID is the fastest way for us to find it — far quicker than a timestamp and an endpoint. The TypeScript SDK surfaces it as `requestId` on every error it raises.

```bash theme={null}
curl -i https://api.alguna.io/customers \
  -H "Authorization: Bearer $ALGUNA_API_KEY" \
  -H "Alguna-Version: 2026-04-01"
# ...
# X-Request-Id: 9f1c2e7a-4b83-4d6e-9a51-2c0f7b3d8e14
```

***

## Typed errors in the TypeScript SDK

The [TypeScript SDK](/docs/api-reference/v2/sdks/typescript) maps failed responses onto typed error classes, so you can branch with `instanceof` rather than inspecting status codes by hand.

| Class                 | Status                     | `code`                 | Extra properties                                             |
| --------------------- | -------------------------- | ---------------------- | ------------------------------------------------------------ |
| `ValidationError`     | `400`                      | `validation_error`     | `fields` — a map of field name to the problems found with it |
| `AuthenticationError` | `401`                      | `authentication_error` | —                                                            |
| `NotFoundError`       | `404`                      | `not_found`            | `resource` — the kind of resource that was missing           |
| `RateLimitError`      | `429`                      | `rate_limit_error`     | `retryAfter` — seconds to wait before retrying               |
| `ApiError`            | any other, including `5xx` | `api_error`            | —                                                            |

All of them extend `AlgunaError` and carry `statusCode`, `code` and `requestId`.

```typescript theme={null}
import {
  AlgunaError,
  NotFoundError,
  RateLimitError,
  ValidationError,
} from "@alguna/sdk";

try {
  await alguna.customers.create({ name: "Acme Corp", currency: "USD" });
} catch (error) {
  if (error instanceof ValidationError) {
    // error.fields — e.g. { currency: ["must be a supported currency"] }
    return reportInvalidInput(error.fields);
  }
  if (error instanceof RateLimitError) {
    await sleep((error.retryAfter ?? 1) * 1000);
    return retry();
  }
  if (error instanceof NotFoundError) {
    return handleMissing(error.resource);
  }
  if (error instanceof AlgunaError) {
    // Unexpected: log the request id so support can trace it.
    logger.error({ requestId: error.requestId, status: error.statusCode });
  }
  throw error;
}
```

<Note>
  `422` is not mapped to `ValidationError`. It arrives as `ApiError` with `statusCode: 422`. Handle both when you are validating user input.
</Note>

***

## Retrying

Retry these:

* **`429`** — wait for `retryAfter` before retrying. If it is absent, back off exponentially.
* **`500`** and other `5xx` — retry with exponential backoff and jitter.
* **`409`** — the earlier request with that idempotency key is still in flight. Retry with the **same** key; do not generate a new one, or you risk creating a duplicate.
* **Network timeouts** — you do not know whether the request was applied. Retry with the same idempotency key.

Do not retry `400`, `401`, `404` or `422` without changing the request. They are deterministic and will fail identically.

<Warning>
  Always send an `Idempotency-Key` on writes you might retry. Without one, a retry after a timeout can create a second customer, subscription or invoice. See [Idempotency](/docs/api-reference/v2/idempotency).
</Warning>

***

## Related

<CardGroup cols={2}>
  <Card title="Idempotency" icon="fingerprint" href="/docs/api-reference/v2/idempotency">
    Idempotency keys, replay behaviour, and the `409` conflict case.
  </Card>

  <Card title="TypeScript SDK" icon="code" href="/docs/api-reference/v2/sdks/typescript">
    Installation, authentication, and error handling.
  </Card>
</CardGroup>
