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

# Pagination, errors & rate limits

> The list envelope, the error envelope, and how rate limiting behaves.

## Pagination

List endpoints take two query parameters and return a consistent envelope:

| Param    | Meaning                                      | Default                        |
| -------- | -------------------------------------------- | ------------------------------ |
| `offset` | Zero-based index of the first item to return | `0`                            |
| `top`    | Maximum number of items to return            | `100` (connections list: `25`) |

```json theme={null}
{
  "items": [ ... ],
  "totalCount": 137,
  "offset": 0,
  "top": 100
}
```

All four fields are always present. Page until `offset + items.length >= totalCount`. Both SDKs auto-paginate internally - their `list`-style methods return the complete array.

## Error envelope

Every non-200 response carries the same JSON body:

```json theme={null}
{
  "errorCode": "VALIDATION_ERROR",
  "message": "Human-readable error message.",
  "requestId": "0HN0...",
  "timestamp": "2026-08-12T10:00:00Z",
  "path": "/v1/tools/monday_create_item/execute",
  "details": [
    { "field": "fields.name", "issue": "Required field is missing." }
  ]
}
```

`details` appears only on field-level validation failures (`400`, `errorCode: "VALIDATION_ERROR"`).

| Status | Meaning                                                                     |
| ------ | --------------------------------------------------------------------------- |
| 400    | Bad request - malformed body or invalid parameters                          |
| 401    | Unauthorized - missing or invalid credentials                               |
| 403    | Forbidden - the caller lacks access to the resource                         |
| 404    | Not found - the resource does not exist                                     |
| 409    | Conflict - e.g. no default connection configured for the tool's application |
| 429    | Too many requests - rate limit exceeded                                     |
| 500    | Internal server error - include `requestId` when reporting                  |

<Note>
  `POST /v1/tools/{toolSlug}/execute` is special: **tool-runtime** failures (the downstream API errored) return `200` with `isSuccess: false` and an `errorMessage` - not the error envelope. Branch on `isSuccess`, not just the HTTP status.
</Note>

## Rate limits

Limits are enforced **per account** with two budgets that must both pass: a per-second burst and a sustained hourly window. Search-backed discovery calls (`GET /v1/tools` or `GET /v1/applications` with a non-empty `?search=`) have their own, stricter budget because they trigger semantic search.

On `429`, honor the `Retry-After` response header (seconds): `1` when the burst window tripped, `3600` when the hourly window tripped. Back off and retry - don't hammer.
