# Credit usage events (admin)

Source: https://docs.recoupable.dev/api-reference/admins/credits-events

Returns the raw usage_events rows for a single account over the selected period, sorted by created_at descending.

## GET /api/admins/credits/events

Full OpenAPI specification: https://docs.recoupable.dev/spec/accounts.json

## Authentication

This operation requires one of the security alternatives in the specification below. Security scheme definitions are included where present in the published specification.

[Authentication guide](https://docs.recoupable.dev/authentication)

## Operation and referenced schemas

```json
{
  "openapi": "3.1.0",
  "info": {
    "title": "Recoup API - Accounts",
    "description": "API documentation for the Recoup platform - an AI agent platform for the music industry",
    "license": {
      "name": "MIT"
    },
    "version": "1.0.0"
  },
  "servers": [
    {
      "url": "https://api.recoupable.dev"
    }
  ],
  "paths": {
    "/api/admins/credits/events": {
      "get": {
        "operationId": "getAdminsCreditsEvents",
        "description": "Returns the raw `usage_events` rows for a single account over the selected period, sorted by `created_at` descending. Powers the drilldown view that expands when a row in the [`/api/admins/credits/rollup`](/api-reference/admins/credits-rollup) table is opened. Each event represents one debit (main agent turn, subagent step, chat completion, or research call), with token counts and `credits_deducted` matching the wallet drop on `credits_usage` for that account.\n\nThe response also carries a `grants` array covering the same account and period: the admin credit grants made through [`POST /api/admins/credits`](/api-reference/admins/credits-grant). The two arrays answer different questions — `events` is what the system spent, `grants` is what a person set by hand, and only a grant carries an actor and a reason. Requires the authenticated account to be a Recoup admin.",
        "parameters": [
          {
            "name": "account_id",
            "in": "query",
            "required": true,
            "description": "UUID of the account whose `usage_events` rows to return.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "period",
            "in": "query",
            "required": false,
            "description": "Window to filter `created_at` against. Same semantics as the rollup endpoint. Defaults to `monthly`.",
            "schema": {
              "type": "string",
              "enum": [
                "all",
                "daily",
                "weekly",
                "monthly"
              ],
              "default": "monthly"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Page size — number of events to return per request, sorted by `created_at` descending. Defaults to 100; max 500.",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 500,
              "default": 100
            }
          },
          {
            "name": "page",
            "in": "query",
            "required": false,
            "description": "1-indexed page number. Server returns rows `(page - 1) * limit` through `page * limit - 1`. Defaults to 1. Use `total_count` in the response to drive a 'load more' control on the drilldown (`page * limit < total_count`).",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "default": 1
            }
          }
        ],
        "security": [
          {
            "apiKeyAuth": []
          },
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Usage events retrieved successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AdminCreditsEventsResponse"
                }
              }
            }
          },
          "400": {
            "description": "Missing or invalid `account_id`, `period`, or `limit`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AccountErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized - missing or invalid credentials"
          },
          "403": {
            "description": "Forbidden - authenticated account is not a Recoup admin"
          },
          "500": {
            "description": "Internal server error while fetching usage events",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AccountErrorResponse"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "AdminCreditsEventsResponse": {
        "type": "object",
        "required": [
          "status",
          "account_id",
          "period",
          "page",
          "limit",
          "total_count",
          "events",
          "grants"
        ],
        "properties": {
          "status": {
            "type": "string",
            "enum": [
              "success",
              "error"
            ],
            "description": "Status of the request"
          },
          "account_id": {
            "type": "string",
            "format": "uuid",
            "description": "UUID of the account whose events were returned (echoes the request)"
          },
          "period": {
            "type": "string",
            "enum": [
              "all",
              "daily",
              "weekly",
              "monthly"
            ],
            "description": "The period the response was filtered to (echoes the request)"
          },
          "page": {
            "type": "integer",
            "minimum": 1,
            "description": "1-indexed page returned (echoes the request, or 1 if omitted)"
          },
          "limit": {
            "type": "integer",
            "minimum": 1,
            "description": "Page size used for this response (echoes the request, or the default if omitted)"
          },
          "total_count": {
            "type": "integer",
            "minimum": 0,
            "description": "Total number of `usage_events` rows for this account in the selected period (i.e. the size of the full result set before pagination). The client derives `has_more` as `page * limit < total_count` and shows 'X of Y events'. Computed via a `COUNT(*)` query alongside the paginated row fetch."
          },
          "events": {
            "type": "array",
            "description": "Raw `usage_events` rows, sorted by `created_at` descending",
            "items": {
              "type": "object",
              "required": [
                "id",
                "created_at",
                "source",
                "agent_type",
                "input_tokens",
                "cached_input_tokens",
                "output_tokens",
                "tool_call_count",
                "credits_deducted"
              ],
              "properties": {
                "id": {
                  "type": "string",
                  "description": "nanoid primary key of the `usage_events` row"
                },
                "created_at": {
                  "type": "string",
                  "format": "date-time",
                  "description": "When the event was recorded"
                },
                "source": {
                  "type": "string",
                  "enum": [
                    "web",
                    "api"
                  ],
                  "description": "Which surface originated the debit. `web` = open-agents chat. `api` = recoupable api (chat completion or research call)."
                },
                "agent_type": {
                  "type": "string",
                  "enum": [
                    "main",
                    "subagent"
                  ],
                  "description": "`main` for the top-level agent turn or any non-agent debit; `subagent` for a nested task-tool step"
                },
                "provider": {
                  "type": "string",
                  "nullable": true,
                  "description": "Provider slug (e.g. `anthropic`). Null when the debit isn't tied to a specific provider (e.g. research)."
                },
                "model_id": {
                  "type": "string",
                  "nullable": true,
                  "description": "The model for LLM-backed debits (e.g. `anthropic/claude-opus-4.6`), otherwise the billed API endpoint as `METHOD /route/pattern` (e.g. `POST /api/research/web`). Null on rows written before 2026-08-27."
                },
                "input_tokens": {
                  "type": "integer",
                  "description": "Total input tokens for the call (including cached). 0 for non-LLM debits."
                },
                "cached_input_tokens": {
                  "type": "integer",
                  "description": "Subset of `input_tokens` that hit the provider cache (priced at the cache-read rate)."
                },
                "output_tokens": {
                  "type": "integer",
                  "description": "Output tokens for the call. 0 for non-LLM debits."
                },
                "tool_call_count": {
                  "type": "integer",
                  "description": "Recorded tool count for this event. For the main agent workflow, this counts tool entries in the accumulated assistant reply, including pending and failed requests and entries retained when that reply resumes. Nested subagent entries are excluded. The value describes the reply snapshot, rather than successful executions or only new work after a resume. A writer can default an omitted count to zero, so zero alone does not establish that no tools were requested. Older events retain their previously recorded counts."
                },
                "credits_deducted": {
                  "type": "integer",
                  "description": "The amount debited from `credits_usage.remaining_credits` for this event, in micro-dollars (1,000,000 = $1.00). Same value the wallet dropped by on this turn."
                },
                "resource_url": {
                  "type": "string",
                  "nullable": true,
                  "description": "App-relative path of what produced the debit (`/chat?roomId=<roomId>`, `/music/<generationId>`, `/tasks/<taskId>/runs/<runId>`). Null for plain API calls and for rows written before the field existed."
                }
              }
            }
          },
          "grants": {
            "type": "array",
            "description": "Admin credit grants made against this account in the selected period, sorted by `created_at` descending — the write-side counterpart to `events`. A grant is a staff member setting the balance through [`POST /api/admins/credits`](/api-reference/admins/credits-grant), so unlike an event it carries an actor and a reason. Not paginated by `page`/`limit` and not counted in `total_count`, which describe `usage_events` only; capped at the 500 most recent grants in the period. Empty for the overwhelming majority of accounts, which have never been granted anything.",
            "items": {
              "type": "object",
              "required": [
                "id",
                "account_id",
                "created_at",
                "granted_by",
                "reason",
                "previous_credits",
                "remaining_credits"
              ],
              "properties": {
                "id": {
                  "type": "string",
                  "format": "uuid",
                  "description": "UUID of the grant row — the `grant_id` returned by `POST /api/admins/credits`"
                },
                "account_id": {
                  "type": "string",
                  "format": "uuid",
                  "description": "UUID of the account the grant was made against. Always equal to the top-level `account_id`, since the endpoint reports on one account at a time; present because each entry is the full stored grant row."
                },
                "created_at": {
                  "type": "string",
                  "format": "date-time",
                  "description": "When the grant was made"
                },
                "granted_by": {
                  "type": "string",
                  "format": "uuid",
                  "description": "UUID of the admin account that made the grant"
                },
                "reason": {
                  "type": "string",
                  "description": "The reason the admin recorded for the grant, verbatim"
                },
                "previous_credits": {
                  "type": "integer",
                  "nullable": true,
                  "description": "Balance immediately before the grant. Null when the account had no credits row and the grant created one."
                },
                "remaining_credits": {
                  "type": "integer",
                  "description": "Balance the account was left holding by the grant"
                }
              }
            }
          },
          "error": {
            "type": "string",
            "description": "Error message (only present if status is 'error')"
          }
        }
      },
      "AccountErrorResponse": {
        "type": "object",
        "required": [
          "status",
          "message"
        ],
        "properties": {
          "status": {
            "type": "string",
            "enum": [
              "error"
            ],
            "description": "Status of the request"
          },
          "message": {
            "type": "string",
            "description": "Error message describing what went wrong"
          }
        }
      }
    },
    "securitySchemes": {
      "apiKeyAuth": {
        "type": "apiKey",
        "in": "header",
        "name": "x-api-key",
        "description": "Your Recoup API key. [Learn more](/quickstart#api-keys)."
      },
      "bearerAuth": {
        "type": "http",
        "scheme": "bearer"
      }
    }
  }
}
```
