# Keep your API key safe

A Clikso API key acts as the person who made it, in one workspace. Keep it on a server, give it only the access it needs, and revoke it if it leaks.

> **In short:**
>
> An API key acts as the person who made it, in one workspace. Keep it on a server, give it the least access it needs, and use one key per app. If a key leaks, revoke it in Settings → API at once.

## You need

* **A role:** Admin in the workspace. Only admins can create, revoke and delete keys.
* **A place:** Settings → API in the [Clikso dashboard](https://app.clik.so).
* **A plan:** Any plan, including Free.

## Keep keys out of your code

Store each key in an environment variable or a secrets manager. Your code then reads it at run time. Every example in these docs does this with `CLIKSO_API_KEY`.

```bash title="Set the key for one terminal session"
export CLIKSO_API_KEY="clik_live_your_key_here"
```

Never put a key in these places:

* **A web page or a browser extension you ship.** Anyone can open the source and read it. The API does not allow browser calls from other sites anyway, so call it from your server.
* **A mobile app.** Keys can be pulled out of an app file.
* **A git repository**, even a private one. Add your `.env` file to `.gitignore`.
* **Chat messages, tickets or logs.** Paste the key preview, not the key.

Every key starts with `clik_live_`. That makes it easy to search your own code, logs and files for keys that slipped in.

## Give each key only what it needs

Pick the lowest permission that does the job:

* **Read** — find links, folders, tags and domains, and read analytics. Best for reports and dashboards.
* **Write** — everything in Read, plus create, change and delete links, folders and tags.
* **Admin** — the same as Write for the API today. Pick Write instead.

A key can never do more than the person who made it. If that person is a viewer, even a Write key can only read.

## Use one key per app

Make a separate key for each script, server or service. Name it after the app, so you know what breaks if you revoke it. Names can be up to 30 characters.

With one key per app, a leak in one place means you replace one key, not all of them.

| Limit                                           | Free | Starter | Pro | Business |
| ----------------------------------------------- | ---- | ------- | --- | -------- |
| API keys (Per workspace, revoked keys excluded) | 3    | 10      | 20  | 30       |

Revoked keys do not count toward this limit. Keys held by the Clikso browser extension (one per connected browser) do.

## Replace a key without downtime

### Step 1. Make a new key

In Settings → API, press **Generate New Key**. Give it the same permission as the old one. Copy it now, because Clikso shows it only once.

### Step 2. Switch your app to the new key

Update the environment variable or secret, and deploy. Check that your app's requests still work.

### Step 3. Revoke the old key

Back in Settings → API, revoke the old key. Requests that still use it now get `401 API_KEY_REVOKED`.

If you are at your plan's key limit, revoke the old key first, then make the new one. Expect a short gap while you deploy.

## If a key leaks

1. Revoke it in Settings → API right away. It stops working on the next request.
2. Make a new key and deploy it, as in the steps above.
3. Look for links and destinations you did not set. [List links](https://clik.so/docs/api/links/list-links) shows the newest links first.

Revoking is safe. It never touches your links, folders or tags.

## Choose who creates the key

A key acts as the person who made it. If that person leaves the workspace, the key stops working with `403 FORBIDDEN`. If their role drops, the key's access drops too.

So make long-lived keys from an admin account that will stay in the workspace.

## Guard against the wrong workspace

A key belongs to one workspace. You can also send a `Workspace-Id` header with your workspace's id. If it does not match the key, Clikso refuses the request with `403 FORBIDDEN` instead of changing the wrong workspace.

To find the id, read `workspace_id` from [Get usage](https://clik.so/docs/api/workspace/get-usage):

```bash
curl "https://app.clik.so/api/workspace/usage" \
  -H "Authorization: Bearer $CLIKSO_API_KEY"
```

Response 200:

```json
{
  "status": 200,
  "success": true,
  "message": "Success",
  "data": {
    "workspace_id": "8a1f2c3d-4b5e-4f60-9a7b-1c2d3e4f5a6b",
    "links_created_this_month": 42,
    "clicks_this_month": 1873,
    "ai_analytics_today": 0,
    "ai_slug_gens_today": 3,
    "last_reset_ai": "2026-10-09",
    "last_reset_monthly": "2026-10-01",
    "next_reset": "2026-11-01T00:00:00.000Z",
    "updated_at": "2026-10-09T09:30:00.000Z",
    "plan_key": "starter",
    "plan_links_limit": 500,
    "plan_domains_limit": 2,
    "is_simulated": false
  }
}
```

## What you get back

A request with a bad key never reaches your data. You get an error with one of the codes below. A `401` means the key itself is the problem. A `403` means the key is fine but not allowed to do this.

## Common errors

| Status | Code                 | What it means                                                                                                            | What to do                                                                                               |
| ------ | -------------------- | ------------------------------------------------------------------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------- |
| 401    | `UNAUTHORIZED`       | The key is mistyped, deleted, or its creator's account is gone.                                                          | Send `Authorization: Bearer clik_live_…` with a key from Settings → API.                                 |
| 401    | `API_KEY_REVOKED`    | Someone revoked this key.                                                                                                | Make a new key in Settings → API.                                                                        |
| 403    | `FORBIDDEN`          | The `Workspace-Id` header names another workspace, the creator left the workspace, or a Read key tried to make a change. | Check the key’s permission and your role. If you send `Workspace-Id`, it must match the key’s workspace. |
| 403    | `EMAIL_NOT_VERIFIED` | The account that made the key has not verified its email.                                                                | Sign in to the dashboard and verify the email.                                                           |
| 403    | `ACCOUNT_BANNED`     | The account that made the key is suspended.                                                                              | Contact support. A new key will not help.                                                                |
| 429    | `RATE_LIMITED`       | Too many requests this minute, or too many failed key checks from your IP address.                                       | Wait the number of seconds in `Retry-After`.                                                             |

## Good to know

* Clikso shows the full key once, when you make it. After that you only see a short preview.
* Keys do not expire on their own. Revoke the ones you no longer use.
* Revoke keeps the key in your list, marked as revoked. Delete removes it from the list. Both stop it working.
* Each key can make 30 requests a minute on Free, and more on paid plans. See [Limits](https://clik.so/docs/limits).
* After 30 failed key checks in a minute from one IP address, more failed checks from it get `429 RATE_LIMITED`.
* Always call `https://app.clik.so`. Never send a key over plain `http`.

---

Source: https://clik.so/docs/guides/api-key-safety
