# API keys

Every API request carries an API key in the `Authorization` header:

```http
Authorization: Bearer mf_live_3f9a...
```

Manage keys on the [API Keys](https://app.marleyfetch.com/tokens) page.

## Creating a key

Click **Create Key** and choose:

- **Name** — shown in the dashboard and next to every email the key sends, so you can tell
  your apps apart.
- **Connection Scope** — *All connections*, or one connection. See below.
- **Expiration Period** — never, or after 7 to 365 days.

The full key is shown **once**. Copy it into your secret store straight away; MarleyFetch keeps
only a hash and cannot show it again.

## Locking a key to one connection

A key scoped to a connection can only send through that connection:

- Requests without `from` use the scoped connection, whatever your default is.
- A `from` that belongs to a different connection is refused with `403 CONNECTION_SCOPE_MISMATCH`.

Give each app its own scoped key: a leaked key can then only send as that one address. You can
change a key's scope later with **Edit Scope**.

## Rotating and revoking

- **Rotate** issues a new secret for the key; the old one stops working. Update your app with the
  new value.
- **Revoke** disables the key permanently.

Requests with a revoked, expired or unknown key get `401` with
`{"error": "Invalid or expired API token"}`.

## Keeping keys safe

- Read the key from the environment: `process.env` on Node.js and Vercel, the `env` argument on
  Cloudflare Workers, `Deno.env.get()` on Deno, `Bun.env` on Bun.
- Never ship a key to a browser or a mobile app — anyone could read it and send as you. Call
  MarleyFetch from your server.
- Never commit a key. If one leaks, revoke it and create a new one.

## Plan limits

The Free plan allows **1** API key; Pro is unlimited.
