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

# Management API

> Programmatic management for administrators

The Management API gives your organization programmatic, read-only access to
its own gateway activity. It is authenticated by a dedicated **management
key** — a separate key type that cannot run inference.

## Management keys

Each organization gets **one** management key, issued by Consus on request
(contact [sales@consusindustries.co](mailto:sales@consusindustries.co)). It
uses the same `x-api-key` header and rate limits as your other keys, but:

* It is **read-only**: `GET /v1/logs` is the only endpoint it can call. Every
  other endpoint — including all inference endpoints
  (`/v1/chat/completions`, `/v1/messages`, `/v1/messages/count_tokens`,
  `/v1/responses`) and `GET /v1/models` — returns
  `403 management_key_not_permitted`. Use your standard API keys for model
  requests and for listing models.
* It reads **org-wide**: `GET /v1/logs` returns request logs for every API key
  in your organization, not just one key.
* It never spends and is not subject to monthly spend caps — it keeps working
  even when your organization has hit its budget, so you can always see why.

Treat the key value like any credential: it is shown once at issuance and can
be rotated or revoked by Consus on request.

## Get request logs

`GET /v1/logs`

Returns your organization's per-request usage logs, newest first.

Logs are **metadata only**. The gateway never stores prompt or response
content ([zero data retention](/security)), so log rows contain token counts,
cost, latency, and status — never message text.

### Headers

| Header      | Required | Description                                                          |
| ----------- | -------- | -------------------------------------------------------------------- |
| `x-api-key` | Yes      | Your organization's **management** key. Standard keys receive `403`. |

### Query parameters

| Parameter    | Type     | Default              | Description                                                                                           |
| ------------ | -------- | -------------------- | ----------------------------------------------------------------------------------------------------- |
| `start`      | ISO 8601 | 30 days before `end` | Window start (UTC). A bare date (`2026-08-01`) means midnight UTC.                                    |
| `end`        | ISO 8601 | now                  | Window end (UTC). A bare date includes that whole day. Max window: 90 days.                           |
| `status`     | string   | `all`                | `all`, `success` (HTTP 200 only), or `errors` (non-200 only).                                         |
| `api_key_id` | string   | —                    | Scope results to one of your organization's key IDs.                                                  |
| `limit`      | integer  | 100                  | Rows per page, 1–1000.                                                                                |
| `cursor`     | string   | —                    | Opaque pagination token from a previous response. Treat it as opaque — do not construct or modify it. |

### Response

```json theme={null}
{
  "object": "list",
  "data": [
    {
      "request_id": "9c5b2f1a-8d3e-4b6a-9f21-0e7c44aa1b55",
      "timestamp": "2026-08-04T17:22:31.481923+00:00",
      "api_key_id": "a1b2c3d4e5",
      "model": "claude-sonnet-4-5:il5",
      "compliance": "il5",
      "reasoning_effort": "high",
      "input_tokens": 1204,
      "output_tokens": 356,
      "cost": 0.00897,
      "latency_ms": 2841,
      "status": "200"
    }
  ],
  "has_more": true,
  "next_cursor": "eyJ2IjoxLCJ3bSI6..."
}
```

| Field                            | Description                                                                                                                    |
| -------------------------------- | ------------------------------------------------------------------------------------------------------------------------------ |
| `request_id`                     | The gateway request ID (also returned to the caller as `X-Request-ID`).                                                        |
| `timestamp`                      | When the request completed (UTC).                                                                                              |
| `api_key_id`                     | Which of your organization's keys made the request.                                                                            |
| `model`                          | The composite model ID as requested.                                                                                           |
| `compliance`                     | The compliance level from the model ID (`il5`, `fedramp-high`, `il5+itar`, …); `null` when the request never resolved a model. |
| `reasoning_effort`               | The reasoning level used, when one applied; otherwise `null`.                                                                  |
| `input_tokens` / `output_tokens` | Billed token counts.                                                                                                           |
| `cost`                           | Cost of the request in USD.                                                                                                    |
| `latency_ms`                     | End-to-end gateway latency.                                                                                                    |
| `status`                         | HTTP status returned to the caller — error rows (`"4xx"`/`"5xx"`) appear alongside successes.                                  |

### Pagination

When `has_more` is `true`, pass `next_cursor` back as `cursor` to fetch the
next (older) page. The cursor freezes the query window, so results are stable
even while new traffic arrives — new requests appear when you start a fresh
query, never in the middle of one. Keep the other parameters identical between
pages; changing `status` or the window invalidates the cursor.

Always drive the loop from `has_more`, not from the size of `data`: when a
narrow filter matches nothing in a stretch of history, a page can come back
empty while `has_more` is still `true`. Stop only when `has_more` is `false`.

```bash theme={null}
curl "https://api.consus.io/v1/logs?limit=200" \
  -H "x-api-key: $CONSUS_MANAGEMENT_KEY"
```

```python theme={null}
import requests

rows, cursor = [], None
while True:
    params = {"limit": 200}
    if cursor:
        params["cursor"] = cursor
    page = requests.get(
        "https://api.consus.io/v1/logs",
        headers={"x-api-key": MANAGEMENT_KEY},
        params=params,
        timeout=30,
    ).json()
    rows.extend(page["data"])
    if not page["has_more"]:
        break
    cursor = page["next_cursor"]
```

### What's not in logs

A request is logged once it reaches a model-serving endpoint, so the log
includes provider errors and malformed-request rejections (`4xx`/`5xx` rows)
alongside successful calls.

Two classes of rejection are **not** recorded, because they are refused before
the request is ever metered:

* **Rejected at the edge** — invalid or missing API keys, WAF blocks, and rate
  limiting. These are visible only in Consus's edge audit logs.
* **Rejected by key policy** — a key over its monthly spend cap (`402`), an
  expired trial (`403`), or a management key attempting inference (`403`).
  These are refused before the request is billed or recorded, so an absence of
  rows during an outage can itself be the signal: if a key stopped producing
  log entries entirely, check its spend cap and expiry.

### Errors

| Status | Type                    | Meaning                                            |
| ------ | ----------------------- | -------------------------------------------------- |
| `400`  | `invalid_request_error` | Malformed parameter or an invalid/expired cursor.  |
| `403`  | `permission_error`      | The key is not a management key.                   |
| `404`  | `not_found`             | `api_key_id` is not a key in your organization.    |
| `503`  | `server_error`          | Log store temporarily unreachable — retry shortly. |
