# Authentication

Every call is made with an API key, sent as a bearer token. A key belongs to one Gateway organization, and its calls are paid from that organization’s credits.

## Send your key

Put the key in the `Authorization` header of every call. The model catalogs need no key, so you can read them before you have one.

```http
Authorization: Bearer $MOMOR_API_KEY
Content-Type: application/json
```

| Route | What it takes |
| --- | --- |
| `POST /models, /models/chat, /models/two, /models/decision, /models/transcribe` | An API key |
| `GET /models/requests/{requestId}` | An API key |
| `POST /v1/chat/completions, /models/completions, /v1/audio/transcriptions` | An API key, or a signed-in Momor session |
| `GET /models, /models/chat, /models/two, /models/decision, /models/transcribe, /v1/models` | Nothing |

## Where keys come from

A Gateway organization’s owner creates its API keys, while signed in: in [Settings › API keys](/settings/gateway/api-keys), or with the call below. A Search account holds no API keys, and the call is refused with `403` there. A Workflow organization’s API keys start and answer its workflow runs; `/models` and `/v1` refuse them with `403`, so only a Gateway organization’s API keys call models. No Gateway organization yet? [Create one](/organization/new/gateway).

`POST https://api.momor.ai/organization/apikeys`

- `name` (string, required): What the key is for, so you can tell your keys apart.
- `expiresAt` (date-time): When the key stops working. Leave it out for a key that works until it is revoked.

The answer is `201` with the key as `apikey`. It is shown only in this answer; Momor can’t show it again.

```json
{ "apikey": "…" }
```

> **Keep keys on your server**
> Anyone with the key can spend your organization’s credits. Don’t put it in a browser or a mobile app.

## Listing and revoking keys

`GET /organization/apikeys` lists the organization’s keys newest first, revoked ones included, a page at a time: `skip` passes over that many keys (0 by default) and `take` sets how many a page holds, from 1 to 200 (50 by default). The answer is `{ "count", "items" }`: how many keys the organization holds, and the page, each key with its `id`, `name`, `expiresAt`, `revokedAt` and `lastUsedAt`. `DELETE /organization/apikeys`, with the key as a JSON string in the body, revokes it and answers `204`; from then on the key is refused. Both are for the owner, signed in.

## When a key is refused

A missing, revoked or expired key, or a value that is not a Momor key, is answered `401` before the call is routed. On the OpenAI-compatible routes the body is OpenAI’s error object:

```json
{ "error": { "message": "The API key was refused.", "type": "authentication_error", "param": null, "code": "invalid_api_key" } }
```

A Workflow organization’s API key is answered `403` on `/models` and `/v1`: its keys start, answer and read workflow runs only.

Each key is counted on its own for [rate limits](/docs/gateway/rate-limits/), and every call it makes is recorded under the organization; see [usage and costs](/docs/gateway/usage/).
