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

# Authentication

> Authenticate API requests with workspace-scoped Bearer tokens

The Clarky API uses **Bearer token** authentication. Every request must include an `Authorization` header containing a valid API key.

```bash theme={null}
Authorization: Bearer ck_live_example
```

Requests without a valid key — or with a key that has been revoked — return `401 Unauthorized`.

<Info>
  **Plan availability:** Creating API keys requires a **Standard**, **Pro**, or **Enterprise** plan. See [Plans & Billing](/features/settings/plans).
</Info>

## Creating an API key

<Steps>
  <Step title="Open Workspace Settings">
    Go to **Settings > API Keys** (under the Workspace Settings section).
  </Step>

  <Step title="Click 'Create API Key'">
    Give the key a descriptive name — for example, "Production data warehouse" or "Zapier sync" — so it's easy to identify later.
  </Step>

  <Step title="Choose the scopes">
    Select **read**, **write**, or both. A key without `write` cannot create, update, or delete records.
  </Step>

  <Step title="Copy the key immediately">
    The full key is shown **only once**, right after you create it. Store it in a secure secret manager. If you lose it, revoke the key and create a new one.
  </Step>
</Steps>

## Key format

Every Clarky API key follows the same shape:

```
ck_live_<random>
```

Keys are 38–39 characters total and prefixed with `ck_live_` so they're easy to recognize in logs and source control scans.

## Workspace scope

Every key is bound to **exactly one workspace**. The workspace is determined by which workspace you were viewing when the key was created. A key cannot be transferred across workspaces — to access a different workspace, create a new key from inside that workspace.

## Scopes

Scopes are selected when the key is created. Two scopes are currently available:

<ResponseField name="read" type="scope">
  Allows `GET` and `HEAD` requests on every endpoint.
</ResponseField>

<ResponseField name="write" type="scope">
  Allows `POST`, `PATCH`, and `DELETE` requests in addition to reads. A request that requires `write` made with a read-only key returns `403 Forbidden` with code `forbidden`.
</ResponseField>

<Tip>
  For backend services that only need to push data into Clarky (for example, a lead-capture form on a marketing site), grant **write** only. For analytics workloads that pull data into a warehouse, grant **read** only. Use the principle of least privilege.
</Tip>

## Sending the header

<CodeGroup>
  ```bash curl theme={null}
  curl https://clarky.ai/api/v1/contacts \
    -H "Authorization: Bearer ck_live_example"
  ```

  ```javascript Node.js theme={null}
  const res = await fetch("https://clarky.ai/api/v1/contacts", {
    headers: {
      Authorization: `Bearer ${process.env.CLARKY_API_KEY}`,
    },
  });
  ```

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

  res = requests.get(
      "https://clarky.ai/api/v1/contacts",
      headers={"Authorization": f"Bearer {os.environ['CLARKY_API_KEY']}"}
  )
  ```
</CodeGroup>

## Rotating keys

To rotate a key without downtime:

<Steps>
  <Step title="Create a new key">
    Create a fresh key with the same scopes from **Settings > API Keys**.
  </Step>

  <Step title="Roll it out">
    Update your application's secret store and deploy. Verify the new key is working in production.
  </Step>

  <Step title="Revoke the old key">
    Once nothing depends on the old key, revoke it from the API Keys list. Revocation takes effect immediately.
  </Step>
</Steps>

## Revoking a key

You can revoke any key at any time from **Settings > API Keys**. Revocation is **immediate and permanent** — every subsequent request using that key will return `401 Unauthorized`. The key cannot be re-enabled.

<Warning>
  If a key is leaked — committed to a public repo, posted in a Slack message, or pasted into a screenshot — revoke it immediately and create a new one. There's no way to "expire" a leaked key while keeping it usable.
</Warning>

## Security best practices

* **Never commit keys to source control.** Use a secret manager (AWS Secrets Manager, GCP Secret Manager, Doppler, 1Password, etc.) and load them at runtime.
* **Use environment variables** for local development — never hardcode keys.
* **Restrict by scope.** A read-only key cannot accidentally delete data even if it's compromised.
* **Use one key per integration** so you can rotate or revoke them independently.
* **Audit regularly.** Review your API key list quarterly and delete any that are no longer in use.
* **Don't expose keys client-side.** API keys must only ever be used from a trusted backend. They should never be embedded in browser JavaScript, mobile apps, or anywhere an end user could read them.

<Check>
  You're authenticated and ready to make requests. Continue to [Errors](/api-reference/errors) to learn the error envelope, or jump straight to [Contacts](/api-reference/contacts).
</Check>
