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

# Authentication

> One API key, sent in the apikey header, for every API.

Every request to `https://api.eventory.ai` must carry your API key. The gateway
authenticates it, checks that your key is granted the API you are calling, and strips
the credential before forwarding the request internally. Downstream services never
see your key.

## Sending the key

Put the key in the `apikey` header:

```bash theme={null}
curl -s https://api.eventory.ai/usage -H "apikey: $EVENTORY_API_KEY"
```

The `Authorization` header and the `api_key` and `token` query parameters are also
accepted for compatibility. Prefer the header: a key in a query string ends up in
proxy and server logs.

For the WebSocket stream the key goes on the upgrade request, the same way. Browsers
cannot set custom headers on a WebSocket, so the stream is meant for native clients
or a backend proxy. See [Connecting to the stream](/stream/connecting).

## Getting a key

Keys are issued with an Eventory plan. Every key starts with access to the stream,
the watchlist and `/usage`; Market Data and Live Availability are enabled per account.
See [Credits & access](/credits-and-access) for how to tell what your key can call.

## Keeping it safe

* **Never ship a key in client-side code.** Anyone who can read your page or app can
  read the key and spend your credits. Call the API from your backend.
* **Store it in an environment variable**, not in source control.
* **Rotate a key you suspect has leaked.** Contact Eventory to revoke and reissue it.
* **Use TLS only.** Plain `http://` and `ws://` are not accepted.

## What goes wrong

| Status | `code`                | Meaning                                                     |
| ------ | --------------------- | ----------------------------------------------------------- |
| `401`  | `unauthenticated`     | No credential was sent. Most often an empty shell variable. |
| `401`  | `invalid_credentials` | A key was sent and rejected. Wrong, revoked, or expired.    |
| `403`  | `forbidden`           | The key is valid but is not granted this API.               |

All three come back in the gateway's error envelope. See [Errors](/errors).
