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

# HTTP conventions

> Authentication, errors, pagination, retries and asynchronous command behavior.

<Warning>The hosted catalog returned HTTP 404 on 2026-09-14T01:46:46.905Z. Generic command calls and the CLI tools/call surface require a release that serves these endpoints. The contract below describes current source; use a released resource route or MCP operation where available. See [capability status](/capability-status).</Warning>

The hosted API origin is `https://app.agentlinkops.com`. Shared cloud operations use `POST /v1/commands/{name}`. Read the authenticated catalog with `GET /v1/commands`.

```bash theme={null}
curl --fail-with-body https://app.agentlinkops.com/v1/commands/get_workspace \
  -H "Authorization: Bearer $LINKTRAIL_TOKEN" \
  -H 'Content-Type: application/json' \
  --data '{}'
```

## Request contract

Send a scoped bearer credential in `Authorization`. Optional `X-Workspace-ID` must match that credential's workspace. Human browser sessions use their own workspace selection and membership checks. A browser Origin must match the API's configured public origin. See [human access](/reference/http/account-access).

JSON bodies must be objects, UTF-8, with `Content-Type: application/json`. The request cap is 256 KiB and body-read timeout is ten seconds. The generic command catalog accepts no query string. Generic command calls reject query parameters and the `Idempotency-Key` header: put every argument, including `idempotencyKey`, in the body.

A successful generic call returns the operation's JSON result directly, with HTTP 200 and `Cache-Control: no-store`. It does not add a data envelope. Resource-route statuses and raw-evidence download behavior appear in the [route index](/reference/http/routes).

## Errors

```json theme={null}
{"error":{"code":"INSUFFICIENT_SCOPE","message":"Access requires watches:read.","details":{"scope":"watches:read"}}}
```

| HTTP status | Meaning and recovery                                                                       |
| ----------- | ------------------------------------------------------------------------------------------ |
| 400         | Invalid JSON/arguments or incompatible resource state; inspect error.code and details      |
| 401         | Missing, expired or revoked credential; reconnect or supply valid access                   |
| 403         | Scope, workspace, role, project or browser-origin denial; obtain appropriate access        |
| 404         | Resource/route absent or inaccessible under the selected identity                          |
| 408         | Request body timed out; retry a bounded body                                               |
| 409         | Conflict, stale revision or existing operation; inspect the specific error details         |
| 410         | Expired evidence or cursor; recover according to the operation, preserving unknown history |
| 413         | Body exceeds 256 KiB; split the request within operation limits                            |
| 415         | Send application/json                                                                      |
| 429         | Rate or usage limit; respect returned retry guidance and avoid immediate loops             |
| 5xx         | Server/request failure; error messages are masked and details omitted                      |

The operation page lists its source-derived error codes. Permission denial and disabled supplier admission are not fixed by repeated requests.

## Pagination and retained history

Use an operation's documented `cursor` and `limit`. Store returned cursors unchanged; do not construct or edit them. Keep cursors bound to the same workspace, filters and feed. Follow `next_cursor` until the page says there is no continuation. Event feeds retain a checkpoint in next\_cursor even when has\_more is false; stop paging when has\_more is false and save that checkpoint for the next poll. Not every list uses identical pagination: member lists and the command catalog are not cursor feeds.

Placement `events` and `target_events` have independent sequence spaces. Keep two checkpoints. On `CURSOR_EXPIRED`, preserve the gap, fetch the instructed snapshot and resume from the supplied cursor. A snapshot restores current state; it does not recover expired events. `EVIDENCE_EXPIRED` means raw bytes are unavailable, while retained observation metadata may still be readable.

## Asynchronous work and retries

An accepted job means work was queued. Poll its documented job/run/batch reader until the returned state is terminal. Read observations and errors from that result before reporting success. Local source coverage does not prove a hosted supplier is admitted.

For operations that accept `idempotencyKey`, reuse the same value and the same arguments when retrying an uncertain write. Resource aliases take that value in the `Idempotency-Key` header where listed. Do not invent that argument for other commands. Read current state before repeating a write without an idempotency contract.

The local cloud client uses a 30-second request timeout, rejects redirects and performs no general automatic retry. Sync owns its cursor recovery. Webhook dispatch has a separate [delivery retry contract](/reference/webhooks).

<Note>Reference follows the current development CLI and HTTP contracts. Hosted availability depends on the selected environment. See [capability status](/capability-status).</Note>
