> Toden documentation. For the full index fetch /llms.txt. Every page is available as Markdown by appending .md to its URL. Identity verification uses /api/kyc, Risk Intelligence uses /api/v1; they are separate contracts with different error shapes. Never invent an endpoint, field or enum value: read the API reference page for the operation first.

# API keys

> Manage publishable and secret keys in the Toden console: environments and prefixes, one-time display of secret keys, origin and IP restrictions, revocation and safe rotation.

API keys are how your application authenticates with Toden. You create and manage them in the console. This page is for the developer who sets up an integration and for whoever is responsible for keeping its credentials safe. For how to send a key with a request, see [Authentication](/get-started/authentication).

## Where to find it

Open **Developers → API Keys** at [console.toden.co](https://console.toden.co). The environment selector in the console header decides which keys you see and which kind you create: Sandbox or Production. Keys from one environment never appear in the other.

| Action                                                             | Permission needed |
| ------------------------------------------------------------------ | ----------------- |
| View the key list                                                  | `api_keys:read`   |
| Create a key, edit its restrictions, see a publishable key in full | `api_keys:create` |
| Revoke a key                                                       | `api_keys:revoke` |

## Key types and prefixes

| Prefix     | Type        | Environment | Where it belongs          |
| ---------- | ----------- | ----------- | ------------------------- |
| `pk_test_` | Publishable | Sandbox     | Client SDKs and frontends |
| `sk_test_` | Secret      | Sandbox     | Your backend only         |
| `pk_live_` | Publishable | Production  | Client SDKs and frontends |
| `sk_live_` | Secret      | Production  | Your backend only         |

A **publishable** key starts verifications from a client. A **secret** key does everything a publishable key can, and also reads full results, personal data and captured media. A publishable key that calls a secret-only endpoint gets `403 secret_key_required`.

A key works only in its own environment. Sending a Sandbox key to Production, or the reverse, returns `403 environment_mismatch`.

## Create a key

### Choose the environment

Set the environment selector in the console header to Sandbox or Production.

### Start a new key

On **Developers → API Keys**, choose **Create key**.

### Name it and pick a type

Enter a **Key name** that says where the key is used, for example "Mobile app sandbox", and choose **Publishable** or **Secret** under **Key type**.

### Copy the key

The console shows the new key once the request succeeds. Copy it before you close the dialog.

> **Warning**
>
> A secret key is shown **once**, when it is created. Toden stores only a hash of it, so nobody, including Toden support, can show it to you again. If you lose it, create a new key and revoke the old one.

### What you can see afterwards

| Key type    | In the list                                                                                       |
| ----------- | ------------------------------------------------------------------------------------------------- |
| Secret      | The first 16 characters only, for identification                                                  |
| Publishable | The full key, for roles that hold `api_keys:create`. Other roles see the first 16 characters only |

A publishable key is safe to ship in client code, but it can still start billable verifications. That is why read-only roles do not see it in full.

The list also shows each key's name, type, status (Active or Revoked), who created it, when it was created and when it was last used.

### Production keys need an approved business

Creating a `pk_live_` or `sk_live_` key requires that Toden has approved your business profile. Until then the Production option is locked in the console, and the request returns `403 business_not_approved`. Sandbox keys are available from the start. See [Go live](/get-started/go-live).

## Restrict a key

Restrictions limit where a key can be used, so a copied key is useless elsewhere. They are optional: a key with an empty list is unrestricted. Open a key's actions and choose **Restrict key** (or **Edit restrictions** once some are set).

The kind of restriction depends on the key type.

| Key type    | Restriction                         | Field            | Refusal                  |
| ----------- | ----------------------------------- | ---------------- | ------------------------ |
| Publishable | Allowed web origins                 | `allowedOrigins` | `403 origin_not_allowed` |
| Secret      | Allowed IP addresses or CIDR ranges | `allowedIpCidrs` | `403 ip_not_allowed`     |

Each list holds up to **20** entries. Duplicates are removed.

#### Publishable: web origins

Enter each origin as scheme and host, with a port if it is not the default: `https://app.example.com`. Paths are ignored, and only `http` and `https` are accepted.

* A browser request whose `Origin` (or, failing that, `Referer`) is not on the list is refused.
* A request with no origin at all is **allowed**. Native mobile SDKs and server callers send no `Origin`, so an origin list does not affect them.

This is a browser control. It stops a key lifted from your site being used on another site. It does not stop a non-browser client, which can omit the header. For a backend, use a secret key restricted by IP.

#### Secret: IP ranges

Enter your backend's public egress addresses as single IPs or CIDR ranges, IPv4 or IPv6: `203.0.113.5` or `203.0.113.0/24`. A single address is stored as a `/32` (IPv4) or `/128` (IPv6) range.

* A request from any address outside the list is refused.
* If Toden cannot determine the caller's address, a restricted key is refused.

> **Tip**
>
> Add restrictions in Sandbox first and confirm your integration still works. A wrong IP range on a live secret key stops your backend from reading results until you correct it.

## Revoke a key

Choose **Revoke key** from the key's actions. Revocation is immediate and permanent: the next request made with that key returns `401` with `Invalid API key`. A revoked key stays in the list, marked Revoked, so the history remains readable. It cannot be re-enabled.

## Rotate a key safely

There is no in-place rotation. Rotating a key means replacing it.

### Create the replacement

Create a new key of the same type in the same environment. Apply the same restrictions.

### Deploy it

Update your secrets manager or client configuration, and release. For a publishable key in a mobile app, wait until the versions carrying the old key are no longer in use.

### Confirm the old key is idle

Watch the **Last used** column for the old key. When it stops moving, nothing is using it.

### Revoke the old key

Revoke it. Any caller still using it starts receiving `401`.

If a secret key may have been exposed, reverse the order: revoke it first, then deploy the replacement. A short outage is better than a leaked key that can read personal data.

## What is recorded

Creating a key, revoking a key and changing restrictions are written to the [audit log](/get-started/console/audit-logs) as `api_key.created`, `api_key.revoked` and `api_key.restrictions_updated`. The entry holds the key name, type, environment and prefix, never the key itself. Toden also sends the `api_key.created` and `api_key.revoked` [webhook events](/integrate/webhooks/overview).

## Related

* [Authentication](/get-started/authentication)
* [Environments](/get-started/environments)
* [Roles and permissions](/get-started/console/roles-permissions)
* [Errors](/get-started/errors)