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

# Authentication

> Get a key, send it as a bearer token, and keep it secret.

Every call to the API needs a secret key, sent in the `Authorization` header.

## Getting a key

Keys are issued by arrangement for now. Email [hello@checkthatfield.com](mailto:hello@checkthatfield.com) with:

* what you'd like to build
* roughly how many calls a month you expect
* for the widget, the sites it will be on

We set each key's monthly quota when we make it. Pricing is by arrangement.

> [!NOTE]
>
> We keep only a hash of your key, so we can't show it to you again. We send it once, when it is made. Store it somewhere safe straight away.

## Two kinds of key

| | Secret key | Publishable key |
| - | - | - |
| Looks like | `ctf_sk_live_` and 32 letters and digits | `ctf_pk_live_` and 24 letters and digits |
| For | The API, from your server | The [widget](https://docs.checkthatfield.com/widget/overview.md), in your web pages |
| Where it may be seen | Only on your server | Anyone can read it in your page |
| What limits it | The key itself | The sites it was issued for, and their subdomains |

A publishable key doesn't work with the API, and a secret key doesn't work in the widget. Using the wrong kind gets `401 invalid_key`.

## Sending your key

Send the secret key as a bearer token:

```http theme={null}
Authorization: Bearer ctf_sk_live_…
```

The word `Bearer` can be in any case. Don't put the key in the query string: the API only reads the header.

```bash curl theme={null}
curl -H "Authorization: Bearer $CTF_KEY" \
  "https://api.checkthatfield.com/v1/usage"
```

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

session = requests.Session()
session.headers["Authorization"] = f"Bearer {os.environ['CTF_KEY']}"
print(session.get("https://api.checkthatfield.com/v1/usage", timeout=30).json())
```

```javascript JavaScript theme={null}
// Server-side only.
const res = await fetch("https://api.checkthatfield.com/v1/usage", {
  headers: { Authorization: `Bearer ${process.env.CTF_KEY}` },
});
console.log(await res.json());
```

A missing or unknown key gets:

```json theme={null}
{ "error": { "code": "invalid_key", "message": "The API key is missing or not valid." } }
```

with status `401`.

## Keeping your key secret

> [!WARNING]
>
> Anyone with your secret key can use your quota. Never put it in a web page, a mobile app, or a public repository.

* Keep it in an environment variable or a secrets manager, not in code.
* Call the API from your server, and pass on only what your pages need.
* To show scores in a page, use the [widget](https://docs.checkthatfield.com/widget/overview.md) with a publishable key instead.
* Give each product or environment its own key, so you can revoke one without stopping the others.

## Revoking a key

If a key leaks, or you no longer need it, email [hello@checkthatfield.com](mailto:hello@checkthatfield.com) and we'll revoke it and issue a new one. Revoking takes effect at once and can't be undone. Calls with a revoked key get:

```json theme={null}
{ "error": { "code": "key_revoked", "message": "This API key has been revoked." } }
```

with status `403`.


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