Ingest Usage Event
Submits a raw usage event to a published extractor rule set. The ingest API accepts the event, writes it to the usage queue, and returns a raw event ID. Normalization, charge item expansion, rating, wallet debit, and analytics projection run asynchronously after the response.
POST /v1/projects/:project_id/extractor-rule-sets/:id/events/ingestAuthentication
Section titled “Authentication”Authorization: Bearer <api-key>Content-Type: application/jsonRequires usage ingest access. Use this endpoint only from a trusted backend, gateway, or server-side SDK.
Path Parameters
Section titled “Path Parameters”| Field | Required | Description |
|---|---|---|
project_id |
Yes | Project that owns the ingest stream and usage analytics boundary. |
id |
Yes | Published extractor rule set ID used to normalize this event. |
Request Body
Section titled “Request Body”{ "source": "openai-gateway", "external_event_id": "chatcmpl_123", "idempotency_key": "openai-gateway:chatcmpl_123", "subject_type": "organization", "subject_id": "org_001", "occurred_at": 1781222400, "raw_json": { "type": "response", "provider": "openai", "usage": { "model": "gpt-4.1-mini", "prompt_tokens": 1200, "output_tokens": 300 }, "meta": { "org_id": "org_001", "user_id": "user_123", "api_key_id": "key_001" } }, "x-billing": { "items": [ { "metric": "tool_call.web_search", "quantity": 1, "unit": "call" } ], "pricing_hints": { "tool_call.web_search": { "unit_price": 0.1, "pricing_unit": 1, "currency": "USD" } } }, "x-usage-control": { "budget_lease_id": "ble_..." }, "metadata": { "gateway_region": "us-east-1" }}| Field | Required | Description |
|---|---|---|
source |
Yes | Stable event source name, for example openai-gateway, agent-runtime, or workflow-engine. |
external_event_id |
No | Upstream event or request ID. Useful for support and reconciliation. |
idempotency_key |
No | Stable retry key. Reusing the same key with the same tenant_id, project_id, and occurred_at produces the same raw_event_id and prevents duplicate raw event facts during processing. |
subject_type |
Conditionally | Explicit subject type for this event. Must match [a-z][a-z0-9_]{0,63} and be provided together with subject_id. |
subject_id |
Conditionally | Explicit subject ID for this event. Must be provided together with subject_type. |
occurred_at |
Yes | Event occurrence time as Unix seconds. Required for partition routing and idempotency. |
raw_json |
Yes | Original usage JSON. The extractor rule set decides which fields become subject, dimensions, and charge items. |
x-billing |
No | Dynamic billing extension at the same request level as metadata. Use it for sparse request-level charge items and pricing or discount hints. |
x-usage-control |
No | Usage-control extension. Set budget_lease_id for a one-time agent-run budget. Billing snapshots it for audit and advances that Lease only after rating. |
metadata |
No | Ingest-side metadata for audit or operations. Keep this small and non-sensitive. |
The quota admission is performed for every ingest attempt. If the HTTP response
is lost after the event was accepted and you retry with the same
idempotency_key, the raw event is deduplicated downstream, but the retry still
counts as a new ingest attempt for the realtime quota. Do not use retries to
probe quota availability.
Example
Section titled “Example”curl 'http://127.0.0.1:8080/v1/projects/proj_gateway/extractor-rule-sets/ers_openai/events/ingest' \ -X POST \ -H 'Authorization: Bearer <api-key>' \ -H 'Content-Type: application/json' \ -d '{ "source": "openai-gateway", "external_event_id": "chatcmpl_123", "idempotency_key": "openai-gateway:chatcmpl_123", "subject_type": "organization", "subject_id": "org_001", "occurred_at": 1781222400, "raw_json": { "type": "response", "provider": "openai", "usage": { "model": "gpt-4.1-mini", "prompt_tokens": 1200, "output_tokens": 300 }, "meta": { "org_id": "org_001", "user_id": "user_123" } } }'Response
Section titled “Response”The API returns HTTP 202 Accepted when the event is accepted for asynchronous processing.
{ "raw_event_id": "raw_01hxy7f9q8m2", "status": "received"}Dynamic Billing
Section titled “Dynamic Billing”Use top-level x-billing.items for sparse, request-level charge items that are only known at runtime, such as optional tool calls or add-ons. pricing_hints and discount_hints are keyed by metric.
When the same metric appears in both extractor-generated charge items and x-billing.items, the reported x-billing item is treated as the source of truth for that metric.
Subject Resolution
Section titled “Subject Resolution”When both top-level subject_type and subject_id are present, Meterry uses that pair as the event subject and does not execute the extractor’s subject paths. Otherwise, it resolves each subject field from type_path or id_path, then falls back to default_type or default_id. Supplying only one top-level subject field is invalid.
- The extractor rule set must belong to the same tenant and project, and it must be published.
- Use a stable
idempotency_keyfor retryable gateway requests. - Use List Usage Event Details with
raw_event_idto inspect the processed usage event and charge items.