# Authentication

https://modelportal.ai/docs/authentication

Every model call is authenticated with an API key created on the Keys page of the console. Each protocol keeps its official SDK's convention:

| Protocol | Endpoints | Where the key goes |
| --- | --- | --- |
| OpenAI-compatible | `https://modelportal.ai/v1/*` | Header `Authorization: Bearer YOUR_API_KEY` |
| Anthropic-compatible | `https://modelportal.ai/v1/messages` and friends | Header `x-api-key: YOUR_API_KEY`, or `Authorization: Bearer YOUR_API_KEY` |
| Gemini-compatible | `https://modelportal.ai/v1beta/*` | Header `x-goog-api-key: YOUR_API_KEY`, query parameter `?key=YOUR_API_KEY`, or `Authorization: Bearer YOUR_API_KEY` |

- The OpenAI and Anthropic APIs reject keys passed in the URL query string.
- If a Gemini request carries the key in more than one place, all copies must match or the request is rejected.
- The public model list under `/api/v1/*` needs no auth; console endpoints use your login session and do not accept API keys.

## When authentication fails

| HTTP | Code | Cause |
| --- | --- | --- |
| 401 | `invalid_api_key` | The key is missing, mistyped or revoked |
| 401 | `key_inactive` | The key is paused or expired |
| 403 | `key_restricted` | The model is not in the key's allowed models, or the source IP is not on the key's allowlist |

## Keeping keys safe

- Use keys on the server only. Anyone can pull code out of a browser or mobile app; to call from a frontend, go through your own backend.
- Create separate keys per app or environment, give each allowed models and a spend limit, and disable just one when something goes wrong.
- If a key may have leaked, revoke it on the Keys page right away and create a new one; see [API keys](/docs/api-keys).
