> ## Documentation Index
> Fetch the complete documentation index at: https://eurusys-6c0957fa.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# API keys & secrets

> Create, rotate, and revoke the credentials your SDK integrations use to authenticate with the Validation Gateway.

An **API key** is how an SDK integration proves which organization it belongs to. Each key has two parts:

* **Key ID** — a non-secret identifier. It is embedded in your SDK config as `apiKeyId` and is always visible in the dashboard.
* **Key secret** — a high-entropy secret used to sign JWTs. It is shown **exactly once**, at creation, and never again.

<Warning>
  The key secret is shown only once. If you lose it, you cannot recover it — you must **regenerate** the key, which immediately invalidates the previous secret. Store it in a secret manager (Vault, AWS Secrets Manager, etc.), never in source control or client-side code.
</Warning>

## How the SDK uses the key

The SDK is configured with the **key ID** only. When it needs to authenticate, it builds a JWT (`header.payload`) and asks your **token signer** to sign it. Your signer — running where the secret lives — computes `HMAC-SHA256(header.payload, keySecret)` and returns the signature.

```
JWT header:  { "alg": "HS256", "typ": "JWT" }
JWT payload: { "key_id": "<your key ID>", "fingerprint": "<device fingerprint>" }
signature:   HMAC-SHA256( base64url(header) + "." + base64url(payload), keySecret )
```

This means the secret never enters the SDK or the user's device. See [Authentication](/concepts/authentication) for the signer contract in each language.

## Lifecycle

<Info>
  Creating and revoking keys requires the **Org Root User** role. Org Users have read-only access to the keys list.
</Info>

<Steps>
  <Step title="Create">
    In **Operations → API Keys**, click **Create API Key**, give it a name (e.g. *Production SDK*), and select the [methods](/dashboard/methods) it may call. On submit, the portal shows the **key ID** and **key secret** once — copy the secret immediately, or use **Download CSV** to save the key details to a file.
  </Step>

  <Step title="Scope to methods">
    A key can only invoke the methods you selected for it, drawn from the methods enabled for your organization. Scope each key to just what its integration needs.
  </Step>

  <Step title="Rotate / regenerate">
    Issue a new key and **revoke** the old one to rotate. Plan a brief overlap: deploy the new secret to your signer before revoking the old key, or expect in-flight requests on the old secret to start failing with an auth error.
  </Step>

  <Step title="Revoke">
    Revoking a key sets it inactive immediately and cannot be undone. The backend rejects any JWT signed with a revoked key with an authentication error (see [`backend` error codes](/reference/error-codes)), and any SDK integration using it stops working.
  </Step>
</Steps>

## Good practice

| Practice                | Why                                                                        |
| ----------------------- | -------------------------------------------------------------------------- |
| One key per environment | Keep sandbox and production isolated; revoke independently.                |
| Sign on the server      | Never ship the secret to a device or browser — only the signer touches it. |
| Rotate on staff changes | Regenerate when someone with access to the secret leaves.                  |
| Scope methods narrowly  | Enable only the methods a key actually needs.                              |

<Info>
  Key creation, regeneration, and revocation are all audit-logged. The secret value itself is never logged.
</Info>
