# Authentication

Every request needs an API key, except [GET /status](/docs/status-endpoint).

## API keys

Keys look like `mna-live-` followed by 40 hex characters. The first key is created when you sign up. While you are signed in, samples on this site use your oldest active key. Create, name and revoke keys on the [API keys](/dashboard/keys) page. Every key on an account shares the account's plan and usage.

## Sending your key

Use whichever method suits your client. If you send more than one, the header wins.

| Method | Example | Use for |
| --- | --- | --- |
| `Authorization` header | `Authorization: Bearer mna-live-...` | Recommended for all server code |
| `X-API-Key` header | `X-API-Key: mna-live-...` | Tools that can't set a Bearer token |
| `api_key` query parameter | `?api_key=mna-live-...` | WebSocket URLs, quick tests in a browser |

```bash
curl "https://api.marketnewsapi.com/v1/news?limit=1" \
 -H "Authorization: Bearer $MARKETNEWSAPI_KEY"
```

> Query-string keys can end up in proxy and server logs. Prefer a header for REST calls. For WebSockets you can also skip the query parameter and authenticate with a message after connecting. See [WebSocket authentication](/docs/websocket#auth).

## Authentication errors

| Status | Code | Meaning |
| --- | --- | --- |
| 401 | `missing_api_key` | No key was sent. Use the `Authorization: Bearer` header, `X-API-Key`, or `?api_key=`. |
| 401 | `invalid_api_key` | The key doesn't exist or was revoked. Create a new one in the dashboard. |
| 403 | `plan_required` | The feature isn't in your plan (for example, the WebSocket stream on Free). |

## Keeping keys safe

- Load keys from environment variables or a secrets manager, never from source control.
- Don't embed keys in front-end JavaScript or mobile apps. Proxy requests through your backend.
- Use a separate named key per app or environment, so you can revoke one without breaking the others.
- If a key leaks, revoke it in the dashboard. It stops working within a few seconds.
