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

# Read your usage and billing data with the Console API

> Pull monthly totals, per-day and per-key usage, usage per second, your API keys and billing status into your own systems as JSON.

The Console API gives you the numbers from the **Usage** and **Billing** pages of the console as JSON. Use it to feed usage into your own reporting, to check costs per printer or warehouse, or to reconcile invoices.

All endpoints are read-only and live under `https://caretly.dev/console/api/v1`.

## Get a key

The Console API uses the same API keys as the renderer. Create one at [caretly.dev/console/keys](https://caretly.dev/console/keys), or use a key you already have, and send it as a bearer token:

```bash theme={null}
Authorization: Bearer zpl_live_…
```

> [!NOTE]
>
> Test keys can read too, and they see the usage of the whole organisation, live labels included. A read-only integration doesn't need a live key.

Every key reads the data of its own organisation only. Revoked keys are refused immediately. A missing, invalid, expired or revoked key returns `401` with an `error` message.

## Monthly totals

```bash theme={null}
curl "https://caretly.dev/console/api/v1/usage?month=2026-10" \
  -H "Authorization: Bearer $ZPL_KEY"
```

```json theme={null}
{
  "month": "2026-10",
  "live_labels": 6170,
  "free_labels": 0,
  "test_labels": 500,
  "requests": 2253,
  "estimated_cost": { "amount": 12.34, "currency": "EUR" }
}
```

Leave out `month` for the current month. Months are calendar months in UTC. `free_labels` are the live labels rendered while your organisation had free access; they are never billed, also after the free access ends. The estimated cost is the other live labels times the price per label; your invoice is authoritative.

For a breakdown, use `/usage/daily` for labels per day and `/usage/keys` for labels and requests per key. They take the same `month` parameter.

## Page through usage events

`/usage/events` lists your usage newest first. Usage is recorded about once a second: an event counts all requests one key made in one format during that second, so a busy key gets one event per second, not one per request. Requests sent with an `Idempotency-Key` are listed one by one, so a retry shows up (and is billed) once.

Each event has an id `request_id`, `key_id`, `type` (`live` or `test`), `labels`, `requests` (how many requests it counts), `format`, and `at` and `until`: when the first and last of those requests were rendered (equal for a single request). Older events, from before usage was added up per second, are one request each.

```bash theme={null}
curl "https://caretly.dev/console/api/v1/usage/events?from=2026-10-01T00:00:00Z&to=2026-10-15T00:00:00Z&limit=500" \
  -H "Authorization: Bearer $ZPL_KEY"
```

```json theme={null}
{
  "from": "2026-10-01T00:00:00Z",
  "to": "2026-10-15T00:00:00Z",
  "events": [
    {
      "request_id": "7bec9189-d315-4529-96ec-8268b23f6b84",
      "key_id": "01a13a63-d85f-74be-9202-488c7a29b991",
      "type": "live",
      "labels": 14,
      "requests": 6,
      "format": "pdf",
      "at": "2026-10-15T16:10:00.120Z",
      "until": "2026-10-15T16:10:00.940Z"
    }
  ],
  "next_cursor": "MTc5MDgyMTU2MDAwMDAwMC5mNDNm…"
}
```

When `next_cursor` is not `null`, there are more events. Pass it as `cursor`, with the same `from` and `to`, to get the next page:

```bash theme={null}
curl "https://caretly.dev/console/api/v1/usage/events?from=2026-10-01T00:00:00Z&to=2026-10-15T00:00:00Z&limit=500&cursor=MTc5MDgyMTU2MDAwMDAwMC5mNDNm…" \
  -H "Authorization: Bearer $ZPL_KEY"
```

This loop fetches every page with `curl` and `jq`:

```bash theme={null}
url="https://caretly.dev/console/api/v1/usage/events?from=2026-10-01T00:00:00Z&to=2026-10-15T00:00:00Z&limit=1000"
cursor=""
while :; do
  page=$(curl -sf "$url${cursor:+&cursor=$cursor}" -H "Authorization: Bearer $ZPL_KEY")
  echo "$page" | jq -c '.events[]'
  cursor=$(echo "$page" | jq -r '.next_cursor // empty')
  [ -z "$cursor" ] && break
done
```

* `limit` is 100 by default and at most 1000.
* `from` is inclusive and `to` is exclusive. They are RFC 3339 times and may be at most 31 days apart. Without them you get the last 31 days.
* Write offsets as `Z`, or encode `+` as `%2B` in the URL.
* Treat the cursor as opaque. Pages stay stable while new usage comes in, so you don't miss or repeat events.

## Keys and billing

`/keys` lists your keys with their type, expiry and status (`active`, `expired` or `revoked`). It never returns tokens.

`/billing` returns your subscription status, whether live keys can be used, and the price per label:

```json theme={null}
{
  "subscription_status": "active",
  "billing_active": true,
  "price_per_label": 0.002,
  "currency": "EUR"
}
```

The **Console API** section of the navigation documents every endpoint and field, and lets you try them with your key.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.