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

# Authentication

> API keys for scripts, session cookies for the app.

Brewgravity accepts two credentials, and treats them identically once verified —
the same ownership rules apply either way.

> **API key**
>
> `X-API-Key` header. For scripts, the MCP server, and anything that is not a
> browser.

> **Session cookie**
>
> Set when you sign in to the web app. Browser requests must send
> `credentials: 'include'`.

## Creating an API key

There is no key management screen yet. Keys are created through the auth API,
using your signed-in session — which means the simplest route is your browser's
console.

**1. Sign in to Brewgravity**

Open [brewgravity.com](https://brewgravity.com) and sign in normally.

**2. Open the browser console**

<kbd>⌘</kbd><kbd>⌥</kbd><kbd>J</kbd> on macOS, <kbd>Ctrl</kbd><kbd>Shift</kbd><kbd>J</kbd> on Windows and Linux.

**3. Create the key**

```js theme={null}
await fetch('/api/auth/api-key/create', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  credentials: 'include',
  body: JSON.stringify({ name: 'laptop script' }),
}).then(r => r.json())
```

**4. Copy the key**

The response contains a `key` field. **This is the only time the full key is
ever returned** — copy it now, into a password manager or an environment
variable, not into a file you will commit.

> [!WARNING]
>
> An API key has the same access to your account as you do: it can read, modify,
> and delete every recipe, session, log, and inventory item you own. Treat it
> like a password. Do not put it in client-side code, a public repository, or a
> URL.

### Managing keys

The same auth API lists and revokes them, again from a signed-in browser:

```js theme={null}
// List your keys (the full key values are not returned)
await fetch('/api/auth/api-key/list', { credentials: 'include' }).then(r => r.json())

// Revoke one
await fetch('/api/auth/api-key/delete', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  credentials: 'include',
  body: JSON.stringify({ keyId: '<id from the list above>' }),
}).then(r => r.json())
```

If a key leaks, revoke it. Creating a replacement takes a few seconds and
nothing else about your account needs to change.

## Using a key

Send it in the `X-API-Key` header on every request:

```bash cURL theme={null}
curl https://brewgravity.com/v1/recipes \
  -H "X-API-Key: $GRAVITY_API_KEY"
```

```js JavaScript theme={null}
const res = await fetch('https://brewgravity.com/v1/recipes', {
  headers: { 'X-API-Key': process.env.GRAVITY_API_KEY },
});
const recipes = await res.json();
```

```python Python theme={null}
import os, requests

r = requests.get(
    "https://brewgravity.com/v1/recipes",
    headers={"X-API-Key": os.environ["GRAVITY_API_KEY"]},
)
recipes = r.json()
```

## Checking a key works

```bash theme={null}
curl https://brewgravity.com/v1/me \
  -H "X-API-Key: $GRAVITY_API_KEY"
```

```json theme={null}
{
  "id": "a1b2c3d4-...",
  "email": "you@example.com",
  "name": "Your Name"
}
```

A missing, malformed, expired, or revoked key returns `401 Unauthorized` with
`{"error":"Unauthorized"}`. There is no distinction between the cases, by
design.

## Browser requests

If you are calling the API from a browser on `brewgravity.com` — a bookmarklet,
a console snippet, a userscript — the session cookie already works and you do
not need a key:

```js theme={null}
await fetch('/v1/recipes', { credentials: 'include' }).then(r => r.json())
```

Cross-origin requests are restricted to known origins. Server-side code should
use an API key rather than trying to reuse a cookie.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.