Zum Hauptinhalt springen
DokumentationNutzung · console.eu.ccsio.ai

Usage

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

Menü der Dokumentation

Die Beschreibungen der Operationen und Felder stammen aus dem Vertrag und sind auf Englisch.

GET/metering/v1/usage

Read a usage fact back by idempotency key

Anmeldedaten
API-Key
Berechtigung
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.eu.ccsio.ai/metering/v1/usage?idempotency_key=<idempotency_key>" \
  -H "Authorization: Bearer $CCSIO_API_KEY"

Parameter

NameInBeschreibung
X-Request-ID
optional
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
Pflicht
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.

Antworten

  • 200

    The usage fact, in its C2 wire form.

    Schema
    UsageRecord
    • deployment_idstring or nulloptional

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

    • provider_classanyoptional

      Erlaubte Werte: "CCSIO_INFERENCE""CUSTOMER_HOSTED""EXTERNAL_MANAGED"null

    • request_duration_msinteger or nulloptional

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

      0 to 9007199254740991

    • request_ttft_msinteger or nulloptional

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

      0 to 9007199254740991

    • session_idstring or nulloptional

      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 nulloptional

      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 nulloptional

      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 nulloptional

      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_versionanyPflicht

      always "c2/v1"

    • event_idstringPflicht

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

    • idempotency_keyobjectPflicht
      • tenant_idstringPflicht

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

      • plane_instance_idstringPflicht

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

      • request_or_run_idstringPflicht

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

      • attemptintegerPflicht

        1 to 9007199254740991

      • provider_response_idone of or nullPflicht

        Eines von

        • #1stringoptional

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

        • #2anyoptional

          always ""

    • occurred_atstring (utc-second)Pflicht

      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)Pflicht

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

    • monotonic_since_boot_msintegerPflicht

      0 to 9007199254740991

    • seqobjectPflicht
      • stream_idstringPflicht

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

      • nintegerPflicht

        1 to 9007199254740991

    • meter_epochstringPflicht

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

    • tenant_idstringPflicht

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

    • team_idstring or nullPflicht

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

    • principal_classstringPflicht

      Erlaubte Werte: "user""service""agent"

    • principal_refstringPflicht

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

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

    • planestringPflicht

      Erlaubte Werte: "ai""agent""memory""brain"

    • operationstringPflicht

      Erlaubte Werte: "chat""embedding""audio""image""document""tool""agent_overhead""responses""decision"

    • accounting_scopestringPflicht

      Erlaubte Werte: "provider_attempt""platform_overhead""agent_aggregate"

    • model_aliasstringPflicht

      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_digeststringPflicht

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

    • request_idstringPflicht

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

    • run_idstring or nullPflicht

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

    • agent_idstring or nullPflicht

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

    • agent_spec_digeststring or nullPflicht

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

    • quantitiesarray of objectPflicht

      at most 16 items

      • unitstringPflicht

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

      • amountstringPflicht

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

    • measurementstringPflicht

      Erlaubte Werte: "measured""estimated""unknown"

    • measurement_reasonstring or nullPflicht

      Erlaubte Werte: "coarse_counter""provider_estimate""final_usage_missing""meter_loss""canceled""implausible_count"

    • duration_msinteger or nullPflicht

      0 to 9007199254740991

    • ttft_msinteger or nullPflicht

      0 to 9007199254740991

    • request_countintegerPflicht

      0 to 9007199254740991

    • tool_call_countintegerPflicht

      0 to 9007199254740991

    • outcome_classstringPflicht

      Erlaubte Werte: "success""error""canceled""unknown"

    • data_classificationstringPflicht

      Erlaubte Werte: "public""internal""restricted"

    • routing_inputsobjectPflicht
      • rule_idsarray of stringPflicht

        at most 16 items

      • classification_labelstringPflicht

        Erlaubte Werte: "public""internal""restricted"

      • priority_groupstringPflicht

        Erlaubte Werte: "low""normal""high"

    • routing_inputs_digeststringPflicht

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

    • bundle_versionintegerPflicht

      1 to 9007199254740991

    • bundle_digeststringPflicht

      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:

    Weiterlesen

    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.

    Weiterlesen

    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.

    Weiterlesen

    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

Anmeldedaten
API-Key
Berechtigung
usage.manage
Request-Body
Body bis 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.

Weiterlesen

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.eu.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"
}'
Aus den Pflichtfeldern des Schemas erzeugt: ersetze die Werte.

Parameter

NameInBeschreibung
X-Request-ID
optional
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.

Request-Body application/json

UsageRecord
  • deployment_idstring or nulloptional

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

  • provider_classanyoptional

    Erlaubte Werte: "CCSIO_INFERENCE""CUSTOMER_HOSTED""EXTERNAL_MANAGED"null

  • request_duration_msinteger or nulloptional

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

    0 to 9007199254740991

  • request_ttft_msinteger or nulloptional

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

    0 to 9007199254740991

  • session_idstring or nulloptional

    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 nulloptional

    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 nulloptional

    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 nulloptional

    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_versionanyPflicht

    always "c2/v1"

  • event_idstringPflicht

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

  • idempotency_keyobjectPflicht
    • tenant_idstringPflicht

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

    • plane_instance_idstringPflicht

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

    • request_or_run_idstringPflicht

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

    • attemptintegerPflicht

      1 to 9007199254740991

    • provider_response_idone of or nullPflicht

      Eines von

      • #1stringoptional

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

      • #2anyoptional

        always ""

  • occurred_atstring (utc-second)Pflicht

    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)Pflicht

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

  • monotonic_since_boot_msintegerPflicht

    0 to 9007199254740991

  • seqobjectPflicht
    • stream_idstringPflicht

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

    • nintegerPflicht

      1 to 9007199254740991

  • meter_epochstringPflicht

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

  • tenant_idstringPflicht

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

  • team_idstring or nullPflicht

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

  • principal_classstringPflicht

    Erlaubte Werte: "user""service""agent"

  • principal_refstringPflicht

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

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

  • planestringPflicht

    Erlaubte Werte: "ai""agent""memory""brain"

  • operationstringPflicht

    Erlaubte Werte: "chat""embedding""audio""image""document""tool""agent_overhead""responses""decision"

  • accounting_scopestringPflicht

    Erlaubte Werte: "provider_attempt""platform_overhead""agent_aggregate"

  • model_aliasstringPflicht

    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_digeststringPflicht

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

  • request_idstringPflicht

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

  • run_idstring or nullPflicht

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

  • agent_idstring or nullPflicht

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

  • agent_spec_digeststring or nullPflicht

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

  • quantitiesarray of objectPflicht

    at most 16 items

    • unitstringPflicht

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

    • amountstringPflicht

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

  • measurementstringPflicht

    Erlaubte Werte: "measured""estimated""unknown"

  • measurement_reasonstring or nullPflicht

    Erlaubte Werte: "coarse_counter""provider_estimate""final_usage_missing""meter_loss""canceled""implausible_count"

  • duration_msinteger or nullPflicht

    0 to 9007199254740991

  • ttft_msinteger or nullPflicht

    0 to 9007199254740991

  • request_countintegerPflicht

    0 to 9007199254740991

  • tool_call_countintegerPflicht

    0 to 9007199254740991

  • outcome_classstringPflicht

    Erlaubte Werte: "success""error""canceled""unknown"

  • data_classificationstringPflicht

    Erlaubte Werte: "public""internal""restricted"

  • routing_inputsobjectPflicht
    • rule_idsarray of stringPflicht

      at most 16 items

    • classification_labelstringPflicht

      Erlaubte Werte: "public""internal""restricted"

    • priority_groupstringPflicht

      Erlaubte Werte: "low""normal""high"

  • routing_inputs_digeststringPflicht

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

  • bundle_versionintegerPflicht

    1 to 9007199254740991

  • bundle_digeststringPflicht

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

Antworten

  • 200

    The usage record was ingested (or redelivered).

    Schema
    IngestResponse
    • statusstringPflicht

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

      Erlaubte Werte: "ingested""redelivered"

    • event_idstringoptional

      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}$

    • checkpointobjectoptional

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

      • tenant_idstringPflicht

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

      • plane_instance_idstringPflicht

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

      • stream_idstringPflicht

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

      • contiguous_usage_throughintegerPflicht

        0 to 9007199254740991

      • usage_high_waterintegerPflicht

        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:

    Weiterlesen

    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.

    Weiterlesen

    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.

    Weiterlesen

    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

Anmeldedaten
API-Key
Berechtigung
Eine vonusage.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.

Weiterlesen

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.eu.ccsio.ai/metering/v1/usage/summary" \
  -H "Authorization: Bearer $CCSIO_API_KEY"

Parameter

NameInBeschreibung
X-Request-ID
optional
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
optional
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
optional
querystring

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

model_alias
optional
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
optional
querystring

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

principal
optional
queryone of

Optional.

Weiterlesen

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
optional
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.

Weiterlesen

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
optional
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.

Antworten

  • 200

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

    Schema
    UsageSummaryResponse
    • organization_idstringPflicht

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

    • windowobjectPflicht
      • fromstring (date-time)Pflicht

        pattern Z$

      • tostring (date-time)Pflicht

        pattern Z$

    • scopesarray of UsageSummaryScopePflicht

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

      • accounting_scopestringPflicht

        Erlaubte Werte: "provider_attempt""platform_overhead""agent_aggregate"

      • recordsUsageCountPflicht

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

      • request_countUsageCountPflicht

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

      • tool_call_countUsageCountPflicht

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

      • quantitiesarray of UsageQuantityPflicht
      • measurement_countsobjectPflicht
        • measuredUsageCountPflicht

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

        • estimatedUsageCountPflicht

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

        • unknownUsageCountPflicht

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

      • outcome_countsobjectPflicht
        • successUsageCountPflicht

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

        • errorUsageCountPflicht

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

        • canceledUsageCountPflicht

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

        • unknownUsageCountPflicht

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

    • modelsarray of UsageSummaryModelPflicht

      Metrics grouped by the pair (accounting_scope, model_alias).

      • accounting_scopestringPflicht

        Erlaubte Werte: "provider_attempt""platform_overhead""agent_aggregate"

      • recordsUsageCountPflicht

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

      • request_countUsageCountPflicht

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

      • tool_call_countUsageCountPflicht

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

      • quantitiesarray of UsageQuantityPflicht
      • measurement_countsobjectPflicht
        • measuredUsageCountPflicht

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

        • estimatedUsageCountPflicht

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

        • unknownUsageCountPflicht

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

      • outcome_countsobjectPflicht
        • successUsageCountPflicht

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

        • errorUsageCountPflicht

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

        • canceledUsageCountPflicht

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

        • unknownUsageCountPflicht

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

      • model_aliasstringPflicht

        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 UsageSummaryPrincipalPflicht

      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_scopestringPflicht

        Erlaubte Werte: "provider_attempt""platform_overhead""agent_aggregate"

      • recordsUsageCountPflicht

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

      • request_countUsageCountPflicht

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

      • tool_call_countUsageCountPflicht

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

      • quantitiesarray of UsageQuantityPflicht
      • measurement_countsobjectPflicht
        • measuredUsageCountPflicht

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

        • estimatedUsageCountPflicht

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

        • unknownUsageCountPflicht

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

      • outcome_countsobjectPflicht
        • successUsageCountPflicht

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

        • errorUsageCountPflicht

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

        • canceledUsageCountPflicht

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

        • unknownUsageCountPflicht

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

      • principal_refstringPflicht

        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_classstringPflicht

        Erlaubte Werte: "user""service""agent"

      • emailstring or nullPflicht

        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 nullPflicht

        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_truncatedbooleanPflicht

      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.

    • costobjectPflicht
      • statusstringPflicht

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

        always "unavailable"

    • seriesarray of UsageSeriesBucketPflicht

      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

      • windowobjectPflicht
        • fromstring (date-time)Pflicht

          pattern Z$

        • tostring (date-time)Pflicht

          pattern Z$

      • scopesarray of UsageSummaryScopePflicht

        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:

    Weiterlesen

    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.

    Weiterlesen

    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.

    Weiterlesen

    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)

Beispielantwort
{
  "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

Anmeldedaten
API-Key
Berechtigung
Eine vonusage.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.

Weiterlesen

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.eu.ccsio.ai/metering/v1/usage/page" \
  -H "Authorization: Bearer $CCSIO_API_KEY"

Parameter

NameInBeschreibung
X-Request-ID
optional
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
optional
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
optional
querystring

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

model_alias
optional
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
optional
querystring

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

principal
optional
queryone of

Optional.

Weiterlesen

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
optional
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.

Weiterlesen

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
optional
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
optional
queryinteger

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

cursor
optional
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.

Weiterlesen

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.

Antworten

  • 200

    A page of usage evidence for the selected organization.

    Schema
    UsagePageResponse
    • organization_idstringPflicht

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

    • windowobjectPflicht
      • fromstring (date-time)Pflicht

        pattern Z$

      • tostring (date-time)Pflicht

        pattern Z$

    • recordsarray of RecentUsageRecordPflicht

      at most 100 items

      • event_idstringPflicht

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

      • occurred_atstring (utc-second)Pflicht

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

      • request_idstringPflicht

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

      • model_aliasstringPflicht

        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_classanyPflicht

        Erlaubte Werte: "CCSIO_INFERENCE""CUSTOMER_HOSTED""EXTERNAL_MANAGED"null

      • operationstringPflicht

        Erlaubte Werte: "chat""embedding""audio""image""document""tool""agent_overhead""responses""decision"

      • accounting_scopestringPflicht

        Erlaubte Werte: "provider_attempt""platform_overhead""agent_aggregate"

      • measurementstringPflicht

        Erlaubte Werte: "measured""estimated""unknown"

      • outcome_classstringPflicht

        Erlaubte Werte: "success""error""canceled""unknown"

      • request_duration_msinteger or nullPflicht

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

        0 to 9007199254740991

      • quantitiesarray of UsageQuantityPflicht
      • request_countstringPflicht

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

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

      • tool_call_countstringPflicht

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

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

    • next_cursorstring or nullPflicht

      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:

    Weiterlesen

    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.

    Weiterlesen

    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.

    Weiterlesen

    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)

Beispielantwort
{
  "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"
}

Erzeugt aus den Plattformverträgen beim Commit 5f833620.

Plattform entdecken

Deinen ersten API-Key holen

Die Registrierung ist offen. Vier Schritte bis zum ersten Aufruf: Konto erstellen, Organisation anlegen, API-Key erzeugen, loslegen.

  1. 01Konto erstellen
  2. 02Organisation anlegen
  3. 03API-Key erzeugen
  4. 04Loslegen