> ## 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.

# Authentication

> Authenticate Financial Data API requests with an API key, choose a header form, and understand scopes.

Financial Data API authenticates every data request with an API key sent in an HTTP header. Create and manage keys in the [dashboard](https://app.financialdatapi.com): sign up, verify your email, and your key works immediately. See [Pricing](/pricing) for per-tier limits. Keys are SHA-256 hashed server-side and never shown again, so store yours securely the moment you create it.

<Warning>
  Treat your API key like a password. Keep it out of client-side code, public repositories, and shared logs. If a key is ever exposed, rotate it immediately in the dashboard. Anyone holding the key can make requests with its scopes.
</Warning>

## Send your key

You can pass the key in either of two header forms. Both are equivalent. Pick one and use it consistently.

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

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

In application code, set the header once on a client or session:

<CodeGroup>
  ```python Python theme={"theme":"css-variables"}
  import os, requests

  session = requests.Session()
  session.headers["x-api-key"] = os.environ["FINANCIALDATA_API_KEY"]

  resp = session.get(
      "https://api.financialdatapi.com/observations/latest",
      params={"country": "USA"},
  )
  print(resp.json()["data"])
  ```

  ```typescript TypeScript theme={"theme":"css-variables"}
  import { FinancialDataApiClient } from "@financialdatapi/client";

  // The SDK sends the key on every request for you.
  const client = new FinancialDataApiClient({ apiKey: process.env.FINANCIALDATA_API_KEY });

  const res = await client.getLatestObservations({ country: "USA" });
  console.log(res.data);
  ```
</CodeGroup>

## Scopes

Each key is granted one or more scopes. A scope controls which families of routes the key may call. Calling a route your key lacks the scope for returns `403 forbidden`.

| Scope       | Grants access to                                                                                                       | Typical use                                             |
| ----------- | ---------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------- |
| `data:read` | Product and data routes (observations, indicators, countries, entities, the screener, fundamentals, derived analytics) | Application and research workloads                      |
| `ops:read`  | Operational routes (liveness, manifest, snapshot, source health)                                                       | Monitoring feed freshness and sync status               |
| `admin`     | Sensitive admin routes                                                                                                 | Administration. `admin` also satisfies the lower scopes |

<Note>
  `admin` is a superset: a key with `admin` can also call `data:read` and `ops:read` routes. Request the narrowest scope that covers your use case.
</Note>

## Endpoints that need no key

A small set of discovery and health endpoints are open and require no authentication:

* `GET /health`
* `GET /ready`
* `GET /openapi.json`
* `GET /llms.txt`
* `GET /llms-full.txt`

The `/llms.txt` and `/llms-full.txt` files are agent-readable indexes of the API, designed so an AI agent can discover Financial Data API before it ever holds a key.

## Errors

Authentication and authorization failures use the standard Financial Data API error envelope with a stable machine-readable `code`:

<ResponseField name="unauthorized" type="401">
  No key was supplied, or the key is invalid. Check that the header is present and the value is correct.
</ResponseField>

<ResponseField name="forbidden" type="403">
  The key is valid but lacks the scope required by the route. Request a key with the needed scope (or use an `admin` key).
</ResponseField>

```json 401 unauthorized theme={"theme":"css-variables"}
{
  "error": {
    "code": "unauthorized",
    "message": "Missing or invalid API key.",
    "request_id": "0c8f...",
    "requestId": "0c8f...",
    "details": {}
  },
  "requestId": "0c8f..."
}
```

## Rate limits

Rate limits are enforced per client, per required scope, in a fixed window. Every API response includes the current limit state in headers:

| Header                  | Meaning                                  |
| ----------------------- | ---------------------------------------- |
| `x-ratelimit-policy`    | The policy applied to this request       |
| `x-ratelimit-limit`     | Maximum requests allowed in the window   |
| `x-ratelimit-remaining` | Requests remaining in the current window |
| `x-ratelimit-reset`     | When the window resets (ISO timestamp)   |

Default limits use a 60-second window: `data:read` allows 1000 requests per minute, `ops:read` allows 500 per minute, and `admin` allows 250 per minute. When you exceed a limit, Financial Data API returns `429 rate_limited` with `details` describing the breach:

```json 429 rate_limited theme={"theme":"css-variables"}
{
  "error": {
    "code": "rate_limited",
    "message": "Rate limit exceeded.",
    "request_id": "0c8f...",
    "requestId": "0c8f...",
    "details": {
      "required_scope": "data:read",
      "limit": 1000,
      "window_seconds": 60
    }
  },
  "requestId": "0c8f..."
}
```

<Tip>
  Read `x-ratelimit-remaining` and `x-ratelimit-reset` from successful responses to pace your requests before you hit a `429`, and back off until the reset time when you do.
</Tip>

## Next steps

<Columns cols={2}>
  <Card title="Quickstart" icon="rocket" href="/quickstart">
    Make your first authenticated call and page through results.
  </Card>

  <Card title="API reference" icon="square-terminal" href="/api-reference/introduction">
    Browse every endpoint, parameter, and response field.
  </Card>
</Columns>
