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

# Errors and Limits

> Shared error envelope, retry headers, and usage-limit headers returned by the Criffy API.

# Errors and Limits

Protected `/api/v1/*` endpoints share a stable error envelope:

```json theme={null}
{
  "error": {
    "code": "rate_limit_exceeded",
    "message": "Rate limit exceeded.",
    "details": {
      "reset_at": "2026-04-23T17:42:00.000Z",
      "limit": 60
    }
  }
}
```

## Limits at a glance

Pro+ API keys currently include:

* 60 requests per minute
* 100,000 requests per calendar month
* Monthly quota reset on the 1st day of each month at `00:00 UTC`

You can see your current monthly usage in [Settings -> API](https://criffy.com/settings/api). The dashboard usage widget shows how many requests you have used, your monthly limit, and the next reset date.

Every authenticated response also includes `X-RateLimit-*` and `X-Quota-*` headers. Treat these headers as the effective source of truth for your current limits, remaining requests, and reset timestamps.

## Shared error codes

* `invalid_api_key`: the Bearer token is missing, invalid, or revoked
* `subscription_required`: the key belongs to a user without active `Pro+`
* `rate_limit_exceeded`: the per-minute request budget was exhausted
* `monthly_quota_exceeded`: the current monthly request budget was exhausted
* `not_found`: the requested resource does not exist or is not exposed publicly, including unpublished or delisted resources
* `validation_error`: query or path parameters failed validation
* `service_unavailable`: a required internal dependency failed closed
* `internal_error`: unexpected unhandled server failure

## Usage-limit headers

Successful authenticated `/api/v1/*` responses include:

* `X-RateLimit-Limit`
* `X-RateLimit-Remaining`
* `X-RateLimit-Reset`
* `X-Quota-Limit`
* `X-Quota-Remaining`
* `X-Quota-Reset`

These headers are the stable way to discover your current effective limits and reset times.

## Retry behavior

`429` and some availability errors can include `Retry-After`.

When present:

* Respect `Retry-After` before retrying
* Use the reset timestamps from `details.reset_at` and the `X-*-Reset` headers to schedule the next attempt

## Important notes

* Limit values can be environment-configured, so treat the response headers as the source of truth instead of hard-coding numeric assumptions.
* Published but unavailable/inactive offers are still public data. They can be returned with `available: false` for earn or `is_active: false` for borrow and collateral.
* `GET /api/v1/collateral/{id}/history` returns `404 not_found` by design because collateral history is not persisted.
