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

# Youverify API Authentication: Keys, Environments, Headers

> Learn how to obtain your Youverify API key, pass it in the token header, and correctly target the sandbox or production environment for every call.

Every request to the Youverify API is authenticated with a single secret key passed in the `token` header — there is no OAuth handshake, no session cookie, and no bearer prefix. Possession of the key is authority, so keeping it server-side and out of client code is the single most important security step you can take.

## Credential types

Youverify issues two distinct credentials per workspace environment. They serve different purposes and must never be swapped.

<CardGroup cols={2}>
  <Card title="API Secret Key" icon="key">
    Used for all **server-to-server** API calls. Pass it in the `token` header. Never expose this key in a browser, mobile app, or public repository — anyone who holds it can act on your workspace.
  </Card>

  <Card title="Public Merchant Key" icon="globe">
    Safe to embed in **web and mobile SDKs** or hosted flows. Scoped only to starting liveness and document-capture sessions. It cannot create entities, retrieve profiles, or trigger verifications.
  </Card>
</CardGroup>

| Credential | Where used | Header / field | Can read entities? |
| - | - | - | - |
| API Secret Key | Backend / server | `token` header | ✅ Yes |
| Public Merchant Key | Frontend / SDK | SDK initialisation | ❌ No |

<Warning>
  Never include your API Secret Key in client-side JavaScript, Android/iOS app bundles, or any code that ships to end users. If you suspect a secret key has been compromised, rotate it immediately in your workspace settings.
</Warning>

## The `token` header

Pass your secret key as the value of the `token` header on every server-to-server request. There is no `Bearer` prefix — the value is the raw key string.

```http theme={null}
POST /v2/api/entities HTTP/1.1
Host: api.sandbox.youverify.co
token: YOUR_SECRET_KEY
Content-Type: application/json
```

A minimal cURL example:

```bash theme={null}
curl -X GET "https://api.sandbox.youverify.co/v2/api/entities/ent_685c73c8519d82bd21a42fae" \
  -H "token: $YV_SECRET_KEY" \
  -H "Content-Type: application/json"
```

<Tip>
  Store your key in an environment variable (`YV_SECRET_KEY`) rather than hard-coding it. This keeps the key out of version control and makes rotating credentials straightforward.
</Tip>

## Environments

Youverify operates two completely independent environments. Each has its own base URL and its own set of API credentials. A key from one environment is rejected by the other.

| Environment | Base URL | Purpose | Data | Billing |
| - | - | - | - | - |
| **Sandbox** | `https://api.sandbox.youverify.co` | Integration & testing | Synthetic test data | Free — never billed |
| **Production** | `https://api.youverify.co` | Live checks | Authoritative government sources | Billed per check |

Use sandbox throughout development and integration testing. Switch to production only when you are ready to process real subjects.

<Warning>
  Do not mix environments. Using a sandbox key against the production URL (or vice versa) returns a `401 Unauthorized` error. Entities and data created in sandbox never appear in production.
</Warning>

## Where to find your keys

Your API keys live in your Youverify workspace settings:

<Steps>
  <Step title="Open your workspace">
    Log in at [cowork.youverify.co](https://cowork.youverify.co).
  </Step>

  <Step title="Navigate to Settings → API Keys">
    In the sidebar, go to **Settings**, then select the **API Keys** tab.
  </Step>

  <Step title="Select the correct environment">
    Use the environment selector at the top of the page to toggle between **Sandbox** and **Production**. Each environment shows its own distinct key pair.
  </Step>

  <Step title="Copy and store securely">
    Click **Copy** next to the API Secret Key and store it in a secrets manager, `.env` file (excluded from source control), or your deployment platform's environment variables.
  </Step>
</Steps>

## Authenticated request examples

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST "https://api.sandbox.youverify.co/v2/api/entities" \
    -H "token: $YV_SECRET_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "entityType": "individual",
      "isSubjectConsent": true,
      "firstName": "Jane",
      "lastName": "Doe",
      "email": "jane@example.com"
    }'
  ```

  ```javascript Node.js theme={null}
  const response = await fetch(
    "https://api.sandbox.youverify.co/v2/api/entities",
    {
      method: "POST",
      headers: {
        token: process.env.YV_SECRET_KEY, // ← token header, no "Bearer" prefix
        "Content-Type": "application/json",
      },
      body: JSON.stringify({
        entityType: "individual",
        isSubjectConsent: true,
        firstName: "Jane",
        lastName: "Doe",
        email: "jane@example.com",
      }),
    }
  );
  ```

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

  headers = {
      "token": os.environ["YV_SECRET_KEY"],   # ← token header, no "Bearer" prefix
      "Content-Type": "application/json",
  }

  response = requests.post(
      "https://api.sandbox.youverify.co/v2/api/entities",
      headers=headers,
      json={
          "entityType": "individual",
          "isSubjectConsent": True,
          "firstName": "Jane",
          "lastName": "Doe",
          "email": "jane@example.com",
      },
  )
  ```
</CodeGroup>

## Authentication errors

When authentication fails, the API returns a standard error envelope with a machine-readable `name` field. The two most common authentication-related errors are:

<AccordionGroup>
  <Accordion title="401 Unauthorized — invalid or missing key">
    Your request arrived without a `token` header, or the key value is incorrect (wrong key, extra whitespace, or a production key against sandbox).

    ```json theme={null}
    {
      "success": false,
      "statusCode": 401,
      "name": "UnauthorizedError",
      "message": "Invalid or missing API key. Provide your secret key in the token header."
    }
    ```

    **Fix:** Confirm the `token` header is present, that the key value matches what is shown in your workspace settings, and that you are using the correct environment's key against the correct base URL.
  </Accordion>

  <Accordion title="403 Forbidden — insufficient scope">
    Your key is valid, but it does not have permission to perform the requested action. This typically happens when a Public Merchant Key is used on an endpoint that requires a secret key.

    ```json theme={null}
    {
      "success": false,
      "statusCode": 403,
      "name": "ForbiddenError",
      "message": "You do not have permission to access this resource."
    }
    ```

    **Fix:** Ensure you are using the API Secret Key (not the Public Merchant Key) for server-side operations. If you have multiple roles or restricted workspace permissions, contact your workspace admin.
  </Accordion>
</AccordionGroup>

## Security best practices

* **Rotate keys regularly.** Generate a new key in workspace settings and update your deployment before retiring the old one.
* **Use environment variables.** Never commit keys to Git, even in private repositories.
* **Scope access.** Use the Public Merchant Key for any client-facing flow. Reserve the secret key exclusively for your backend.
* **Monitor usage.** Review API activity logs in your workspace dashboard to detect unexpected usage patterns early.
