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

# Authentication

> API keys, their scopes, environments and expiry.

Every request carries an API key in the `X-API-Key` header.

```bash cURL theme={null}
curl "https://go-fetch.io/api/v1/jobs/?limit=5" \
  -H "X-API-Key: $GOFETCH_API_KEY"
```

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

from gofetch import GoFetchClient

client = GoFetchClient(api_key=os.environ["GOFETCH_API_KEY"])  # sends X-API-Key on every request
print(client.base_url)
```

```javascript JavaScript theme={null}
const res = await fetch('https://go-fetch.io/api/v1/jobs/?limit=5', {
  headers: { 'X-API-Key': process.env.GOFETCH_API_KEY },
});
console.log(res.status, (await res.json()).total);
```

Four endpoints answer without a key: the price list (`GET /api/v1/pricing/`, `GET /api/v1/pricing/{platform}/`),
the cost estimate (`POST /api/v1/pricing/calculate_cost/`) and the schema (`GET /api/v1/openapi.json`). Requests without a key have a lower
[rate limit](https://docs.go-fetch.io/rate-limits.md).

## Keys

* Create keys in the dashboard under **API keys**, or with `POST /api/v1/api-keys/create/` using a key that has the
  `admin` scope.
* A key starts with `sk_`. It is shown in full once, when it is created; afterwards you see only its prefix. Store it
  in a secret manager or an environment variable, and use it only from your servers, never in browser or mobile code.
* A key belongs to one organization. Everything it does is billed to that organization and recorded in its audit log.
* An organization can have at most 25 active API keys. Creating or re-activating a key above that returns `400`;
  revoke one first.
* A key has a `rate_limit`: its requests per hour, from 1 to 100,000, and 1,000 unless you set another when you
  create it. Creating or updating a key with `rate_limit` above 100,000 returns `400`. See [Rate limits](https://docs.go-fetch.io/rate-limits.md).
* **Rotate** a key with `POST /api/v1/api-keys/{id}/rotate/`: you get a new key with the same name, scopes, rate limit
  and environment, and the old key stops working at once.
* **Revoke** a key with `DELETE /api/v1/api-keys/{id}/`. It stops working at once.

## Scopes

A key has one or more scopes. `admin` includes `write`, and `write` includes `read`.

| Scope | Allows |
| - | - |
| `read` | Every `GET`: jobs, results, logs, webhooks and their deliveries, usage, API keys, organization details |
| `write` | Creating, cancelling and retrying jobs; creating, changing, testing and deleting webhooks; redelivering events |
| `admin` | Creating, changing, rotating and revoking API keys; changing the organization, its members and environments |

To run jobs and read their results, a key needs `read` and `write`. A request outside the key's scopes answers
`403`:

```json theme={null}
{"detail":"Insufficient scope. Required: admin"}
```

## Environments

An organization has one or more environments, for example production and staging. Each key belongs to one
environment, chosen when the key is created (the organization's default otherwise). Jobs the key creates are tagged
with that environment, and `GET /api/v1/jobs/?environment=<slug>` lists one environment's jobs.

Environments label work; they do not isolate it. Any key of the organization can read every job of the
organization, and all environments share one credit balance.

## Expiry

A key can have an expiry time (`expires_at`). From that moment it is refused like a revoked key. Keys without
`expires_at` work until they are revoked.

## When a key is refused

| Status | Body | Why |
| - | - | - |
| `401` | `{"detail":"Authentication credentials were not provided."}` | No `X-API-Key` header |
| `401` | `{"detail":"Invalid or expired API key"}` | The key is wrong, revoked or past `expires_at` |
| `401` | `{"detail":"Organization is inactive"}` | The key's organization is not active |
| `403` | `{"detail":"Insufficient scope. Required: write"}` | The key lacks the scope the endpoint needs |

A `401` response carries `WWW-Authenticate: X-API-Key`.

> [!WARNING]
>
> The API reference's playground sends your requests, key included, through Mintlify, the service that hosts these
> docs. Try it with a key you can revoke afterwards, scoped to `read` where that is enough.


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