# Errors and rate limits

> Index of the TerraLab docs for agents: [llms.txt](https://terra-lab.ai/docs/llms.txt). Every docs page is also served as markdown: add .md to its URL.

Errors come as JSON with a stable `error` code and a `message` written for a person:

```json
{ "error": "auth_required", "message": "This tool needs a TerraLab account. Connect TerraLab in your assistant's settings; see https://terra-lab.ai/mcp." }
```

Branch on `error`, never on `message`: the wording can change.

## HTTP errors

| Status | `error` | Meaning | What to do |
| --- | --- | --- | --- |
| 400 | `invalid_input` | The body is not a JSON object of the tool arguments. | Fix the request body. |
| 400 | `bad_request` | The request could not be read. | Check the JSON and the headers. |
| 401 | `auth_required` | No key or token was sent. | Send `Authorization: Bearer <key>`. |
| 401 | `invalid_token` | The key or token is invalid, revoked or expired. | Create a new key, or let the agent sign in again. |
| 401 | `access_revoked` | The app was disconnected from the dashboard. | Reconnect the agent. |
| 402 | `balance_required` | The free calls of the month are used, or the operation is paid, and the balance is empty. | Add funds; the answer carries `hint` and `account_url`. |
| 404 | `not_found` | There is no such API path. | Check the URL. |
| 404 | `unknown_tool` | No tool has that name. | List tools with `GET /v1/tools`. |
| 405 | `method_not_allowed` | Tools are called with `POST`. | Use `POST`. |
| 413 | `too_large` | The request body is too large. | Send a smaller file or fewer features. |
| 429 | `rate_limited` | Too many requests in the last minute. | Wait for `Retry-After` seconds, then retry. |
| 429 | `daily_limit` | The account reached its daily safety ceiling. | Retry the next day (UTC) or write to support. |
| 503 | `unavailable` | The account service did not answer. | Retry after `Retry-After` seconds. |

## Tool errors

A tool that runs but cannot answer returns `200` with `isError: true`. Its `structuredContent` then carries `code`, `message` and, most of the time, a `hint` saying what to change: a place it could not find, an area too large, a country it does not cover.

```json
{
  "structuredContent": { "code": "...", "message": "...", "hint": "..." },
  "content": [{ "type": "text", "text": "..." }],
  "isError": true
}
```

## What is counted

A call that fails or finds nothing is not counted: the free call or the amount taken from the balance is given back. Only answers with a result count.

## Rate limits

Every account can make 60 calls a minute. Past it, the API answers `429` with `Retry-After: 60`. Spread batch jobs over time, and retry with a growing delay:

```python
import time
import requests

def call(url, headers, body, attempts=5):
    for attempt in range(attempts):
        response = requests.post(url, headers=headers, json=body, timeout=120)
        if response.status_code not in (429, 503):
            return response
        time.sleep(int(response.headers.get("Retry-After", 2 ** attempt)))
    return response
```

Retry only `429` and `503`. A `401` or `402` will not pass on a second try.

Source: https://terra-lab.ai/docs/errors · Updated 2026-10-27
