> For the complete documentation index, see [llms.txt](https://documentation.connexica.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://documentation.connexica.com/api/02.-using-the-api.md).

# 02. Using the API

CXAIR exposes a JSON-RPC 2.0 API through a single endpoint:

```
POST /api/v1
```

The `method` field selects the operation and `params` carries its parameters as a JSON object. Batch requests (JSON arrays) are not supported — send one request per HTTP call. Request bodies are limited to 1 MB.

## Authentication

Every request requires an API token as a bearer token:

```
Authorization: Bearer cxat_<token-value>
```

See [API Tokens](/api/01.-api-tokens.md) for creating tokens. Requirements:

* The token must be active (not revoked, not expired) and carry at least one recognised scope.
* Each method enforces its own required scope; `QUERIES.EXECUTE` and `CROSSTAB.EXECUTE` additionally need `reports:write` when `saveReport` is used.
* The token owner must resolve to a valid CXAIR user — requests run with that user's permissions.

### Authentication errors

Authentication failures are returned as HTTP errors with an RFC 7807-style body `{type, title, status, detail}` — not as JSON-RPC envelopes.

| HTTP | Detail                                    |
| ---- | ----------------------------------------- |
| 401  | Missing or invalid `Authorization` header |
| 401  | Empty bearer token                        |
| 401  | Token not found or invalid                |
| 401  | Token has been revoked                    |
| 401  | Token has expired                         |
| 401  | Token owner could not be resolved         |
| 403  | Token has no recognised scope             |

Per-method scope failures are raised later as JSON-RPC business errors (403, "Token does not have `<scope>` scope").

## Headers

| Header          | Required | Description                                               |
| --------------- | -------- | --------------------------------------------------------- |
| `Content-Type`  | Yes      | `application/json`                                        |
| `Authorization` | Yes      | `Bearer cxat_<token-value>`                               |
| `X-Request-Id`  | No       | Client request ID for tracing; echoed in `meta.requestId` |

## Request format

```json
{
  "jsonrpc": "2.0",
  "method": "QUERIES.EXECUTE",
  "params": { "index": "MyIndex", "query": "search text" },
  "id": 1
}
```

| Field     | Type   | Required | Description                                        |
| --------- | ------ | -------- | -------------------------------------------------- |
| `jsonrpc` | string | Yes      | Must be `"2.0"`                                    |
| `method`  | string | Yes      | The operation to run                               |
| `params`  | object | No       | Method parameters as a JSON object                 |
| `id`      | any    | No       | Client-supplied identifier, echoed in the response |

## Response format

Successful calls return a `result` envelope with operation `data` and a `meta` block that always includes `requestId`:

```json
{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "data": { },
    "meta": { "requestId": "uuid-or-client-id" }
  }
}
```

Business errors return `error` with an HTTP status `code`, a `message`, and `data.detail`:

```json
{
  "jsonrpc": "2.0",
  "id": 1,
  "error": {
    "code": 400,
    "message": "Bad Request",
    "data": { "type": "about:blank", "detail": "index is required" }
  }
}
```

## Error reference

Business errors use HTTP status codes: `400` invalid parameters, `401` unauthorised, `403` forbidden, `404` not found, `409` conflict, `413` body too large, `415` unsupported media type, `500` internal error.

Protocol-level errors use standard JSON-RPC codes:

| Code   | Message          | When                                                                                                      |
| ------ | ---------------- | --------------------------------------------------------------------------------------------------------- |
| -32700 | Parse error      | Invalid JSON body                                                                                         |
| -32600 | Invalid Request  | Not a JSON-RPC 2.0 object, a batch array, non-object `params`, or unsupported media type / oversized body |
| -32601 | Method not found | Unknown method name                                                                                       |
| -32603 | Internal error   | Unexpected server error                                                                                   |

For protocol errors raised before `id` can be read, the HTTP status reflects the error (400, 413, 415) and `id` is `null`. Other errors return HTTP 200 per JSON-RPC convention, with `id` echoing the request.

## Method catalogue

| Method             | Required scope  | Description                                                             |
| ------------------ | --------------- | ----------------------------------------------------------------------- |
| `QUERIES.EXECUTE`  | `query:execute` | Execute a search query; paginated results, optional `saveReport`        |
| `INDEXES.FIND`     | `indexes:read`  | Search available indexes with `searchText` filter and cursor pagination |
| `CROSSTAB.EXECUTE` | `query:execute` | Execute a crosstab; returns HTML or a base64 chart image                |
| `REPORTS.FIND`     | `reports:read`  | Search saved reports by text and type                                   |
| `REPORTS.METADATA` | `reports:read`  | Load a saved report's executable metadata by GUID                       |

See [Method Reference](/api/03.-method-reference.md) for parameters and results, and [Examples](/api/04.-examples.md) for complete requests.
