> This page is for version 🇬🇧 UK.
> For other versions, use one of these documentation indexes:
> - 🇦🇺 AU (default): https://docs.humanapproved.com/au/llms.txt
> - 🇬🇧 UK: https://docs.humanapproved.com/uk/llms.txt
> - 🇺🇸 US: https://docs.humanapproved.com/us/llms.txt

> This is HumanApproved's documentation, as Markdown for AI agents. /llms.txt lists every page; /llms-full.txt has them all. If you're helping someone integrate HumanApproved, start with /guides/ai-coding-agents.

# Keys and environments

> HumanApproved publishable keys, review tokens and secret keys, test and live environments, allowed websites and the Origin header, and the host each key works with.

## Three credentials

Send each as `Authorization: Bearer …`.

| Credential          | Looks like                             | Scope                                     | Where it's safe                                                                                     | Routes                                                                          |
| ------------------- | -------------------------------------- | ----------------------------------------- | --------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------- |
| **Publishable key** | `pk_test_…`, `pk_live_…`               | One product, in one environment           | In a web page                                                                                       | `POST /api/v1/checks`, `POST /api/v1/checks/{checkId}/result`                   |
| **Review token**    | 43 characters, in the check's response | One review                                | In the page that made the check. In an agent flow, on your server only: never give it to the agent. | `PUT /api/v1/reviews/{reviewId}/quote`, `GET /api/v1/reviews/{reviewId}/status` |
| **Secret key**      | `sk_test_…`, `sk_live_…`               | One product's reviews, in one environment | Your servers only. Never in a page or an app.                                                       | `GET /api/v1/server/reviews/{reviewId}`                                         |

* A publishable key only identifies the product and its environment, so it's safe in your page's source.
* A review token is returned once, in the check's `review.token`. It lets the holder send that review's quote and read its status, nothing more.
* A secret key reads a review's full outcome, including the decline reason. Store it as you would any server secret.

Create and revoke keys on the portal's **API keys** page (an admin can). The portal shows a key in full only once, when it's created; after that it shows only how the key starts. A key of the wrong kind, a revoked key or another region's key is refused with `401 invalid_key`.

## Test and live

Every key belongs to one environment: `test` or `live`, the second part of the key.

|                  | Test                                                | Live                                        |
| ---------------- | --------------------------------------------------- | ------------------------------------------- |
| Keys             | `pk_test_…`, `sk_test_…`                            | `pk_live_…`, `sk_live_…`                    |
| Host             | Your region's address                               | The same address                            |
| Reviews          | Test reviews only                                   | Live reviews only                           |
| SMS              | Nothing is texted: the approval page shows the code | The code is texted to the customer's mobile |
| Allowed websites | The product's test websites                         | The product's live websites, https only     |

Both use the same host. Test reviews are kept separate from live ones: a test secret key reads only test reviews, and asking for a review from the other environment gets `404 review_not_found`. The outcome's `env` field says which environment a review is in.

## Allowed websites

Each product has a list of **allowed websites** for each environment, on its **API keys** page. Every route except `/api/v1/server/*` checks the request's `Origin` header against the list for the key's environment (or, for the review token routes, the review's environment):

* The origin must match exactly: scheme, host and port, with no path. There are no wildcards, so add each address you use, such as `https://www.example.com` and `https://quote.example.com`.
* Live websites must use https.
* A missing or unlisted origin is refused with `403 origin_not_allowed`.

Browsers send `Origin` for you. **From a server, send it yourself**, set to one of the product's allowed websites. Here `HUMANAPPROVED_URL` is your region's address:

```bash
export HUMANAPPROVED_URL="https://uk.humanapproved.com"
```

```bash
curl $HUMANAPPROVED_URL/api/v1/checks \
  -H "Authorization: Bearer $HUMANAPPROVED_PUBLISHABLE_KEY" \
  -H "Origin: https://www.example.com" \
  -H "Content-Type: application/json" \
  -d '{ "quoteRef": "HTA-4471920" }'
```

The secret key route, `/api/v1/server/reviews/{reviewId}`, needs no `Origin` and sends no CORS headers: it's for servers only.

> **Note**
>
> The routes a page calls respond to CORS preflights from any origin, and the real request is then checked against your allowed websites. A key, token or website that's refused gets a response without CORS headers, so in a browser it shows as a network error. The status and error code are in the browser's network panel.

## Keys and regions

A key works only in the region it was created in. A key sent to another region's host is refused with `invalid_key`.

A key from the UK portal works only with `https://uk.humanapproved.com`.

The embed works out the host from the key, so you don't configure one. Leave the embed's `baseUrl` option unset.

See [Regions and data](/uk/concepts/regions-and-data).