---
title: "Get usage over time"
description: "Retrieve what the workspace's answers cost over a period: answers and credits by day, week or month, by mode, assistant, person or key, and words stored."
canonical: "https://lookio.app/docs/api/usage/get-usage"
updated: "2026-10-17"
---

# Get usage over time

Requires `usage:read`.

Usage comes from the ledger of settled answers, so it counts what was charged, not what was reserved. Besides the totals and one point per bucket, it breaks the usage down by query mode, by assistant, by who asked (a person or an API key) and by API key, and reports the words stored against your plan's allowance.

Without parameters, the range is the last 30 days. When you omit `granularity`, it follows the length of the range: day up to 31 days, week up to 180, month beyond. `from` and `to` accept a date such as `2026-07-01` or a full ISO 8601 timestamp, and a date-only `to` means the end of that day.

Answers given through a [widget](/docs/widget/overview) are part of these figures.

```http
GET https://api.lookio.app/v1/usage
```

## Authorizations

- `Authorization` (bearer, in header, required)

## Query parameters

- `from` (`string`)
- `to` (`string`)
- `granularity` (`enum<string>`, one of: `day, week, month`)

## Response

**200**: Retrieve credit usage over time

- `data` (`object`, required)
- `data.from` (`string`, required)
- `data.to` (`string`, required)
- `data.granularity` (`enum<string>`, required, one of: `day, week, month`)
- `data.totals` (`object`, required)
- `data.totals.answers` (`integer`, required): Answers settled, found or not.
- `data.totals.credits_used` (`integer`, required)
- `data.points` (`object[]`, required)
- `data.points.date` (`string`, required)
- `data.points.answers` (`integer`, required): Answers settled, found or not.
- `data.points.credits_used` (`integer`, required)
- `data.by_mode` (`object[]`, required): Per query mode. Besides the modes of `GET /v1/account`, it can list `search` (passage searches) and modes no longer offered, such as `europe` and `agent-lite`, kept for the history.
- `data.by_mode.mode` (`string`, required)
- `data.by_mode.answers` (`integer`, required): Answers settled, found or not.
- `data.by_mode.credits_used` (`integer`, required)
- `data.by_assistant` (`object[]`, required)
- `data.by_assistant.assistant_id` (`string,null`, required)
- `data.by_assistant.name` (`string,null`, required): Null when the assistant was deleted since.
- `data.by_assistant.answers` (`integer`, required): Answers settled, found or not.
- `data.by_assistant.credits_used` (`integer`, required)
- `data.by_origin` (`object[]`, required)
- `data.by_origin.origin` (`enum<string>`, required, one of: `person, api_key`): `person`: someone asking from the app, the CLI or an MCP client. `api_key`: a technical identity.
- `data.by_origin.answers` (`integer`, required): Answers settled, found or not.
- `data.by_origin.credits_used` (`integer`, required)
- `data.by_api_key` (`object[]`, required)
- `data.by_api_key.credential_id` (`string`, required)
- `data.by_api_key.name` (`string,null`, required)
- `data.by_api_key.answers` (`integer`, required): Answers settled, found or not.
- `data.by_api_key.credits_used` (`integer`, required)
- `data.words` (`object`, required)
- `data.words.stored` (`integer`, required): Words currently indexed in the workspace.
- `data.words.allowance` (`integer | null`, required): What the plan allows. Null is unlimited.
- `data.pages` (`object`, required)
- `data.pages.used` (`integer`, required): Pages extracted this calendar month (UTC): OCR pages and web pages read, new or changed only. Imports never spend credits.
- `data.pages.allowance` (`integer | null`, required): Pages the plan extracts a month. Null is unlimited.
- `data.pages.resets_at` (`string`, required): When the count starts again (the first of next month, UTC).
- `request_id` (`string`, required)

```json
{
  "data": {
    "from": "<string>",
    "to": "<string>",
    "granularity": "day",
    "totals": {
      "answers": 123,
      "credits_used": 123
    },
    "points": [
      {
        "date": "<string>",
        "answers": 123,
        "credits_used": 123
      }
    ],
    "by_mode": [
      {
        "mode": "<string>",
        "answers": 123,
        "credits_used": 123
      }
    ],
    "by_assistant": [
      {
        "assistant_id": null,
        "name": null,
        "answers": 123,
        "credits_used": 123
      }
    ],
    "by_origin": [
      {
        "origin": "person",
        "answers": 123,
        "credits_used": 123
      }
    ],
    "by_api_key": [
      {
        "credential_id": "<string>",
        "name": null,
        "answers": 123,
        "credits_used": 123
      }
    ],
    "words": {
      "stored": 123,
      "allowance": 123
    },
    "pages": {
      "used": 123,
      "allowance": 123,
      "resets_at": "<string>"
    }
  },
  "request_id": "<string>"
}
```

**400**: Possible codes: invalid_request, unknown_field, invalid_parameter, invalid_cursor

- `error` (`object`, required)
- `error.type` (`string`, required)
- `error.code` (`string`, required)
- `error.message` (`string`, required)
- `error.param` (`string`)
- `error.docs_url` (`string`, required)
- `error.action_url` (`string<uri>`)
- `request_id` (`string`, required)

```json
{
  "error": {
    "type": "<string>",
    "code": "<string>",
    "message": "<string>",
    "param": "<string>",
    "docs_url": "<string>",
    "action_url": "<string>"
  },
  "request_id": "<string>"
}
```

**401**: Possible codes: authentication_required, invalid_api_key, api_key_expired, api_key_revoked, invalid_access_key

- `error` (`object`, required)
- `error.type` (`string`, required)
- `error.code` (`string`, required)
- `error.message` (`string`, required)
- `error.param` (`string`)
- `error.docs_url` (`string`, required)
- `error.action_url` (`string<uri>`)
- `request_id` (`string`, required)

```json
{
  "error": {
    "type": "<string>",
    "code": "<string>",
    "message": "<string>",
    "param": "<string>",
    "docs_url": "<string>",
    "action_url": "<string>"
  },
  "request_id": "<string>"
}
```

**403**: Possible codes: insufficient_scope, feature_not_available, admin_required, permission_denied

- `error` (`object`, required)
- `error.type` (`string`, required)
- `error.code` (`string`, required)
- `error.message` (`string`, required)
- `error.param` (`string`)
- `error.docs_url` (`string`, required)
- `error.action_url` (`string<uri>`)
- `request_id` (`string`, required)

```json
{
  "error": {
    "type": "<string>",
    "code": "<string>",
    "message": "<string>",
    "param": "<string>",
    "docs_url": "<string>",
    "action_url": "<string>"
  },
  "request_id": "<string>"
}
```

**429**: Possible codes: rate_limited

- `error` (`object`, required)
- `error.type` (`string`, required)
- `error.code` (`string`, required)
- `error.message` (`string`, required)
- `error.param` (`string`)
- `error.docs_url` (`string`, required)
- `error.action_url` (`string<uri>`)
- `request_id` (`string`, required)

```json
{
  "error": {
    "type": "<string>",
    "code": "<string>",
    "message": "<string>",
    "param": "<string>",
    "docs_url": "<string>",
    "action_url": "<string>"
  },
  "request_id": "<string>"
}
```

**500**: Possible codes: internal_error

- `error` (`object`, required)
- `error.type` (`string`, required)
- `error.code` (`string`, required)
- `error.message` (`string`, required)
- `error.param` (`string`)
- `error.docs_url` (`string`, required)
- `error.action_url` (`string<uri>`)
- `request_id` (`string`, required)

```json
{
  "error": {
    "type": "<string>",
    "code": "<string>",
    "message": "<string>",
    "param": "<string>",
    "docs_url": "<string>",
    "action_url": "<string>"
  },
  "request_id": "<string>"
}
```

**Example request**

```bash
curl --request GET \
  --url 'https://api.lookio.app/v1/usage' \
  --header 'Authorization: <api-key>'
```
