---
title: "Errors"
description: "Handle Lookio API failures with one error format, stable error codes, request IDs and retry guidance, with an explanation for every code."
canonical: "https://lookio.app/docs/developers/errors"
updated: "2026-11-08"
---

# Errors

All API errors use one format. Branch on `error.code`, never on the message.

```json title="Example error"
{
  "error": {
    "type": "permission_error",
    "code": "insufficient_scope",
    "message": "This credential does not have the 'resources:write' scope. Grant it at https://dashboard.lookio.app/developer on the workspace that owns the credential, or use a credential that already has it.",
    "docs_url": "https://lookio.app/docs/developers/errors#insufficient_scope"
  },
  "request_id": "req_0123456789abcdef0123456789abcdef"
}
```

| Field              | Meaning                                                                                                      |
| ------------------ | ------------------------------------------------------------------------------------------------------------ |
| `error.type`       | The family of the failure.                                                                                   |
| `error.code`       | The stable code. New codes can come without notice, so handle an unknown code by its `type` and HTTP status. |
| `error.message`    | A sentence that names the wrong value and, if possible, the fix. Do not parse it.                            |
| `error.param`      | The field at fault, when there is one.                                                                       |
| `error.docs_url`   | The explanation of the code, on this page.                                                                   |
| `error.action_url` | A link to fix it, when there is one, such as the Permissions page.                                           |
| `request_id`       | Also in the `X-Request-Id` header. Keep it in your logs.                                                     |

The error types are `invalid_request_error`, `authentication_error`, `permission_error`, `not_found_error`, `conflict_error`, `rate_limit_error` and `api_error`.

A `401` also has a `WWW-Authenticate` header, a `405` an `Allow` header and a `429` a `Retry-After` header.

> **Note**
>
> If a streamed answer fails after its first event, the error comes in an `error` event with this format, not as an HTTP status. See [Streaming](/docs/developers/streaming).

## Status codes

| Status   | Meaning                                         | What to do                            |
| -------- | ----------------------------------------------- | ------------------------------------- |
| 400      | Malformed request, unknown field, bad value     | Fix the request.                      |
| 401      | Credential missing, invalid, expired or revoked | Replace or renew it.                  |
| 402      | Not enough credits                              | Add credits, then ask again.          |
| 403      | Authenticated but not allowed                   | Grant the scope or permission.        |
| 404      | Absent, or in another workspace                 | Check the ID and the workspace.       |
| 405      | The endpoint does not accept this HTTP method   | Use a method from the `Allow` header. |
| 409      | The current state conflicts with the request    | Read the resource, then decide.       |
| 413      | Body or file too large                          | Send less.                            |
| 422      | Valid request that the plan cannot take         | Change the plan or the content.       |
| 429      | Rate limited                                    | Wait for `Retry-After`.               |
| 500, 503 | Lookio failed, or is briefly unavailable        | Retry with backoff.                   |

**Fix before retrying**

A 400, 401, 402, 403, 404, 405, 409, 413 or 422 needs a change first. The same request fails again.

**Retry safely**

Retry a 429 after `Retry-After`. Retry a 500 or 503 with exponential backoff and random jitter. Send an `Idempotency-Key` on a POST.

A resource in another workspace returns `resource_not_found`, like a resource that does not exist. The API never shows what other workspaces hold.

## Authentication codes

### authentication\_required

The request has no credential. Add the `Authorization: Bearer` header.

### invalid\_api\_key

The credential is malformed or unknown, or an OAuth token was used on a resource that it is not for. Check that you copied the whole `sk_live_...` value.

### invalid\_access\_key

The access (`/a/{access_id}`) refused the key. The key is malformed, revoked, or for another access. Or it is a workspace API key (`sk_live_...`), not an access key (`ak_live_...`). Ask the owner of the access for a key.

### api\_key\_expired

The credential expired. Create a new one.

### api\_key\_revoked

An admin revoked or rotated the key, or the person of a connection left the workspace. Use an active credential.

## Permission codes

### insufficient\_scope

The credential is valid but does not have the scope of this endpoint. The message names the scope. See [Authentication](/docs/developers/authentication#scopes).

### feature\_not\_available

The plan or the kind of credential does not include this. For example: member permissions need the Pro or Custom plan. [Thumbs on an answer](/docs/api/conversations/submit-answer-feedback) work on an API key's conversations, not yet on a person's own chats.

### admin\_required

Only a workspace admin can do this, for example rename a tag or list members. Use a personal connection of an admin.

### permission\_denied

The person of a connection does not have a Lookio permission, for example to create resources, or to use the API or MCP on the Pro or Custom plan. `action_url` links to the Permissions page. Ask a workspace admin.

## Request codes

### invalid\_request

Lookio cannot read the request. The JSON is malformed, a required value is missing, or two options exclude each other, such as `conversation_id` with `history`.

### unknown\_field

The JSON body has an unknown field. The message gives the closest valid field. Unknown _query_ parameters never cause this error: Lookio ignores them.

### invalid\_parameter

A value is not valid. `error.param` names the field. A bad `Idempotency-Key` also gives this code.

### invalid\_cursor

The `cursor` matches no resource. Start again from the first page.

### request\_too\_large

The JSON body is over 1 MB, or a file is over the limit of its format. See [File formats](/docs/guides/file-formats).

### method\_not\_allowed

The endpoint does not accept this HTTP method. The status is `405`. The `Allow` header lists the methods it accepts, for example `GET, POST` on `/v1/resources`.

## Not found and conflict codes

### resource\_not\_found

The id does not exist in this workspace, or the caller cannot see it: a resource, an assistant, a widget, a conversation, a member or a tag. A path that is not an endpoint also gives this code.

### conflict

The request is valid, but the current state forbids it. For example: an assistant still uses the resource to delete, a widget still uses the assistant to delete, a site action went to a resource that is not a site, or an `Idempotency-Key` is used for a different request or is still running. Read the state, then decide.

### assistant\_has\_no\_resources

The assistant reads no resource, so it cannot answer. Its **Chosen resources** list is empty, its tags match no resource, it reads **All resources** in an empty workspace, or no resource is `ready` yet. Lookio refuses the question before any model runs, so it is free. The status is `409`. Give the assistant resources, or wait until they are ready, then ask again.

## Credit and plan codes

### insufficient\_credits

The balance is lower than the price of the mode. Add credits, then ask again. The status is `402`. `error.action_url` links to the pricing page.

### request\_too\_large\_for\_plan

This content would pass a limit of your plan: words stored, or pages read this month (PDF pages, slides, images, web pages). The message says which. Delete resources, buy extra pages on **Billing**, or change plan. See [Word allowance](/docs/guides/resources#word-allowance) and [Pages read each month](/docs/guides/resources#pages-read-each-month).

## Rate limit code

### rate\_limited

Too many requests. Wait for the number of seconds in `Retry-After`. See [Rate limits](/docs/developers/rate-limits).

## Server codes

### internal\_error

Lookio failed. Retry with backoff. If it continues, contact support with the `request_id`.

### service\_unavailable

A part of Lookio is not available: the engine, the file storage, or maintenance. Retry with backoff.
