Saltar al contenido principal
DocumentaciónUso · console.latam.ccsio.ai

Usage

Usage ingest and the organization's usage reads: records, pages and summaries, filtered by principal where the caller may.

Menú de la documentación

Las descripciones de las operaciones y los campos son las del contrato, en inglés.

GET/metering/v1/usage

Read a usage fact back by idempotency key

Credencial
API key
Permiso
usage.read

Reads back the ingested C2 usage record by its canonical idempotency key (the idempotency_key query parameter, in the key's canonical compact-JSON form, percent-encoded). The response is the codec's exact C2 wire bytes — byte-identical to the ingested fixture. A key that was never applied is 404 usage-not-found.

curl
curl "https://console.latam.ccsio.ai/metering/v1/usage?idempotency_key=<idempotency_key>" \
  -H "Authorization: Bearer $CCSIO_API_KEY"

Parámetros

NombreEnDescripción
X-Request-ID
opcional
headerstring

Optional request ULID. A valid ULID (upper or lowercase) is honored; when the header is absent or invalid, the runtime mints the id. The response X-Request-ID header carries the canonical uppercase form.

idempotency_key
obligatorio
querystring

The key's canonical C2 form: compact JSON, five fields in schema order (tenant_id, plane_instance_id, request_or_run_id, attempt, provider_response_id), percent-encoded; the object shape is the C2 schema's idempotency_key; out-of-form is idempotency-key-invalid, distinct from invalid-request.

Respuestas

  • 200

    The usage fact, in its C2 wire form.

    Esquema
    UsageRecord
    • deployment_idstring or nullopcional

      pattern ^[A-Za-z0-9][A-Za-z0-9._:/-]{0,127}$

    • provider_classanyopcional

      Valores permitidos: "CCSIO_INFERENCE""CUSTOMER_HOSTED""EXTERNAL_MANAGED"null

    • request_duration_msinteger or nullopcional

      Whole router request timing, shared by all attempt records; absent on legacy records.

      0 to 9007199254740991

    • request_ttft_msinteger or nullopcional

      Whole router request timing, shared by all attempt records; absent on legacy records.

      0 to 9007199254740991

    • session_idstring or nullopcional

      Client-provided session label (the X-Session-Id request header), copied onto every attempt record of the request; absent or null when the client sent none. It groups requests for the operator; it is never an identity and never used for authorization or tenancy.

      pattern ^[A-Za-z0-9._:-]{1,128}$

    • http_statusinteger or nullopcional

      The HTTP status the router answered for the whole request: its single response, identical on every attempt record of the request (the per-attempt result is outcome_class). A request that failed after the response header was committed (a stream cut mid-way) keeps the committed status, 200. Absent or null on legacy records.

      100 to 599

    • error_codestring or nullopcional

      The stable error code of the router's response to the request (the OpenAI-format error.code, or the platform error code on the routes that answer in that envelope), identical on every attempt record of the request; for a stream cut after the header was committed it is the code of the terminal error frame, or, on the surfaces that write no terminal frame (a cut chat stream, an aborted audio transfer), the code the failure classifies to. Null or absent when the request succeeded and on legacy records.

      pattern ^[a-z][a-z0-9._-]{0,127}$

    • api_key_idstring or nullopcional

      The id of the API key the request was authenticated with (the key's key_id in the identity API, never the key itself), copied by the router from the signed context onto every attempt record of the request; absent or null for a request made without an API key, such as one from a console session. It says which credential was used; it is never an identity and never used for authorization or tenancy.

      pattern ^[A-Za-z0-9][A-Za-z0-9._:/-]{0,127}$

    • schema_versionanyobligatorio

      always "c2/v1"

    • event_idstringobligatorio

      pattern ^[a-z][a-z0-9._-]{0,127}$

    • idempotency_keyobjectobligatorio
      • tenant_idstringobligatorio

        pattern ^[a-z][a-z0-9._-]{0,127}$

      • plane_instance_idstringobligatorio

        pattern ^[a-z][a-z0-9._-]{0,127}$

      • request_or_run_idstringobligatorio

        pattern ^[a-z][a-z0-9._-]{0,127}$

      • attemptintegerobligatorio

        1 to 9007199254740991

      • provider_response_idone of or nullobligatorio

        Uno de

        • #1stringopcional

          pattern ^[a-z][a-z0-9._-]{0,127}$

        • #2anyopcional

          always ""

    • occurred_atstring (utc-second)obligatorio

      pattern ^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}Z$

    • emitted_atstring (utc-second)obligatorio

      pattern ^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}Z$

    • monotonic_since_boot_msintegerobligatorio

      0 to 9007199254740991

    • seqobjectobligatorio
      • stream_idstringobligatorio

        pattern ^[a-z][a-z0-9._-]{0,127}$

      • nintegerobligatorio

        1 to 9007199254740991

    • meter_epochstringobligatorio

      pattern ^[a-z][a-z0-9._-]{0,127}$

    • tenant_idstringobligatorio

      pattern ^[a-z][a-z0-9._-]{0,127}$

    • team_idstring or nullobligatorio

      pattern ^[a-z][a-z0-9._-]{0,127}$

    • principal_classstringobligatorio

      Valores permitidos: "user""service""agent"

    • principal_refstringobligatorio

      Original authenticated principal reference, preserved byte-for-byte under the C0 identity grammar.

      pattern ^[A-Za-z0-9][A-Za-z0-9._:/-]{0,127}$

    • planestringobligatorio

      Valores permitidos: "ai""agent""memory""brain"

    • operationstringobligatorio

      Valores permitidos: "chat""embedding""audio""image""document""tool""agent_overhead""responses""decision"

    • accounting_scopestringobligatorio

      Valores permitidos: "provider_attempt""platform_overhead""agent_aggregate"

    • model_aliasstringobligatorio

      Original selected model reference, preserved byte-for-byte under the C0 model registry grammar.

      pattern ^[A-Za-z0-9][A-Za-z0-9._:/-]{0,127}$

    • model_catalog_entry_digeststringobligatorio

      pattern ^[a-f0-9]{64}$

    • request_idstringobligatorio

      pattern ^[a-z][a-z0-9._-]{0,127}$

    • run_idstring or nullobligatorio

      pattern ^[a-z][a-z0-9._-]{0,127}$

    • agent_idstring or nullobligatorio

      pattern ^[a-z][a-z0-9._-]{0,127}$

    • agent_spec_digeststring or nullobligatorio

      pattern ^[a-f0-9]{64}$

    • quantitiesarray of objectobligatorio

      at most 16 items

      • unitstringobligatorio

        pattern ^[a-z][a-z0-9._-]{0,127}$

      • amountstringobligatorio

        pattern ^(0|[1-9][0-9]{0,17})(\.[0-9]{0,8}[1-9])?$

    • measurementstringobligatorio

      Valores permitidos: "measured""estimated""unknown"

    • measurement_reasonstring or nullobligatorio

      Valores permitidos: "coarse_counter""provider_estimate""final_usage_missing""meter_loss""canceled""implausible_count"

    • duration_msinteger or nullobligatorio

      0 to 9007199254740991

    • ttft_msinteger or nullobligatorio

      0 to 9007199254740991

    • request_countintegerobligatorio

      0 to 9007199254740991

    • tool_call_countintegerobligatorio

      0 to 9007199254740991

    • outcome_classstringobligatorio

      Valores permitidos: "success""error""canceled""unknown"

    • data_classificationstringobligatorio

      Valores permitidos: "public""internal""restricted"

    • routing_inputsobjectobligatorio
      • rule_idsarray of stringobligatorio

        at most 16 items

      • classification_labelstringobligatorio

        Valores permitidos: "public""internal""restricted"

      • priority_groupstringobligatorio

        Valores permitidos: "low""normal""high"

    • routing_inputs_digeststringobligatorio

      pattern ^[a-f0-9]{64}$

    • bundle_versionintegerobligatorio

      1 to 9007199254740991

    • bundle_digeststringobligatorio

      pattern ^[a-f0-9]{64}$

  • 400

    Client refusal unrelated to authentication, including malformed input, a denied or failed request.

  • 401

    The request carries no credential, more than one, or one the platform does not accept, and is refused before the operation runs; `error.code` says why. Supply exactly one credential. Codes: invalid-request (no credential, or both Authorization:

    Leer más

    Bearer and x-api-key), api-key-invalid (a value that is not a platform API key, or a key of a kind the platform does not accept), api-key-unknown, api-key-revoked, api-key-expired, bootstrap-disabled (the one-shot installation credential, once a key exists), token-malformed (a bearer token that is not a JWT), token-algorithm-unsupported, token-signature-invalid, token-claim-invalid, token-issuer-mismatch, token-audience-mismatch, token-expired, token-not-yet-valid, issuer-untrusted, issuer-residency-mismatch (the issuer belongs to another plane), issuer-resolution-unknown, jwks-unavailable, jwks-key-not-found, staff-token-inactive (a platform operator's token), staff-not-operator, staff-directory-unavailable, identity-not-provisioned (a verified identity with no account on this plane), organization-not-found (a verified identity or key whose organization this plane does not know), internal-error (a fault while the credential is checked is refused too, fail closed), context-cancelled

  • 402

    The organization has to pay first: its standing is payment_required.

    Leer más

    The request boundary applies this payment gate to every route except an organization's billing routes, the caller's own context, organization list, onboarding, session report and personal keys, the public routes, and the routes of platform operators, who administer an organization that has to pay. The operations the gate covers declare this response. On /v1 the refusal is rendered in the OpenAI error format. Code: payment-required

  • 403

    The credential is valid but may not do this here; the request is refused by the request boundary before the handler runs, and `error.code` says which refusal. An operation may add codes of its own.

    Leer más

    Codes: policy-denied (no role of the caller holds the permission the operation needs, or the credential class may not call it: a personal API key outside inference and MCP, a route that needs a signed-in person, the one-shot installation credential outside its three steps), tenant-mismatch (the organization a path, query, body or X-Tenant header names is not the caller's own), organization-provisioning, organization-suspended, organization-disabled, organization-deleted (the state of the caller's organization), user-disabled, residency-mismatch (the organization lives on another plane), organization-selection-required (a caller with more than one organization, or a platform operator, must name one in X-Organization-Id), organization-not-selectable, no-active-organization-membership, team-not-selectable (the X-Organization-Id or X-Team-Id the caller sent does not name an organization or team it may act in), identity-managed-by-provider (a person who is not a platform operator changes an organization's status, which belongs to the identity provider), support-session-required (a platform operator reads an organization's data without an open support session)

  • 404

    The requested resource or path was not found.

  • 405

    The path is claimed but the request method is not allowed. Go ServeMux returns its standard plain-text response and lists permitted methods in Allow.

  • 500

    Platform failure, rendered without internal cause details.

POST/metering/v1/usage

Ingest one C2 usage record

Credencial
API key
Permiso
usage.manage
Cuerpo de la solicitud
Cuerpo de hasta 1 MiB

Ingests one C2 v1 usage record. The body is the strict C2 profile (unknown fields and trailing data rejected). Idempotent under redelivery: a duplicate key renders exactly {"status":"redelivered"} with no event_id or checkpoint.

Leer más

First delivery renders {"status":"ingested","event_id":...,"checkpoint":{...}}; event_id is present only when usage-event emission is enabled on the serving role (see info). The request body is capped at 1048576 bytes; over-cap is 400 invalid-request, never 413.

curl
curl -X POST "https://console.latam.ccsio.ai/metering/v1/usage" \
  -H "Authorization: Bearer $CCSIO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "schema_version": null,
  "event_id": "string",
  "idempotency_key": {
    "tenant_id": "string",
    "plane_instance_id": "string",
    "request_or_run_id": "string",
    "attempt": 0,
    "provider_response_id": "string"
  },
  "occurred_at": "string",
  "emitted_at": "string",
  "monotonic_since_boot_ms": 0,
  "seq": {
    "stream_id": "string",
    "n": 0
  },
  "meter_epoch": "string",
  "tenant_id": "string",
  "team_id": "string",
  "principal_class": "user",
  "principal_ref": "string",
  "plane": "ai",
  "operation": "chat",
  "accounting_scope": "provider_attempt",
  "model_alias": "string",
  "model_catalog_entry_digest": "string",
  "request_id": "string",
  "run_id": "string",
  "agent_id": "string",
  "agent_spec_digest": "string",
  "quantities": [
    {
      "unit": "string",
      "amount": "string"
    }
  ],
  "measurement": "measured",
  "measurement_reason": "coarse_counter",
  "duration_ms": 0,
  "ttft_ms": 0,
  "request_count": 0,
  "tool_call_count": 0,
  "outcome_class": "success",
  "data_classification": "public",
  "routing_inputs": {
    "rule_ids": [
      "string"
    ],
    "classification_label": "public",
    "priority_group": "low"
  },
  "routing_inputs_digest": "string",
  "bundle_version": 0,
  "bundle_digest": "string"
}'
Construido con los campos obligatorios del esquema: reemplaza los valores.

Parámetros

NombreEnDescripción
X-Request-ID
opcional
headerstring

Optional request ULID. A valid ULID (upper or lowercase) is honored; when the header is absent or invalid, the runtime mints the id. The response X-Request-ID header carries the canonical uppercase form.

Cuerpo de la solicitud application/json

UsageRecord
  • deployment_idstring or nullopcional

    pattern ^[A-Za-z0-9][A-Za-z0-9._:/-]{0,127}$

  • provider_classanyopcional

    Valores permitidos: "CCSIO_INFERENCE""CUSTOMER_HOSTED""EXTERNAL_MANAGED"null

  • request_duration_msinteger or nullopcional

    Whole router request timing, shared by all attempt records; absent on legacy records.

    0 to 9007199254740991

  • request_ttft_msinteger or nullopcional

    Whole router request timing, shared by all attempt records; absent on legacy records.

    0 to 9007199254740991

  • session_idstring or nullopcional

    Client-provided session label (the X-Session-Id request header), copied onto every attempt record of the request; absent or null when the client sent none. It groups requests for the operator; it is never an identity and never used for authorization or tenancy.

    pattern ^[A-Za-z0-9._:-]{1,128}$

  • http_statusinteger or nullopcional

    The HTTP status the router answered for the whole request: its single response, identical on every attempt record of the request (the per-attempt result is outcome_class). A request that failed after the response header was committed (a stream cut mid-way) keeps the committed status, 200. Absent or null on legacy records.

    100 to 599

  • error_codestring or nullopcional

    The stable error code of the router's response to the request (the OpenAI-format error.code, or the platform error code on the routes that answer in that envelope), identical on every attempt record of the request; for a stream cut after the header was committed it is the code of the terminal error frame, or, on the surfaces that write no terminal frame (a cut chat stream, an aborted audio transfer), the code the failure classifies to. Null or absent when the request succeeded and on legacy records.

    pattern ^[a-z][a-z0-9._-]{0,127}$

  • api_key_idstring or nullopcional

    The id of the API key the request was authenticated with (the key's key_id in the identity API, never the key itself), copied by the router from the signed context onto every attempt record of the request; absent or null for a request made without an API key, such as one from a console session. It says which credential was used; it is never an identity and never used for authorization or tenancy.

    pattern ^[A-Za-z0-9][A-Za-z0-9._:/-]{0,127}$

  • schema_versionanyobligatorio

    always "c2/v1"

  • event_idstringobligatorio

    pattern ^[a-z][a-z0-9._-]{0,127}$

  • idempotency_keyobjectobligatorio
    • tenant_idstringobligatorio

      pattern ^[a-z][a-z0-9._-]{0,127}$

    • plane_instance_idstringobligatorio

      pattern ^[a-z][a-z0-9._-]{0,127}$

    • request_or_run_idstringobligatorio

      pattern ^[a-z][a-z0-9._-]{0,127}$

    • attemptintegerobligatorio

      1 to 9007199254740991

    • provider_response_idone of or nullobligatorio

      Uno de

      • #1stringopcional

        pattern ^[a-z][a-z0-9._-]{0,127}$

      • #2anyopcional

        always ""

  • occurred_atstring (utc-second)obligatorio

    pattern ^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}Z$

  • emitted_atstring (utc-second)obligatorio

    pattern ^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}Z$

  • monotonic_since_boot_msintegerobligatorio

    0 to 9007199254740991

  • seqobjectobligatorio
    • stream_idstringobligatorio

      pattern ^[a-z][a-z0-9._-]{0,127}$

    • nintegerobligatorio

      1 to 9007199254740991

  • meter_epochstringobligatorio

    pattern ^[a-z][a-z0-9._-]{0,127}$

  • tenant_idstringobligatorio

    pattern ^[a-z][a-z0-9._-]{0,127}$

  • team_idstring or nullobligatorio

    pattern ^[a-z][a-z0-9._-]{0,127}$

  • principal_classstringobligatorio

    Valores permitidos: "user""service""agent"

  • principal_refstringobligatorio

    Original authenticated principal reference, preserved byte-for-byte under the C0 identity grammar.

    pattern ^[A-Za-z0-9][A-Za-z0-9._:/-]{0,127}$

  • planestringobligatorio

    Valores permitidos: "ai""agent""memory""brain"

  • operationstringobligatorio

    Valores permitidos: "chat""embedding""audio""image""document""tool""agent_overhead""responses""decision"

  • accounting_scopestringobligatorio

    Valores permitidos: "provider_attempt""platform_overhead""agent_aggregate"

  • model_aliasstringobligatorio

    Original selected model reference, preserved byte-for-byte under the C0 model registry grammar.

    pattern ^[A-Za-z0-9][A-Za-z0-9._:/-]{0,127}$

  • model_catalog_entry_digeststringobligatorio

    pattern ^[a-f0-9]{64}$

  • request_idstringobligatorio

    pattern ^[a-z][a-z0-9._-]{0,127}$

  • run_idstring or nullobligatorio

    pattern ^[a-z][a-z0-9._-]{0,127}$

  • agent_idstring or nullobligatorio

    pattern ^[a-z][a-z0-9._-]{0,127}$

  • agent_spec_digeststring or nullobligatorio

    pattern ^[a-f0-9]{64}$

  • quantitiesarray of objectobligatorio

    at most 16 items

    • unitstringobligatorio

      pattern ^[a-z][a-z0-9._-]{0,127}$

    • amountstringobligatorio

      pattern ^(0|[1-9][0-9]{0,17})(\.[0-9]{0,8}[1-9])?$

  • measurementstringobligatorio

    Valores permitidos: "measured""estimated""unknown"

  • measurement_reasonstring or nullobligatorio

    Valores permitidos: "coarse_counter""provider_estimate""final_usage_missing""meter_loss""canceled""implausible_count"

  • duration_msinteger or nullobligatorio

    0 to 9007199254740991

  • ttft_msinteger or nullobligatorio

    0 to 9007199254740991

  • request_countintegerobligatorio

    0 to 9007199254740991

  • tool_call_countintegerobligatorio

    0 to 9007199254740991

  • outcome_classstringobligatorio

    Valores permitidos: "success""error""canceled""unknown"

  • data_classificationstringobligatorio

    Valores permitidos: "public""internal""restricted"

  • routing_inputsobjectobligatorio
    • rule_idsarray of stringobligatorio

      at most 16 items

    • classification_labelstringobligatorio

      Valores permitidos: "public""internal""restricted"

    • priority_groupstringobligatorio

      Valores permitidos: "low""normal""high"

  • routing_inputs_digeststringobligatorio

    pattern ^[a-f0-9]{64}$

  • bundle_versionintegerobligatorio

    1 to 9007199254740991

  • bundle_digeststringobligatorio

    pattern ^[a-f0-9]{64}$

Respuestas

  • 200

    The usage record was ingested (or redelivered).

    Esquema
    IngestResponse
    • statusstringobligatorio

      The ingest result: ingested (first delivery) or redelivered (duplicate key).

      Valores permitidos: "ingested""redelivered"

    • event_idstringopcional

      The durable outbox row's ULID, minted at enqueue (first delivery only; omitted on redelivery; present only when usage-event emission is enabled on the serving role).

      pattern ^[0-9A-HJKMNP-TV-Z]{26}$

    • checkpointobjectopcional

      The scope's C3 checkpoint cursors (first delivery only; omitted on redelivery).

      • tenant_idstringobligatorio

        pattern ^[a-z][a-z0-9._-]{0,127}$

      • plane_instance_idstringobligatorio

        pattern ^[a-z][a-z0-9._-]{0,127}$

      • stream_idstringobligatorio

        pattern ^[a-z][a-z0-9._-]{0,127}$

      • contiguous_usage_throughintegerobligatorio

        0 to 9007199254740991

      • usage_high_waterintegerobligatorio

        0 to 9007199254740991

  • 400

    Client refusal unrelated to authentication, including malformed input, a denied or failed request.

  • 401

    The request carries no credential, more than one, or one the platform does not accept, and is refused before the operation runs; `error.code` says why. Supply exactly one credential. Codes: invalid-request (no credential, or both Authorization:

    Leer más

    Bearer and x-api-key), api-key-invalid (a value that is not a platform API key, or a key of a kind the platform does not accept), api-key-unknown, api-key-revoked, api-key-expired, bootstrap-disabled (the one-shot installation credential, once a key exists), token-malformed (a bearer token that is not a JWT), token-algorithm-unsupported, token-signature-invalid, token-claim-invalid, token-issuer-mismatch, token-audience-mismatch, token-expired, token-not-yet-valid, issuer-untrusted, issuer-residency-mismatch (the issuer belongs to another plane), issuer-resolution-unknown, jwks-unavailable, jwks-key-not-found, staff-token-inactive (a platform operator's token), staff-not-operator, staff-directory-unavailable, identity-not-provisioned (a verified identity with no account on this plane), organization-not-found (a verified identity or key whose organization this plane does not know), internal-error (a fault while the credential is checked is refused too, fail closed), context-cancelled

  • 402

    The organization has to pay first: its standing is payment_required.

    Leer más

    The request boundary applies this payment gate to every route except an organization's billing routes, the caller's own context, organization list, onboarding, session report and personal keys, the public routes, and the routes of platform operators, who administer an organization that has to pay. The operations the gate covers declare this response. On /v1 the refusal is rendered in the OpenAI error format. Code: payment-required

  • 403

    The credential is valid but may not do this here; the request is refused by the request boundary before the handler runs, and `error.code` says which refusal. An operation may add codes of its own.

    Leer más

    Codes: policy-denied (no role of the caller holds the permission the operation needs, or the credential class may not call it: a personal API key outside inference and MCP, a route that needs a signed-in person, the one-shot installation credential outside its three steps), tenant-mismatch (the organization a path, query, body or X-Tenant header names is not the caller's own), organization-provisioning, organization-suspended, organization-disabled, organization-deleted (the state of the caller's organization), user-disabled, residency-mismatch (the organization lives on another plane), organization-selection-required (a caller with more than one organization, or a platform operator, must name one in X-Organization-Id), organization-not-selectable, no-active-organization-membership, team-not-selectable (the X-Organization-Id or X-Team-Id the caller sent does not name an organization or team it may act in), identity-managed-by-provider (a person who is not a platform operator changes an organization's status, which belongs to the identity provider), support-session-required (a platform operator reads an organization's data without an open support session)

  • 405

    The path is claimed but the request method is not allowed. Go ServeMux returns its standard plain-text response and lists permitted methods in Allow.

  • 500

    Platform failure, rendered without internal cause details.

GET/metering/v1/usage/summary

Summarize the selected organization's usage

Credencial
API key
Permiso
Cualquiera deusage.read_ownusage.readplatform-usage.readsupport-access.read

The organization is derived exclusively from the verified actor context; tenant or organization query parameters are not accepted. Reads occurred_at in the half-open [from, to) UTC interval, defaulting to the last 7 days and capped at 90 days. Counts and quantities are exact strings.

Leer más

Metrics retain accounting_scope so provider attempts, platform overhead, and agent aggregates are not double-counted as a single total. Unknown or duplicate query parameters and invalid windows return 400; a missing selected organization returns 403. Windows with no usage return empty scopes/models/by_principal, zero daily series, and cost unavailable. Optional model_alias and accounting_scope filters apply to the full requested window before aggregation or pagination; filtering never operates on a truncated request page. The optional principal filter (a principal_ref or an email address, with the request-log principal filter's validation, case-insensitive email resolution and visibility rule) narrows every total, daily bucket and breakdown to that principal's usage. The optional api_key_id filter narrows them to the usage made with one API key; with both, a fact must match both. by_principal breaks the filtered window down per principal: one entry per accounting scope and principal_ref, named with the email and display name resolved when the summary is read, at most 100 per accounting scope (by_principal_truncated tells when any scope was cut); the scope totals always cover every principal. Requires usage.read_own (at any level), usage.read or, for a platform operator, platform-usage.read. WHICH usage: a caller holding usage.read at organization level (the Administrator role) reads every principal's usage; a caller holding usage.read_own without it - the built-in User role, and a Team Admin, whose usage.read applies to its team's request log and not to this report - reads ONLY the usage whose principal is themselves (a member's own user principal and personal API keys, a service account the usage it made), whatever the request carries: the principal filter is forced to the caller's own reference, so a principal filter naming anyone else, by reference or by email, matches nothing (200 with an empty result, never an error and never a hint of whose usage it is - the request log's narrowing) and by_principal holds only the caller. WITH AN API KEY: these routes answer a service-account API key sent in x-api-key or as Authorization: Bearer, on the console host of the key's own organization and region; a personal API key reaches inference and MCP only and is refused here with 403 policy-denied. A key whose role holds usage.read_own without usage.read reads ONLY the usage made with that key: the facts whose api_key_id is the key's own key_id, not everything its service account made. Whatever the request carries, the read stays bound to that key and to its service account: an api_key_id naming another key (of the same service account or of anyone else) and a principal naming anyone else match nothing (200 with an empty result, never an error), and the key's own id or reference is the same read as no filter. A key whose role holds usage.read at organization level reads the organization's usage exactly as the Administrator role does and may narrow it to one key with api_key_id. Neither level reads another organization: the organization is the key's own and no parameter or header names it. A revoked or expired key is 401 api-key-revoked or api-key-expired, as on every route; an organization with no active subscription is refused with 402 payment-required before any role is checked. A caller holding none of these permissions is 403 policy-denied. A platform operator (platform-usage.read: a permission of the fixed operator set, held by no organization or team role and by no custom role) who selected the organization with the X-Organization-Id header reads the organization's totals, daily series and per-model rows exactly as the Administrator role does, with by_principal an empty list and by_principal_truncated false and nobody named: the view is not per user, so a principal or api_key_id filter is refused with 400 invalid-request, while the period, model_alias, accounting_scope and operation_class filters apply. Without a selected organization the operator is told to select one (403 organization-selection-required). The permission opens no other read: the usage page, the request logs, the usage lookup and the status reads need usage.read or usage.read_own and answer a platform operator with 403 policy-denied. The answer for the organization's own members is unchanged.

curl
curl "https://console.latam.ccsio.ai/metering/v1/usage/summary" \
  -H "Authorization: Bearer $CCSIO_API_KEY"

Parámetros

NombreEnDescripción
X-Request-ID
opcional
headerstring

Optional request ULID. A valid ULID (upper or lowercase) is honored; when the header is absent or invalid, the runtime mints the id. The response X-Request-ID header carries the canonical uppercase form.

from
opcional
querystring

Inclusive UTC RFC 3339 start (must end in Z; fractional seconds allowed). Supply both from and to or omit both for the last 7 days, or the cursor's frozen window when paging. The interval must be positive and at most 90 days.

to
opcional
querystring

Exclusive UTC RFC 3339 end (must end in Z; fractional seconds allowed). Required when from is supplied.

model_alias
opcional
querystring

Optional exact model reference, preserving case and punctuation. Omit for all models; a valid reference with no matching usage returns empty totals and zero daily buckets.

accounting_scope
opcional
querystring

Optional accounting scope. Omit for all scopes, which remain separate in every aggregate; the literal all is not accepted.

principal
opcional
queryone of

Optional.

Leer más

Narrows every total, daily bucket and breakdown of the response to the usage made by this principal: the principal_ref (a C0 reference) or an email address (it contains '@'), matched case-insensitively against the organization's users and resolved to their refs, exactly as the request-log principal filter does. A reference matches the usage of that principal_ref whatever its principal_class (a member's own sessions and personal API keys share their reference). An email filter follows the visibility rule of the emails themselves: a caller who may not read the organization's member list (members.read at organization level, or a platform administrator) may filter only by their own email, any other address matches no usage; an address that matches no user matches no usage (a 200 with empty scopes, models and by_principal, zero daily buckets or an empty page — not an error — so the filter cannot be used to probe whose address it is). A value that is neither a reference nor a plain email address (no display name, no whitespace, at most 254 bytes) renders 400 invalid-request. On the page read the cursor is bound to the filter as it was typed. The platform operator's summary (platform-usage.read) is not per user: there this filter renders 400 invalid-request. For an API key reading only its own usage, a principal other than its service account's matches no usage.

api_key_id
opcional
querystring

Optional. Narrows every total, daily bucket and breakdown of the response (or every record of the page) to the usage made with this API key: the facts whose api_key_id is this value, the key's key_id in the identity API.

Leer más

Usage made from a console session carries no key and never matches, and neither does usage recorded before the usage fact carried the key (2026-10-06) nor a tool call through the MCP endpoint. A key that made no usage in the window gives a 200 with empty scopes, models and by_principal, zero daily buckets or an empty page, not an error. A value outside the key id grammar renders 400 invalid-request. On the page read the cursor is bound to the filter. The platform operator's summary (platform-usage.read) is not per user: there this filter renders 400 invalid-request. For an API key whose role holds usage.read_own without usage.read, the read is already bound to that key's own id: its own key_id is the same read as no filter, and any other id (of its service account's other keys too) gives a 200 with an empty result.

operation_class
opcional
querystring

Optional. Narrows every total, daily bucket and breakdown of the response (or every record of the page) to one class of usage. `inference` is the usage of models: every fact whose operation is not `tool`. `tool` is the calls of MCP tools: the facts whose operation is `tool`, whose model_alias names the installation and the tool. Without it the read covers both, as before. A page's cursor is bound to it.

Respuestas

  • 200

    The selected organization's usage metrics for the requested window.

    Esquema
    UsageSummaryResponse
    • organization_idstringobligatorio

      pattern ^[a-z][a-z0-9._-]{0,63}$

    • windowobjectobligatorio
      • fromstring (date-time)obligatorio

        pattern Z$

      • tostring (date-time)obligatorio

        pattern Z$

    • scopesarray of UsageSummaryScopeobligatorio

      Metrics grouped by accounting_scope; scopes are never combined into an ambiguous total.

      • accounting_scopestringobligatorio

        Valores permitidos: "provider_attempt""platform_overhead""agent_aggregate"

      • recordsUsageCountobligatorio

        An exact non-negative integer serialized as a string to avoid client precision loss.

      • request_countUsageCountobligatorio

        An exact non-negative integer serialized as a string to avoid client precision loss.

      • tool_call_countUsageCountobligatorio

        An exact non-negative integer serialized as a string to avoid client precision loss.

      • quantitiesarray of UsageQuantityobligatorio
      • measurement_countsobjectobligatorio
        • measuredUsageCountobligatorio

          An exact non-negative integer serialized as a string to avoid client precision loss.

        • estimatedUsageCountobligatorio

          An exact non-negative integer serialized as a string to avoid client precision loss.

        • unknownUsageCountobligatorio

          An exact non-negative integer serialized as a string to avoid client precision loss.

      • outcome_countsobjectobligatorio
        • successUsageCountobligatorio

          An exact non-negative integer serialized as a string to avoid client precision loss.

        • errorUsageCountobligatorio

          An exact non-negative integer serialized as a string to avoid client precision loss.

        • canceledUsageCountobligatorio

          An exact non-negative integer serialized as a string to avoid client precision loss.

        • unknownUsageCountobligatorio

          An exact non-negative integer serialized as a string to avoid client precision loss.

    • modelsarray of UsageSummaryModelobligatorio

      Metrics grouped by the pair (accounting_scope, model_alias).

      • accounting_scopestringobligatorio

        Valores permitidos: "provider_attempt""platform_overhead""agent_aggregate"

      • recordsUsageCountobligatorio

        An exact non-negative integer serialized as a string to avoid client precision loss.

      • request_countUsageCountobligatorio

        An exact non-negative integer serialized as a string to avoid client precision loss.

      • tool_call_countUsageCountobligatorio

        An exact non-negative integer serialized as a string to avoid client precision loss.

      • quantitiesarray of UsageQuantityobligatorio
      • measurement_countsobjectobligatorio
        • measuredUsageCountobligatorio

          An exact non-negative integer serialized as a string to avoid client precision loss.

        • estimatedUsageCountobligatorio

          An exact non-negative integer serialized as a string to avoid client precision loss.

        • unknownUsageCountobligatorio

          An exact non-negative integer serialized as a string to avoid client precision loss.

      • outcome_countsobjectobligatorio
        • successUsageCountobligatorio

          An exact non-negative integer serialized as a string to avoid client precision loss.

        • errorUsageCountobligatorio

          An exact non-negative integer serialized as a string to avoid client precision loss.

        • canceledUsageCountobligatorio

          An exact non-negative integer serialized as a string to avoid client precision loss.

        • unknownUsageCountobligatorio

          An exact non-negative integer serialized as a string to avoid client precision loss.

      • model_aliasstringobligatorio

        Original selected model reference, preserved byte-for-byte under the C0 model registry grammar.

        pattern ^[A-Za-z0-9][A-Za-z0-9._:/-]{0,127}$

    • by_principalarray of UsageSummaryPrincipalobligatorio

      Metrics grouped by the pair (accounting_scope, principal_ref): who made the usage of the filtered window, each principal named (see UsageSummaryPrincipal). Ordered by request_count descending (an exact integer), then principal_ref ascending, then accounting_scope. At most 100 entries per accounting_scope (so at most 300): a scope with more principals lists its first 100 and by_principal_truncated is true. The scope totals in scopes always cover every principal.

      at most 300 items

      • accounting_scopestringobligatorio

        Valores permitidos: "provider_attempt""platform_overhead""agent_aggregate"

      • recordsUsageCountobligatorio

        An exact non-negative integer serialized as a string to avoid client precision loss.

      • request_countUsageCountobligatorio

        An exact non-negative integer serialized as a string to avoid client precision loss.

      • tool_call_countUsageCountobligatorio

        An exact non-negative integer serialized as a string to avoid client precision loss.

      • quantitiesarray of UsageQuantityobligatorio
      • measurement_countsobjectobligatorio
        • measuredUsageCountobligatorio

          An exact non-negative integer serialized as a string to avoid client precision loss.

        • estimatedUsageCountobligatorio

          An exact non-negative integer serialized as a string to avoid client precision loss.

        • unknownUsageCountobligatorio

          An exact non-negative integer serialized as a string to avoid client precision loss.

      • outcome_countsobjectobligatorio
        • successUsageCountobligatorio

          An exact non-negative integer serialized as a string to avoid client precision loss.

        • errorUsageCountobligatorio

          An exact non-negative integer serialized as a string to avoid client precision loss.

        • canceledUsageCountobligatorio

          An exact non-negative integer serialized as a string to avoid client precision loss.

        • unknownUsageCountobligatorio

          An exact non-negative integer serialized as a string to avoid client precision loss.

      • principal_refstringobligatorio

        The principal's authoritative reference, preserved byte-for-byte under the C0 identity grammar.

        pattern ^[A-Za-z0-9][A-Za-z0-9._:/-]{0,127}$

      • principal_classstringobligatorio

        Valores permitidos: "user""service""agent"

      • emailstring or nullobligatorio

        The principal's email address, resolved at read time; null when the principal has none (a service account), is unknown to the organization's directory, or this caller may not see another user's email.

        at most 254 characters

      • display_namestring or nullobligatorio

        The principal's display name (for a service account, its name), resolved at read time; null under the same conditions as email and when the principal has none.

        at most 128 characters

    • by_principal_truncatedbooleanobligatorio

      True when at least one accounting scope has more than 100 principals and by_principal lists only its first 100 (ordered by request_count descending, then principal_ref). scopes, models and series always cover every principal.

    • costobjectobligatorio
      • statusstringobligatorio

        Usage quantities have no authoritative pricing data; no estimated monetary total is presented.

        always "unavailable"

    • seriesarray of UsageSeriesBucketobligatorio

      Ascending UTC calendar-day buckets covering the whole half-open response window. First and last bucket boundaries are clipped to the window, including fractional seconds. Every intersecting day is present, including zero days. Within each accounting scope, summing daily metrics and quantities equals the full-window scoped totals; scopes are never added together.

      at least 1 items · at most 91 items

      • windowobjectobligatorio
        • fromstring (date-time)obligatorio

          pattern Z$

        • tostring (date-time)obligatorio

          pattern Z$

      • scopesarray of UsageSummaryScopeobligatorio

        Each requested accounting scope is present independently. An empty scope has exact zero counts, zero measurement/outcome counts, and quantities []; no units or measurements are fabricated.

        at least 1 items · at most 3 items

  • 400

    Client refusal unrelated to authentication, including malformed input, a denied or failed request.

  • 401

    The request carries no credential, more than one, or one the platform does not accept, and is refused before the operation runs; `error.code` says why. Supply exactly one credential. Codes: invalid-request (no credential, or both Authorization:

    Leer más

    Bearer and x-api-key), api-key-invalid (a value that is not a platform API key, or a key of a kind the platform does not accept), api-key-unknown, api-key-revoked, api-key-expired, bootstrap-disabled (the one-shot installation credential, once a key exists), token-malformed (a bearer token that is not a JWT), token-algorithm-unsupported, token-signature-invalid, token-claim-invalid, token-issuer-mismatch, token-audience-mismatch, token-expired, token-not-yet-valid, issuer-untrusted, issuer-residency-mismatch (the issuer belongs to another plane), issuer-resolution-unknown, jwks-unavailable, jwks-key-not-found, staff-token-inactive (a platform operator's token), staff-not-operator, staff-directory-unavailable, identity-not-provisioned (a verified identity with no account on this plane), organization-not-found (a verified identity or key whose organization this plane does not know), internal-error (a fault while the credential is checked is refused too, fail closed), context-cancelled

  • 402

    The organization has to pay first: its standing is payment_required.

    Leer más

    The request boundary applies this payment gate to every route except an organization's billing routes, the caller's own context, organization list, onboarding, session report and personal keys, the public routes, and the routes of platform operators, who administer an organization that has to pay. The operations the gate covers declare this response. On /v1 the refusal is rendered in the OpenAI error format. Code: payment-required

  • 403

    The credential is valid but may not do this here; the request is refused by the request boundary before the handler runs, and `error.code` says which refusal. An operation may add codes of its own.

    Leer más

    Codes: policy-denied (no role of the caller holds the permission the operation needs, or the credential class may not call it: a personal API key outside inference and MCP, a route that needs a signed-in person, the one-shot installation credential outside its three steps), tenant-mismatch (the organization a path, query, body or X-Tenant header names is not the caller's own), organization-provisioning, organization-suspended, organization-disabled, organization-deleted (the state of the caller's organization), user-disabled, residency-mismatch (the organization lives on another plane), organization-selection-required (a caller with more than one organization, or a platform operator, must name one in X-Organization-Id), organization-not-selectable, no-active-organization-membership, team-not-selectable (the X-Organization-Id or X-Team-Id the caller sent does not name an organization or team it may act in), identity-managed-by-provider (a person who is not a platform operator changes an organization's status, which belongs to the identity provider), support-session-required (a platform operator reads an organization's data without an open support session)

  • 405

    The path is claimed but the request method is not allowed. Go ServeMux returns its standard plain-text response and lists permitted methods in Allow.

  • 500

    Platform failure, rendered without internal cause details.

  • 503

    A dependency the operation needs is not configured on this plane or could not be reached, and nothing was changed. `error.code` names it; an operation lists the ones it can answer besides the boundary's. Retry later. Codes: support-audit-unavailable (the request boundary: an operator's read under an open support session could not be recorded, so nothing was served)

Respuesta de ejemplo
{
  "organization_id": "acme",
  "window": {
    "from": "2026-10-12T00:00:00Z",
    "to": "2026-10-14T00:00:00Z"
  },
  "scopes": [
    {
      "accounting_scope": "provider_attempt",
      "records": "5",
      "request_count": "5",
      "tool_call_count": "0",
      "quantities": [
        {
          "unit": "input_tokens",
          "amount": "1840"
        },
        {
          "unit": "output_tokens",
          "amount": "3122"
        }
      ],
      "measurement_counts": {
        "measured": "5",
        "estimated": "0",
        "unknown": "0"
      },
      "outcome_counts": {
        "success": "4",
        "error": "1",
        "canceled": "0",
        "unknown": "0"
      }
    }
  ],
  "models": [
    {
      "accounting_scope": "provider_attempt",
      "model_alias": "gpt-4o",
      "records": "3",
      "request_count": "3",
      "tool_call_count": "0",
      "quantities": [
        {
          "unit": "input_tokens",
          "amount": "1200"
        },
        {
          "unit": "output_tokens",
          "amount": "3122"
        }
      ],
      "measurement_counts": {
        "measured": "3",
        "estimated": "0",
        "unknown": "0"
      },
      "outcome_counts": {
        "success": "2",
        "error": "1",
        "canceled": "0",
        "unknown": "0"
      }
    },
    {
      "accounting_scope": "provider_attempt",
      "model_alias": "embed-1",
      "records": "2",
      "request_count": "2",
      "tool_call_count": "0",
      "quantities": [
        {
          "unit": "input_tokens",
          "amount": "640"
        }
      ],
      "measurement_counts": {
        "measured": "2",
        "estimated": "0",
        "unknown": "0"
      },
      "outcome_counts": {
        "success": "2",
        "error": "0",
        "canceled": "0",
        "unknown": "0"
      }
    }
  ],
  "by_principal": [
    {
      "accounting_scope": "provider_attempt",
      "principal_ref": "svc/01K7YP2C9W4X5E8H3J6M0N1Q2R",
      "principal_class": "service",
      "email": null,
      "display_name": "billing-app",
      "records": "5",
      "request_count": "5",
      "tool_call_count": "0",
      "quantities": [
        {
          "unit": "input_tokens",
          "amount": "1840"
        },
        {
          "unit": "output_tokens",
          "amount": "3122"
        }
      ],
      "measurement_counts": {
        "measured": "5",
        "estimated": "0",
        "unknown": "0"
      },
      "outcome_counts": {
        "success": "4",
        "error": "1",
        "canceled": "0",
        "unknown": "0"
      }
    }
  ],
  "by_principal_truncated": false,
  "cost": {
    "status": "unavailable"
  },
  "series": [
    {
      "window": {
        "from": "2026-10-12T00:00:00Z",
        "to": "2026-10-13T00:00:00Z"
      },
      "scopes": [
        {
          "accounting_scope": "provider_attempt",
          "records": "3",
          "request_count": "3",
          "tool_call_count": "0",
          "quantities": [
            {
              "unit": "input_tokens",
              "amount": "1000"
            },
            {
              "unit": "output_tokens",
              "amount": "1800"
            }
          ],
          "measurement_counts": {
            "measured": "3",
            "estimated": "0",
            "unknown": "0"
          },
          "outcome_counts": {
            "success": "3",
            "error": "0",
            "canceled": "0",
            "unknown": "0"
          }
        }
      ]
    },
    {
      "window": {
        "from": "2026-10-13T00:00:00Z",
        "to": "2026-10-14T00:00:00Z"
      },
      "scopes": [
        {
          "accounting_scope": "provider_attempt",
          "records": "2",
          "request_count": "2",
          "tool_call_count": "0",
          "quantities": [
            {
              "unit": "input_tokens",
              "amount": "840"
            },
            {
              "unit": "output_tokens",
              "amount": "1322"
            }
          ],
          "measurement_counts": {
            "measured": "2",
            "estimated": "0",
            "unknown": "0"
          },
          "outcome_counts": {
            "success": "1",
            "error": "1",
            "canceled": "0",
            "unknown": "0"
          }
        }
      ]
    }
  ]
}
GET/metering/v1/usage/page

List recent usage for the selected organization

Credencial
API key
Permiso
Cualquiera deusage.read_ownusage.readsupport-access.read

The organization is derived exclusively from the verified actor context; tenant or organization query parameters are not accepted. Reads occurred_at in a half-open UTC interval and returns a bounded page, in descending occurrence time with deterministic ledger-identity tie breaking.

Leer más

The cursor is bound to the organization, frozen window, model filter, accounting-scope filter, principal filter, and API key filter, so a continuation cannot move to another tenant or time range. Counts and quantities preserve exact string values. Unknown or duplicate query parameters, invalid windows, and invalid cursors return 400; a missing selected organization returns 403. An empty window returns records [] and next_cursor null. Optional model_alias, accounting_scope and principal filters (the principal filter takes a principal_ref or an email, like the request-log filter of the same name) apply to the full requested window before aggregation or pagination; filtering never operates on a truncated request page. Requires usage.read_own (at any level) or usage.read. WHICH usage: a caller holding usage.read at organization level (the Administrator role) reads every principal's usage; a caller holding usage.read_own without it - the built-in User role, and a Team Admin, whose usage.read applies to its team's request log and not to this report - reads ONLY the usage whose principal is themselves (a member's own user principal and personal API keys, a service account the usage it made), whatever the request carries: the principal filter is forced to the caller's own reference, so a principal filter naming anyone else, by reference or by email, matches nothing (200 with an empty result, never an error and never a hint of whose usage it is - the request log's narrowing) and by_principal holds only the caller. WITH AN API KEY: these routes answer a service-account API key sent in x-api-key or as Authorization: Bearer, on the console host of the key's own organization and region; a personal API key reaches inference and MCP only and is refused here with 403 policy-denied. A key whose role holds usage.read_own without usage.read reads ONLY the usage made with that key: the facts whose api_key_id is the key's own key_id, not everything its service account made. Whatever the request carries, the read stays bound to that key and to its service account: an api_key_id naming another key (of the same service account or of anyone else) and a principal naming anyone else match nothing (200 with an empty result, never an error), and the key's own id or reference is the same read as no filter. A key whose role holds usage.read at organization level reads the organization's usage exactly as the Administrator role does and may narrow it to one key with api_key_id. Neither level reads another organization: the organization is the key's own and no parameter or header names it. A revoked or expired key is 401 api-key-revoked or api-key-expired, as on every route; an organization with no active subscription is refused with 402 payment-required before any role is checked. For a key reading only its own usage the cursor freezes the key's id and its service account's reference, so a cursor of a read of the organization's usage is refused with 400 invalid-request and a cursor of another key reads nothing. A caller holding neither permission is 403 policy-denied. For a caller reading only their own usage the cursor freezes their own reference as the principal filter, so a cursor minted for a read of everyone's usage (or for anyone else) is refused with 400.

curl
curl "https://console.latam.ccsio.ai/metering/v1/usage/page" \
  -H "Authorization: Bearer $CCSIO_API_KEY"

Parámetros

NombreEnDescripción
X-Request-ID
opcional
headerstring

Optional request ULID. A valid ULID (upper or lowercase) is honored; when the header is absent or invalid, the runtime mints the id. The response X-Request-ID header carries the canonical uppercase form.

from
opcional
querystring

Inclusive UTC RFC 3339 start (must end in Z; fractional seconds allowed). Supply both from and to or omit both for the last 7 days, or the cursor's frozen window when paging. The interval must be positive and at most 90 days.

to
opcional
querystring

Exclusive UTC RFC 3339 end (must end in Z; fractional seconds allowed). Required when from is supplied.

model_alias
opcional
querystring

Optional exact model reference, preserving case and punctuation. Omit for all models; a valid reference with no matching usage returns empty totals and zero daily buckets.

accounting_scope
opcional
querystring

Optional accounting scope. Omit for all scopes, which remain separate in every aggregate; the literal all is not accepted.

principal
opcional
queryone of

Optional.

Leer más

Narrows every total, daily bucket and breakdown of the response to the usage made by this principal: the principal_ref (a C0 reference) or an email address (it contains '@'), matched case-insensitively against the organization's users and resolved to their refs, exactly as the request-log principal filter does. A reference matches the usage of that principal_ref whatever its principal_class (a member's own sessions and personal API keys share their reference). An email filter follows the visibility rule of the emails themselves: a caller who may not read the organization's member list (members.read at organization level, or a platform administrator) may filter only by their own email, any other address matches no usage; an address that matches no user matches no usage (a 200 with empty scopes, models and by_principal, zero daily buckets or an empty page — not an error — so the filter cannot be used to probe whose address it is). A value that is neither a reference nor a plain email address (no display name, no whitespace, at most 254 bytes) renders 400 invalid-request. On the page read the cursor is bound to the filter as it was typed. The platform operator's summary (platform-usage.read) is not per user: there this filter renders 400 invalid-request. For an API key reading only its own usage, a principal other than its service account's matches no usage.

api_key_id
opcional
querystring

Optional. Narrows every total, daily bucket and breakdown of the response (or every record of the page) to the usage made with this API key: the facts whose api_key_id is this value, the key's key_id in the identity API.

Leer más

Usage made from a console session carries no key and never matches, and neither does usage recorded before the usage fact carried the key (2026-10-06) nor a tool call through the MCP endpoint. A key that made no usage in the window gives a 200 with empty scopes, models and by_principal, zero daily buckets or an empty page, not an error. A value outside the key id grammar renders 400 invalid-request. On the page read the cursor is bound to the filter. The platform operator's summary (platform-usage.read) is not per user: there this filter renders 400 invalid-request. For an API key whose role holds usage.read_own without usage.read, the read is already bound to that key's own id: its own key_id is the same read as no filter, and any other id (of its service account's other keys too) gives a 200 with an empty result.

operation_class
opcional
querystring

Optional. Narrows every total, daily bucket and breakdown of the response (or every record of the page) to one class of usage. `inference` is the usage of models: every fact whose operation is not `tool`. `tool` is the calls of MCP tools: the facts whose operation is `tool`, whose model_alias names the installation and the tool. Without it the read covers both, as before. A page's cursor is bound to it.

limit
opcional
queryinteger

Page size: 1 to 100 records, default 50. Anything else renders 400 invalid-request.

cursor
opcional
querystring

Opaque next_cursor from the preceding page. Omitted window and filters reuse the cursor's frozen values; explicitly supplied values must match. Version 2 binds model_alias and accounting_scope as well as organization and window. Legacy version-1 cursors are accepted only for unfiltered continuations.

Leer más

Changing any filter requires starting without a cursor. A cursor binds the organization, the window and every filter, including api_key_id; for an API key reading only its own usage it also binds the key, so it cannot be used to read another key's records.

Respuestas

  • 200

    A page of usage evidence for the selected organization.

    Esquema
    UsagePageResponse
    • organization_idstringobligatorio

      pattern ^[a-z][a-z0-9._-]{0,63}$

    • windowobjectobligatorio
      • fromstring (date-time)obligatorio

        pattern Z$

      • tostring (date-time)obligatorio

        pattern Z$

    • recordsarray of RecentUsageRecordobligatorio

      at most 100 items

      • event_idstringobligatorio

        pattern ^[a-z][a-z0-9._-]{0,127}$

      • occurred_atstring (utc-second)obligatorio

        pattern ^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}Z$

      • request_idstringobligatorio

        pattern ^[a-z][a-z0-9._-]{0,127}$

      • model_aliasstringobligatorio

        Original selected model reference, preserved byte-for-byte under the C0 model registry grammar.

        pattern ^[A-Za-z0-9][A-Za-z0-9._:/-]{0,127}$

      • provider_classanyobligatorio

        Valores permitidos: "CCSIO_INFERENCE""CUSTOMER_HOSTED""EXTERNAL_MANAGED"null

      • operationstringobligatorio

        Valores permitidos: "chat""embedding""audio""image""document""tool""agent_overhead""responses""decision"

      • accounting_scopestringobligatorio

        Valores permitidos: "provider_attempt""platform_overhead""agent_aggregate"

      • measurementstringobligatorio

        Valores permitidos: "measured""estimated""unknown"

      • outcome_classstringobligatorio

        Valores permitidos: "success""error""canceled""unknown"

      • request_duration_msinteger or nullobligatorio

        Whole router request timing, shared by all attempt records; absent on legacy records.

        0 to 9007199254740991

      • quantitiesarray of UsageQuantityobligatorio
      • request_countstringobligatorio

        An exact non-negative integer serialized as a string to avoid client precision loss.

        pattern ^(0|[1-9][0-9]*)$

      • tool_call_countstringobligatorio

        An exact non-negative integer serialized as a string to avoid client precision loss.

        pattern ^(0|[1-9][0-9]*)$

    • next_cursorstring or nullobligatorio

      Opaque continuation cursor bound to the selected organization, frozen window, exact model reference and accounting scope; null when there are no more records.

      at most 2048 characters

  • 400

    Client refusal unrelated to authentication, including malformed input, a denied or failed request.

  • 401

    The request carries no credential, more than one, or one the platform does not accept, and is refused before the operation runs; `error.code` says why. Supply exactly one credential. Codes: invalid-request (no credential, or both Authorization:

    Leer más

    Bearer and x-api-key), api-key-invalid (a value that is not a platform API key, or a key of a kind the platform does not accept), api-key-unknown, api-key-revoked, api-key-expired, bootstrap-disabled (the one-shot installation credential, once a key exists), token-malformed (a bearer token that is not a JWT), token-algorithm-unsupported, token-signature-invalid, token-claim-invalid, token-issuer-mismatch, token-audience-mismatch, token-expired, token-not-yet-valid, issuer-untrusted, issuer-residency-mismatch (the issuer belongs to another plane), issuer-resolution-unknown, jwks-unavailable, jwks-key-not-found, staff-token-inactive (a platform operator's token), staff-not-operator, staff-directory-unavailable, identity-not-provisioned (a verified identity with no account on this plane), organization-not-found (a verified identity or key whose organization this plane does not know), internal-error (a fault while the credential is checked is refused too, fail closed), context-cancelled

  • 402

    The organization has to pay first: its standing is payment_required.

    Leer más

    The request boundary applies this payment gate to every route except an organization's billing routes, the caller's own context, organization list, onboarding, session report and personal keys, the public routes, and the routes of platform operators, who administer an organization that has to pay. The operations the gate covers declare this response. On /v1 the refusal is rendered in the OpenAI error format. Code: payment-required

  • 403

    The credential is valid but may not do this here; the request is refused by the request boundary before the handler runs, and `error.code` says which refusal. An operation may add codes of its own.

    Leer más

    Codes: policy-denied (no role of the caller holds the permission the operation needs, or the credential class may not call it: a personal API key outside inference and MCP, a route that needs a signed-in person, the one-shot installation credential outside its three steps), tenant-mismatch (the organization a path, query, body or X-Tenant header names is not the caller's own), organization-provisioning, organization-suspended, organization-disabled, organization-deleted (the state of the caller's organization), user-disabled, residency-mismatch (the organization lives on another plane), organization-selection-required (a caller with more than one organization, or a platform operator, must name one in X-Organization-Id), organization-not-selectable, no-active-organization-membership, team-not-selectable (the X-Organization-Id or X-Team-Id the caller sent does not name an organization or team it may act in), identity-managed-by-provider (a person who is not a platform operator changes an organization's status, which belongs to the identity provider), support-session-required (a platform operator reads an organization's data without an open support session)

  • 405

    The path is claimed but the request method is not allowed. Go ServeMux returns its standard plain-text response and lists permitted methods in Allow.

  • 500

    Platform failure, rendered without internal cause details.

  • 503

    A dependency the operation needs is not configured on this plane or could not be reached, and nothing was changed. `error.code` names it; an operation lists the ones it can answer besides the boundary's. Retry later. Codes: support-audit-unavailable (the request boundary: an operator's read under an open support session could not be recorded, so nothing was served)

Respuesta de ejemplo
{
  "organization_id": "acme",
  "window": {
    "from": "2026-10-12T00:00:00Z",
    "to": "2026-10-14T00:00:00Z"
  },
  "records": [
    {
      "event_id": "event.req-01k7yqa2c4e6g8j0m2p4r6t8v0",
      "occurred_at": "2026-10-13T16:41:02Z",
      "request_id": "req-01k7yqa2c4e6g8j0m2p4r6t8v0",
      "model_alias": "gpt-4o",
      "provider_class": "CCSIO_INFERENCE",
      "operation": "chat",
      "accounting_scope": "provider_attempt",
      "quantities": [
        {
          "unit": "input_tokens",
          "amount": "412"
        },
        {
          "unit": "output_tokens",
          "amount": "697"
        }
      ],
      "measurement": "measured",
      "outcome_class": "success",
      "request_duration_ms": 1840,
      "request_count": "1",
      "tool_call_count": "0"
    },
    {
      "event_id": "event.req-01k7yq5v8n3m4p7r2s6t9w0x1y",
      "occurred_at": "2026-10-13T09:14:27Z",
      "request_id": "req-01k7yq5v8n3m4p7r2s6t9w0x1y",
      "model_alias": "embed-1",
      "provider_class": "CCSIO_INFERENCE",
      "operation": "embedding",
      "accounting_scope": "provider_attempt",
      "quantities": [
        {
          "unit": "input_tokens",
          "amount": "320"
        }
      ],
      "measurement": "measured",
      "outcome_class": "success",
      "request_duration_ms": 96,
      "request_count": "1",
      "tool_call_count": "0"
    }
  ],
  "next_cursor": "eyJ2Ijo0LCJ0ZW5hbnQiOiJhY21lIiwid2luZG93Ijp7ImZyb20iOiIyMDI2LTEwLTEyVDAwOjAwOjAwWiIsInRvIjoiMjAyNi0xMC0xNFQwMDowMDowMFoifSwiYWZ0ZXIiOnsiYXQiOiIyMDI2LTEwLTEzVDA5OjE0OjI3WiIsInBsYW5lIjoicGxhbmUuZXUiLCJyZXF1ZXN0IjoicmVxLTAxazd5cTV2OG4zbTRwN3IyczZ0OXcweDF5IiwiYXR0ZW1wdCI6MSwicHJvdmlkZXIiOiJcdTAwM2NudWxsXHUwMDNlIn0sInByaW5jaXBhbCI6InN2Yy8wMUs3WVAyQzlXNFg1RThIM0o2TTBOMVEyUiIsImFwaV9rZXlfaWQiOiIwMUs3WVAzQTVUOFEyTjZSNFYxVzlYWkI3RCJ9"
}

Generado a partir de los contratos de la plataforma en el commit 5f833620.

Explora la plataforma

Obtén tu primera key API

El registro está abierto. Cuatro pasos hasta tu primera llamada: crea tu cuenta, crea tu organización, crea tu API key y empieza a usarla.

  1. 01Crea tu cuenta
  2. 02Crea tu organización
  3. 03Crea tu API key
  4. 04Empieza a usarla