# Errors

Every Clikso API error has a status, a stable code and a message. This page lists every code an API key can get, what it means, and what to do next.

> **In short:**
>
> When a request fails, you get an HTTP status and a JSON body with an `error.code`, such as `VALIDATION_ERROR`. Check the code in your program, not the message. Some errors are worth a retry; most mean you need to fix the request.

## What an error looks like

Every error has the same shape. `success` is `false`, and the `error` object holds the details.

* `status` — the HTTP status, repeated in the body.
* `error.code` — a fixed name for the problem. Your code can rely on it.
* `error.message` — a sentence for people. Its words may change, so do not match on it.
* `error.details` — extra facts. Only some errors send it, and its shape depends on the code.

## Every error code

| Status | Code                         | What it means                                                                                                                                                                                 | What to do                                                                                                                |
| ------ | ---------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------- |
| 401    | `UNAUTHORIZED`               | The key is missing, malformed or unknown, or the account that made it no longer exists.                                                                                                       | Send `Authorization: Bearer clik_live_…` with a key from Settings → API.                                                  |
| 401    | `API_KEY_REVOKED`            | Someone revoked this key in Settings → API.                                                                                                                                                   | Create a new key and replace the old one.                                                                                 |
| 401    | `API_KEY_EXPIRED`            | The key is past its expiry date.                                                                                                                                                              | Create a new key.                                                                                                         |
| 402    | `UPGRADE_REQUIRED`           | The request uses a feature your plan does not include, or adds a folder or tag past your plan’s count. `error.details` names the `feature`, the `field` and the `required_plan`.              | Leave the field out, or upgrade the workspace.                                                                            |
| 402    | `WORKSPACE_PAYMENT_REQUIRED` | The workspace is waiting for its first payment. Until then only reading the workspace (bootstrap and usage) works.                                                                            | Finish the payment in the Clikso dashboard. Do not retry until it has gone through.                                       |
| 402    | `WORKSPACE_PAUSED`           | The workspace is read-only (paused): it is not the account’s default and has no active paid plan. Reads and the analytics reads still work; changes do not. Its short links keep redirecting. | Add a paid plan for the workspace in the Clikso dashboard, or make it your default workspace there. Reads need no change. |
| 403    | `FORBIDDEN`                  | The key’s permission or role is too low for this action, the `Workspace-Id` header names a different workspace, or the key’s creator is no longer a member.                                   | Check the key’s permission and your role. If you send `Workspace-Id`, it must match the key’s workspace.                  |
| 403    | `API_KEY_NOT_ALLOWED`        | This endpoint does not accept API keys at all (for example billing, members, API keys or revealing a link password).                                                                          | Use only the endpoints in the API reference.                                                                              |
| 403    | `ACCOUNT_BANNED`             | The account that created the key is suspended.                                                                                                                                                | Contact support. A new key will not help.                                                                                 |
| 403    | `EMAIL_NOT_VERIFIED`         | The account that created the key has not verified its email address.                                                                                                                          | Sign in to the dashboard and verify the email.                                                                            |
| 404    | `NOT_FOUND`                  | The link, folder, tag or domain does not exist in this key’s workspace (or was deleted).                                                                                                      | Check the id. Ids from another workspace are never found.                                                                 |
| 409    | `CONFLICT`                   | The short code is already taken on that domain. Also returned when you try to delete a link that was banned for abuse.                                                                        | Pick another `short_code`, or leave it out to get a random one.                                                           |
| 422    | `VALIDATION_ERROR`           | A field is missing or invalid. `error.message` says which; `error.details.field` may name it, or `error.details` may map field names to messages.                                             | Fix the field and send the request again.                                                                                 |
| 422    | `DESTINATION_BLOCKED`        | The destination URL is not allowed: another link shortener, or a domain on Clikso’s blocklist.                                                                                                | Show `error.message` to the user as it is. Do not retry.                                                                  |
| 429    | `RATE_LIMITED`               | Too many requests in one minute — for this key, or for this workspace’s analytics or AI slug quota.                                                                                           | Wait the number of seconds in the `Retry-After` header, then try again.                                                   |
| 429    | `USAGE_LIMIT_REACHED`        | A plan quota is used up: links this month, AI slugs today, or analytics requests today.                                                                                                       | Wait for the reset (analytics sends `details.resets_at`) or upgrade.                                                      |
| 500    | `INTERNAL_ERROR`             | Something failed on Clikso’s side.                                                                                                                                                            | Retry with a growing delay. If it keeps failing, contact support.                                                         |

## Errors with details

### VALIDATION_ERROR

`error.message` names the first problem. Is a value too long, or not a date? Then `details.field` holds the field's name, such as `title` or `expires_at`. For some fields, `error.details` maps each field name to its message instead. Tracking ids are one example:

Show each message next to the field it names. If there are no details, show `error.message`.

### DESTINATION_BLOCKED

The destination URL is another link shortener, or a site on Clikso's blocklist. Every URL in the request is checked, including A/B, country and device URLs. Show `error.message` to the person as it is: it explains which URL was refused. Do not retry the same URL.

### UPGRADE_REQUIRED

You set a field your plan does not include, such as country rules on Free. `error.details` says which feature, which field, the lowest plan that has it, and your current plan.

On an update, you can always send a value the link already has, or clear a field. Only a new or changed value is checked.

Adding a folder or tag past your plan's count also returns `402`. Then `details.feature` is `folders` or `tags`, `details.field` is `null`, and `details.limit` and `details.current` give the count.

### WORKSPACE_PAYMENT_REQUIRED and WORKSPACE_PAUSED

Every account has one default workspace that's free forever. Each extra workspace needs its own paid plan, and it waits for its first payment before it can be used. An extra workspace is paused (read-only) when its paid plan ends, or when it stops being the default without a paid plan. Both answer with `402` and say which state the workspace is in:

* **WORKSPACE_PAYMENT_REQUIRED** — the workspace is waiting for its first payment. Only reading the workspace works ([Get workspace details](https://clik.so/docs/api/workspace/get-bootstrap) and [Get usage](https://clik.so/docs/api/workspace/get-usage)). Finish the payment in the dashboard.
* **WORKSPACE_PAUSED** — the workspace is read-only. It is not the account's default and has no active paid plan. Reads and the click analytics still work, and the short links keep redirecting. Changes need a paid plan, or the owner can make it their default workspace in the dashboard.

`workspaces[].access_state` in [Get workspace details](https://clik.so/docs/api/workspace/get-bootstrap) tells you the state before you hit either error: `null` for a normal workspace. `workspaces[].is_default` is `true` when the workspace is its owner's default, which is never paused. It is the owner's flag: a member's API key sees the same value.

### USAGE_LIMIT_REACHED

A plan allowance is used up. For the analytics API, `error.details.resets_at` says when the daily count starts again, at midnight UTC.

The monthly link allowance and the daily AI slug allowance send the same code, without `details`. The [Limits](https://clik.so/docs/limits) page lists every allowance.

## When to retry

* **429 RATE_LIMITED** — wait the number of seconds in the `Retry-After` header, then send the same request again.
* **429 USAGE_LIMIT_REACHED** — do not retry right away. Wait until the allowance resets, or upgrade.
* **500 INTERNAL_ERROR** — retry after a short wait. Double the wait each time, and stop after a few tries.
* **Network errors** — retry like a `500`. For a create, list your links first, so you do not make the same link twice.
* **Any other 4xx** — do not retry. The same request will fail the same way. Fix it first.

## Good to know

* `403 API_KEY_NOT_ALLOWED` is a bug in your code, not a key problem. Check that the endpoint is in the [API reference](https://clik.so/docs/api).
* A `404` for an id from another workspace is on purpose. The API never says whether that id exists elsewhere.
* Each [API reference](https://clik.so/docs/api) page lists the errors that endpoint can send.

---

Source: https://clik.so/docs/errors
