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

# API Reference

> Auto-generated endpoint reference for the Financial Data API, built from the live OpenAPI spec.

Every page in this section is generated from Financial Data API's OpenAPI spec. Each endpoint page shows its path, method, parameters, request scopes, and response schema directly from the source of truth, so the reference never drifts from the running service.

<Info>
  The reference is built from [`openapi.json`](/api-reference/openapi.json). If an endpoint, parameter, or field appears in the spec, it is live. If it does not appear there, it is not part of the public contract.
</Info>

## Base URL

All paths are relative to a single host.

```
https://api.financialdatapi.com
```

Endpoints use clean, versionless paths (for example `/observations/latest`), and every response reports `meta.api_version = "v1"`. The legacy `/v1/...` paths remain available as aliases. Financial Data API is read-only and GET-only.

## Authentication

Send your API key on every data request. Two header forms are accepted.

<CodeGroup>
  ```bash x-api-key header theme={"theme":"css-variables"}
  curl https://api.financialdatapi.com/observations/latest \
    -H "x-api-key: $FINANCIALDATA_API_KEY"
  ```

  ```bash Authorization header theme={"theme":"css-variables"}
  curl https://api.financialdatapi.com/observations/latest \
    -H "Authorization: Bearer $FINANCIALDATA_API_KEY"
  ```
</CodeGroup>

A small set of routes need no key: `GET /health`, `GET /ready`, `GET /openapi.json`, `GET /llms.txt`, and `GET /llms-full.txt`.

Keys carry scopes. Most product and data routes require `data:read`. Operational routes require `ops:read`. Sensitive admin routes require `admin`, which also satisfies the lower scopes. A key without the required scope returns `403 forbidden`.

<Note>
  Keys are issued on request today. There is no self-serve signup form yet. See [Support](/support) to request access. Keys are hashed server-side and are never returned, so store yours securely when issued.
</Note>

## The response envelope

Every response shares one shape, so you can write parsing once and reuse it everywhere. List responses wrap an array in `data` and carry pagination in `meta.pagination`. Item responses wrap a single object in `data`. Errors carry a stable machine-readable `code`. The `request_id` (also mirrored as top-level `requestId`) identifies the exact request and is what you quote when you contact support.

<CodeGroup>
  ```json List response theme={"theme":"css-variables"}
  {
    "data": [ /* ... */ ],
    "meta": {
      "request_id": "8f1c0e2a-6b3d-4f0a-9c11-1d2e3f4a5b6c",
      "requestId": "8f1c0e2a-6b3d-4f0a-9c11-1d2e3f4a5b6c",
      "api_version": "v1",
      "pagination": {
        "limit": 100,
        "cursor": null,
        "next_cursor": null,
        "has_more": false
      }
    },
    "requestId": "8f1c0e2a-6b3d-4f0a-9c11-1d2e3f4a5b6c"
  }
  ```

  ```json Item response theme={"theme":"css-variables"}
  {
    "data": { /* ... */ },
    "meta": {
      "request_id": "8f1c0e2a-6b3d-4f0a-9c11-1d2e3f4a5b6c",
      "requestId": "8f1c0e2a-6b3d-4f0a-9c11-1d2e3f4a5b6c",
      "api_version": "v1"
    },
    "requestId": "8f1c0e2a-6b3d-4f0a-9c11-1d2e3f4a5b6c"
  }
  ```

  ```json Error response theme={"theme":"css-variables"}
  {
    "error": {
      "code": "bad_request",
      "message": "Unknown query parameter: foo",
      "request_id": "8f1c0e2a-6b3d-4f0a-9c11-1d2e3f4a5b6c",
      "requestId": "8f1c0e2a-6b3d-4f0a-9c11-1d2e3f4a5b6c",
      "details": {}
    },
    "requestId": "8f1c0e2a-6b3d-4f0a-9c11-1d2e3f4a5b6c"
  }
  ```
</CodeGroup>

### Error codes

Errors use a stable `error.code`. Branch on the code, not the message.

| Code             | HTTP | Meaning                                         |
| ---------------- | ---- | ----------------------------------------------- |
| `bad_request`    | 400  | Malformed input, or an unknown query parameter. |
| `unauthorized`   | 401  | Missing or invalid API key.                     |
| `forbidden`      | 403  | Key is valid but lacks the required scope.      |
| `not_found`      | 404  | The resource does not exist.                    |
| `rate_limited`   | 429  | Rate limit exceeded for this client and scope.  |
| `internal_error` | 500  | Unexpected server error.                        |

<Warning>
  Unknown query parameters fail closed. A parameter Financial Data API does not recognize is rejected with `bad_request`, never silently ignored. This catches typos before they return misleading data.
</Warning>

## Pagination

List endpoints page with an opaque cursor. Set `limit` (1 to 500, default 100). When `meta.pagination.has_more` is `true`, pass `meta.pagination.next_cursor` back as `cursor` to fetch the next page. `sort` and `order` (`asc` or `desc`, default `asc`) control ordering on endpoints that support them.

## Rate limits

Limits are enforced per client, per required scope, in a fixed window. Every API response includes `x-ratelimit-policy`, `x-ratelimit-limit`, `x-ratelimit-remaining`, and `x-ratelimit-reset` (ISO timestamp). On exceed you get `429 rate_limited` with `details` carrying `required_scope`, `limit`, and `window_seconds`.

| Scope       | Default limit | Window |
| ----------- | ------------- | ------ |
| `data:read` | 1000 requests | 60s    |
| `ops:read`  | 500 requests  | 60s    |
| `admin`     | 250 requests  | 60s    |

## Explore the spec

<Columns cols={2}>
  <Card title="OpenAPI spec" icon="file-code" href="/api-reference/openapi.json">
    The raw machine-readable contract. Import it into Postman, Insomnia, or your own code generator.
  </Card>

  <Card title="Coverage" icon="layer-group" href="https://api.financialdatapi.com/coverage">
    A live breadth summary: catalog totals, public indicator categories, and covered countries.
  </Card>
</Columns>
