---
title: "Per-person, per-model consumption for the org"
method: GET
path: "/orgs/{org_id}/usage/by-person"
tags: ["Organizations"]
---

# Per-person, per-model consumption for the org

`GET /orgs/{org_id}/usage/by-person`

## Request

- Base URL: `https://api.mnemom.ai/v1`
- URL: `https://api.mnemom.ai/v1/orgs/{org_id}/usage/by-person`
- Auth: HTTP bearer

Query-time aggregation of token/request consumption grouped by attributed person, provider, and model, scoped ONLY to the org's own usage_events via the immutable attribution_org_id snapshot (MNE-3213). Consumption only — never spend/cost/currency; see `GET /orgs/{org_id}/costs` for the dollar-cost rollup. Billing-shaped: `owner`, `admin`, and `auditor` only (`member`/`viewer` never receive this data). `days` is restricted to 7, 30, or 90 for v1. Cursor pagination is deterministic on `(total_tokens DESC, user_id, provider, model)`; `totals` and `attribution_rate` are computed over the complete filtered result before pagination. Behind the `USAGE_ATTRIBUTION_API_ENABLED` flag (default false in every environment) — while disabled this returns 404 to every caller, including owners.

## Path parameters

- `org_id` string, required

## Query parameters

- `days` 7 | 30 | 90
- `person_id` string
- `provider` string
- `model` string
- `limit` integer
- `cursor` string

## Response `200`

Per-person, per-model consumption rows + org-wide totals for the window.

- object
  - `from` string, date-time
  - `to` string, date-time
  - `collection_started_at` string, date-time, nullable: Earliest v1-attributed event for this org, independent of the selected filters. Null until the org has a v1 event.
  - `data` object[]
    - `user_id` string, nullable
    - `display_name` string, nullable
    - `email` string, nullable
    - `membership_state` 'active' | 'former' | 'unattributed'
    - `provider` string
    - `model` string
    - `tokens_in` string: 64-bit-safe total; transported as a string.
    - `tokens_out` string: 64-bit-safe total; transported as a string.
    - `request_count` string: 64-bit-safe total; transported as a string.
  - `totals` object
    - `tokens_in` string
    - `tokens_out` string
    - `request_count` string
    - `attributed_request_count` string
    - `unattributed_request_count` string
    - `attribution_rate` number
  - `next_cursor` string, nullable

## Other responses

- `400`: Bad request
- `401`: Authentication required
- `403`: Forbidden
- `404`: Resource not found
- `409`: Resource conflict — the request cannot proceed because of a current state conflict (e.g., resource already exists, version mismatch, in-flight idempotency key with a different body).
- `429`: Rate-limit exceeded. The global per-IP limiter (100 requests/minute, applied to every `/v1/*` route) rejected this request. Back off until the window resets — `Retry-After` carries the cooldown in seconds and `X-RateLimit-Reset` the absolute reset time.
- `500`: Server error — request was well-formed but the server failed to fulfill it. Typically a downstream dependency (DB / RPC / external API) returned an unexpected error.

---

[API](https://skmtc.dev/mnemom/apis/mnemom-api.md) · [All operations](https://skmtc.dev/mnemom/apis/mnemom-api/llms.txt) · [OpenAPI document](https://skmtc.dev/mnemom/apis/mnemom-api/revisions/274b7a6ea182?raw)
