{"info":{"title":"Hyperline Ingest API","version":"0.0.0"},"servers":[{"url":"https://ingest.hyperline.co"},{"url":"https://sandbox.ingest.hyperline.co"}],"openapi":"3.1.0","components":{"securitySchemes":{"bearer":{"type":"http","scheme":"bearer","bearerFormat":"JWT"}},"schemas":{"PaginatedEvent":{"type":"object","properties":{"meta":{"type":"object","properties":{"total":{"type":"number","description":"Total of existing items.","example":1},"taken":{"type":"number","description":"Number of items returned.","example":1},"skipped":{"type":"number","description":"Number of items skipped.","example":0}},"required":["total","taken","skipped"]},"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"Event ID in Hyperline.","example":"evt_abc123def456"},"event_type":{"type":"string","description":"Type of the event, as defined when ingesting events.","example":"api_call"},"timestamp":{"type":"string","description":"Timestamp of when the event occurred.","example":"2024-01-15T10:30:00.000Z"},"customer_id":{"type":["string","null"],"description":"ID of the customer associated with this event.","example":"cus_xyz789"},"record_id":{"type":"string","description":"External record ID provided when ingesting the event.","example":"rec_123"},"record":{"type":"object","additionalProperties":{},"description":"JSON payload of the event record.","example":{"id":"rec_123","endpoint":"/api/users","method":"GET"}}},"required":["id","event_type","timestamp","customer_id","record_id","record"]},"description":"List of Event."}},"required":["meta","data"]},"IngestionOverloadedError":{"type":"object","properties":{"statusCode":{"type":"number","enum":[503],"example":503},"type":{"type":"string","enum":["ServiceUnavailable"],"example":"ServiceUnavailable"},"message":{"type":"string","description":"Human-readable reason for the rejection.","example":"Event ingestion is temporarily overloaded, retry in 30 seconds"},"retryAfterSeconds":{"type":"integer","description":"Seconds to wait before retrying, same value as the `Retry-After` header.","example":30}},"required":["statusCode","type","message","retryAfterSeconds"]},"BillableEvent":{"type":"object","properties":{"customer_id":{"type":"string","description":"Hyperline ID or external ID of the existing customer.","example":"cus_CrqwefTRWBWRT"},"event_type":{"type":"string","minLength":1,"description":"Type corresponding to the event. When creating a dynamic product, this type will be used to map the related events to specific prices.","example":"api_call"},"timestamp":{"type":"string","format":"date-time","description":"UTC date time string in the [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601) format, or milliseconds since the epoch. The event timestamp is used to retrieve the events related to a specific billing period.","example":"2024-12-20T16:04:11Z"},"record":{"allOf":[{"type":"object","properties":{"id":{"anyOf":[{"type":"string"},{"type":"number"}],"description":"A unique identifier for your event, used to identify the event in your system and prevent duplicates."}},"required":["id"]},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"null"}]}}],"description":"Payload of the event containing an ID and any additional metadata.","example":{"id":"D32NAA8","durationInMs":32,"isVerified":true}}},"required":["customer_id","event_type","timestamp","record"]}},"parameters":{}},"paths":{"/v1/ai/billing/consume":{"post":{"operationId":"consumeAiBilling","tags":["AI > Ingest"],"security":[{"bearer":[]}],"summary":"Consume AI usage","description":"Explicit consumption is only for customers without automatic telemetry billing; configuring a shared billing policy normally makes this return 409 telemetry_managed. Record what a customer consumed and charge it against their balance. Hyperline prices the usage itself and applies the policy markup — an amount sent by the caller is never read. The call writes one append-only ledger entry and updates the customer's balance atomically. Replaying an `idempotency_key` returns the original result unchanged.\n\nHow it charges depends on the customer's mode. In `wallet` mode the usage is priced against the workspace's resolved rates in the wallet's minor units, and the wallet ledger is not touched — a background settlement rolls entries up separately. In `credits` mode it is priced against the policy's credit rate card and the customer's credit balance is decremented for real, in the same transaction, with no settlement afterwards; a customer without enough credits is refused with a 402 and nothing is deducted, so a call is never partially charged.\n\nIn `windows` mode the usage is weighted into units and metered against every one of the customer's overlapping rolling allowances — a 5h and a 7d window, say. Each window instance is anchored at the first call after the previous one expired and runs for exactly its duration, so `resets_at` is a real instant rather than a moving average. Every window meters every call, and a call that does not fit in *all* of them is refused whole with a 402 carrying `meters` and the soonest `resets_at`: no window is incremented, so a refused call leaves no trace.","requestBody":{"description":"Consumption payload.","content":{"application/json":{"schema":{"type":"object","properties":{"customer":{"type":"string","minLength":1,"maxLength":255,"description":"Customer to bill — the external id your application knows them by, or a Hyperline `cus_…` id. Resolved exactly the way AI telemetry resolves it.","example":"acme-corp"},"agent":{"type":"string","minLength":1,"maxLength":128,"description":"The agent making the call, as `run({ agent })` names it. Optional, and absent means the customer's shared pool — which is what every call did before per-agent billing existed. Naming an agent only changes anything once an operator has given that agent a billing policy of its own; until then it resolves to the same shared pool and the response says so with `agent: null`.","example":"invoice-copilot"},"usage":{"type":"object","properties":{"llm_calls":{"type":"array","items":{"type":"object","properties":{"provider":{"type":"string","minLength":1,"maxLength":64,"description":"The model's provider, e.g. `anthropic`.","example":"anthropic"},"model":{"type":"string","minLength":1,"maxLength":128,"description":"The model invoked, e.g. `claude-sonnet-5`.","example":"claude-sonnet-5"},"input_tokens":{"type":"integer","minimum":0,"description":"Uncached input tokens.","example":12400},"output_tokens":{"type":"integer","minimum":0,"description":"Output tokens.","example":1300},"extra":{"type":["object","null"],"additionalProperties":{"type":"number","minimum":0,"maximum":1000000000000},"description":"Cost dimensions beyond the two token classes — cached input tokens, web searches, whatever the resolved rate knows how to bill. Keys must match `[a-z0-9_.]{1,64}`, values must be finite and at most 1e12, at most 20 keys.","example":{"cached_input":9000}}},"required":["provider","model","input_tokens","output_tokens"]},"maxItems":500,"description":"Model invocations to price.","example":[{"provider":"anthropic","model":"claude-sonnet-5","input_tokens":12400,"output_tokens":1300,"extra":{"cached_input":9000}}]},"items":{"type":"array","items":{"type":"object","properties":{"vendor":{"type":"string","minLength":1,"maxLength":64,"description":"The vendor the item was bought from, e.g. `exa`.","example":"exa"},"item":{"type":"string","minLength":1,"maxLength":128,"description":"The item purchased, e.g. `search`.","example":"search"},"quantity":{"type":"number","minimum":0,"description":"How many, in `unit`.","example":3},"unit":{"type":"string","minLength":1,"maxLength":64,"description":"The dimension `quantity` is counted in.","example":"units"}},"required":["vendor","item","quantity","unit"]},"maxItems":500,"description":"Non-LLM cost items to price — a search API call, a vector query.","example":[{"vendor":"exa","item":"search","quantity":3,"unit":"units"}]}},"description":"What was consumed. Priced server-side against your resolved rates — an amount sent by the client is never trusted, and never read.","example":{"llm_calls":[{"provider":"anthropic","model":"claude-sonnet-5","input_tokens":12400,"output_tokens":1300,"extra":{"cached_input":9000}}],"items":[{"vendor":"exa","item":"search","quantity":3,"unit":"units"}]}},"idempotency_key":{"type":"string","minLength":1,"maxLength":255,"description":"Replay key. Replaying it returns the original amount and breakdown unchanged, with a freshly read balance.","example":"cns_9f2c1ab4e77d3105bb0a"}},"required":["customer","usage","idempotency_key"]}}}},"responses":{"200":{"description":"Consumption recorded.","content":{"application/json":{"schema":{"type":"object","properties":{"currency":{"type":["string","null"],"enum":["EUR","AED","AFN","XCD","ALL","AMD","AOA","ARS","USD","AUD","AWG","AZN","BAM","BBD","BDT","BGN","BHD","BIF","XOF","BMD","BND","BOB","BRL","BSD","BTN","NOK","BWP","BYR","BZD","CAD","CDF","XAF","CHF","NZD","CLP","CNY","COP","CRC","CUP","CVE","ANG","CZK","DJF","DKK","DOP","DZD","EGP","MAD","ERN","ETB","FJD","FKP","GBP","GEL","GHS","GIP","GMD","GNF","GTQ","GYD","HKD","HNL","HRK","HTG","HUF","IDR","ILS","INR","IQD","IRR","ISK","JMD","JOD","JPY","KES","KGS","KHR","KMF","KPW","KRW","KWD","KYD","KZT","LAK","LBP","LKR","LRD","LSL","LYD","MDL","MGA","MKD","MMK","MNT","MOP","MRO","MUR","MVR","MWK","MXN","MYR","MZN","NAD","XPF","NGN","NIO","NPR","OMR","PAB","PEN","PGK","PHP","PKR","PLN","PYG","QAR","RON","RSD","RUB","RWF","SAR","SBD","SCR","SDG","SEK","SGD","SHP","SLL","SOS","SRD","SSP","STD","SYP","SZL","THB","TJS","TMT","TND","TOP","TRY","TTD","TWD","TZS","UAH","UGX","UYU","UZS","VEF","VND","VUV","WST","YER","ZAR","ZMW","ZWL"],"description":"ISO 4217 currency code for monetary amounts. Null for counts or historical amounts without recorded currency.","example":"USD"},"agent":{"type":["string","null"],"description":"The billing scope that answered: the agent's own slug when it has a policy of its own, and null when the customer's shared pool answered — including when an agent was named but has no policy of its own.","example":"invoice-copilot"},"amount":{"type":"string","pattern":"^-?\\d+(\\.\\d+)?(e[+-]?\\d+)?$/i","description":"Total charged, at full precision — a sub-cent model call is not rounded away, and neither is a fractional credit.","example":"4.182"},"denomination":{"type":"string","enum":["minor_units","credits","units"],"description":"Unit of account for amounts.\n\n- minor_units: Fractional minor units of the accompanying currency.\n- credits: Credit counts, without a currency.\n- units: Weighted rolling-allowance units, without a currency.","example":"minor_units"},"breakdown":{"type":"array","items":{"type":"object","properties":{"kind":{"type":"string","enum":["llm_call","item","markup"],"description":"Receipt line kind.\n\n- llm_call: Model usage.\n- item: Non-LLM cost-item usage.\n- markup: Pricing markup applied to usage.","example":"llm_call"},"provider":{"type":["string","null"],"description":"The provider or vendor the line prices. Null on a markup line.","example":"anthropic"},"model":{"type":["string","null"],"description":"The model or item the line prices. Null on a markup line.","example":"claude-sonnet-5"},"quantity":{"type":["string","null"],"pattern":"^-?\\d+(\\.\\d+)?(e[+-]?\\d+)?$/i","description":"How much was priced, in `unit`. Null on a markup line.","example":"12400"},"unit":{"type":["string","null"],"description":"The dimension `quantity` is counted in. Null on a markup line.","example":"tokens"},"amount":{"type":"string","pattern":"^-?\\d+(\\.\\d+)?(e[+-]?\\d+)?$/i","description":"What the line costs, counted in `denomination`.","example":"3.482"},"denomination":{"type":"string","enum":["minor_units","credits","units"],"description":"Unit of account for amounts.\n\n- minor_units: Fractional minor units of the accompanying currency.\n- credits: Credit counts, without a currency.\n- units: Weighted rolling-allowance units, without a currency.","example":"minor_units"},"usd_amount":{"type":["string","null"],"pattern":"^-?\\d+(\\.\\d+)?(e[+-]?\\d+)?$/i","description":"Set only on a credits line the rate card did not price directly, which was therefore converted from the USD price registry. The USD figure it came from, so a receipt can show both numbers instead of a bare credit count.","example":"0.0348"},"rate":{"type":["string","null"],"description":"The rate the line was priced at, when there is one to name. Null on an unpriced line — there was no rate, which is the point.","example":"1000/5000 per 1M in/out"},"price_status":{"type":"string","enum":["priced","partial","unpriced"],"description":"Pricing completeness. Omission on historical receipts means priced.\n\n- priced: All usage dimensions were priced.\n- partial: Some usage dimensions could not be priced.\n- unpriced: No price was available; zero means unknown cost, not free usage.","example":"priced"}},"required":["kind","provider","model","quantity","unit","amount"]},"description":"Itemized lines behind `amount`: one per LLM call, one per cost item, plus a `markup` line when the policy charges one. In credits mode every line is in credits, and a line the rate card did not price directly also carries the `usd_amount` it was converted from. Read each line's `price_status`: a line nothing could price is present at 0 and marked `unpriced` rather than dropped, so the receipt always accounts for everything that was sent.","example":[{"kind":"llm_call","provider":"anthropic","model":"claude-sonnet-5","quantity":"12400","unit":"tokens","amount":"3.482","denomination":"minor_units","usd_amount":"0.03482","rate":"3/15 per 1M in/out","price_status":"priced"}]},"balance":{"type":"object","properties":{"currency":{"type":["string","null"],"enum":["EUR","AED","AFN","XCD","ALL","AMD","AOA","ARS","USD","AUD","AWG","AZN","BAM","BBD","BDT","BGN","BHD","BIF","XOF","BMD","BND","BOB","BRL","BSD","BTN","NOK","BWP","BYR","BZD","CAD","CDF","XAF","CHF","NZD","CLP","CNY","COP","CRC","CUP","CVE","ANG","CZK","DJF","DKK","DOP","DZD","EGP","MAD","ERN","ETB","FJD","FKP","GBP","GEL","GHS","GIP","GMD","GNF","GTQ","GYD","HKD","HNL","HRK","HTG","HUF","IDR","ILS","INR","IQD","IRR","ISK","JMD","JOD","JPY","KES","KGS","KHR","KMF","KPW","KRW","KWD","KYD","KZT","LAK","LBP","LKR","LRD","LSL","LYD","MDL","MGA","MKD","MMK","MNT","MOP","MRO","MUR","MVR","MWK","MXN","MYR","MZN","NAD","XPF","NGN","NIO","NPR","OMR","PAB","PEN","PGK","PHP","PKR","PLN","PYG","QAR","RON","RSD","RUB","RWF","SAR","SBD","SCR","SDG","SEK","SGD","SHP","SLL","SOS","SRD","SSP","STD","SYP","SZL","THB","TJS","TMT","TND","TOP","TRY","TTD","TWD","TZS","UAH","UGX","UYU","UZS","VEF","VND","VUV","WST","YER","ZAR","ZMW","ZWL"],"description":"ISO 4217 currency code for monetary amounts. Null for counts or historical amounts without recorded currency.","example":"USD"},"denomination":{"type":"string","enum":["minor_units","credits","units"],"description":"Unit of account for amounts.\n\n- minor_units: Fractional minor units of the accompanying currency.\n- credits: Credit counts, without a currency.\n- units: Weighted rolling-allowance units, without a currency.","example":"minor_units"},"wallet":{"type":"string","pattern":"^-?\\d+(\\.\\d+)?(e[+-]?\\d+)?$/i","description":"The settled source balance — the wallet's balance in wallet mode, the credit pot's balance in credits mode.","example":"12500"},"unsettled":{"type":"string","pattern":"^-?\\d+(\\.\\d+)?(e[+-]?\\d+)?$/i","description":"Consumption recorded but not yet rolled into a wallet transaction. Always `0` in credits mode, where a consume decrements the real credit pot inside its own transaction and leaves nothing in flight.","example":"43.218"},"available":{"type":"string","pattern":"^-?\\d+(\\.\\d+)?(e[+-]?\\d+)?$/i","description":"`wallet - unsettled` — what the customer can still spend, and the only one of the three to gate on in either mode. Correct the instant a consume commits; in wallet mode it may go negative if they overspent between settlements.","example":"12456.782"}},"required":["currency","denomination","wallet","unsettled","available"],"description":"What the customer can spend. In wallet mode this is the shadow balance — micro-consumption never touches the wallet ledger directly. In credits mode it is the credit pot itself, read live. In windows mode the three numbers describe the *binding* window, the one with least room left and therefore the one that will refuse the next call; `meters` carries every window separately.","example":{"currency":"USD","denomination":"minor_units","wallet":"12500","unsettled":"43.218","available":"12456.782"}},"meters":{"type":["array","null"],"items":{"type":"object","properties":{"key":{"type":"string","description":"The window this meter is for, as the policy names it — `5h`, `7d`, `monthly`.","example":"5h"},"included_units":{"type":"string","pattern":"^-?\\d+(\\.\\d+)?(e[+-]?\\d+)?$/i","description":"The whole allowance for one instance of this window.","example":"50000"},"used_units":{"type":"string","pattern":"^-?\\d+(\\.\\d+)?(e[+-]?\\d+)?$/i","description":"Weighted units consumed inside the open instance, counting the call that just returned. Zero when no instance is open.","example":"12500"},"remaining_units":{"type":"string","pattern":"^-?\\d+(\\.\\d+)?(e[+-]?\\d+)?$/i","description":"`included_units - used_units`, floored at zero. The whole allowance when no instance is open.","example":"37500"},"window_started_at":{"type":["string","null"],"format":"date-time","description":"When the open instance was anchored — the first consumption after the previous instance expired. Null together with `resets_at` when no instance is open.","example":"2026-08-20T09:14:02.113Z"},"resets_at":{"type":["string","null"],"format":"date-time","description":"When the open instance expires and the allowance comes back in full. Null when no instance is open: nothing has been consumed since the last one ended, so the clock has not started and the next call is what anchors it.","example":"2026-08-20T14:14:02.113Z"}},"required":["key","included_units","used_units","remaining_units","window_started_at","resets_at"],"description":"One rolling allowance window's live state, including the call that just happened.","example":{"key":"5h","included_units":"50000","used_units":"12500","remaining_units":"37500","window_started_at":"2026-08-20T09:14:02.113Z","resets_at":"2026-08-20T14:14:02.113Z"}},"description":"Every rolling allowance window after this call, in `windows` mode — the units it just consumed are already in `used_units`. Null in every other mode.","example":[{"key":"5h","included_units":"50000","used_units":"12500","remaining_units":"37500","window_started_at":"2026-08-20T09:14:02.113Z","resets_at":"2026-08-20T14:14:02.113Z"}]},"blocked":{"type":"boolean","description":"Whether the customer's kill switch is on. Consumption is still recorded when it is — blocking is a gate for `check`, not a way to lose ledger entries.","example":false},"warning":{"type":["object","null"],"properties":{"code":{"type":"string","enum":["unpriced_usage"],"description":"Warning code for a successful consume.\n\n- unpriced_usage: At least one usage line could not be fully priced.","example":"unpriced_usage"},"message":{"type":"string","description":"Human-readable explanation of the warning.","example":"1 usage line could not be priced and was recorded at zero. Add the missing rate-card row, catalog entry, or fallback conversion rate — this consume will not be re-charged retroactively."},"unpriced_lines":{"type":"number","description":"How many breakdown lines were recorded at 0 because nothing could price them. Matches the number of lines carrying `price_status: \"unpriced\"`.","example":1}},"required":["code","message","unpriced_lines"],"description":"Set when part of this consume could not be priced. The customer was still charged for the lines that could be, and the unpriceable ones are in `breakdown` with `price_status: \"unpriced\"`. Null otherwise.","example":{"code":"unpriced_usage","message":"One usage line could not be fully priced.","unpriced_lines":1}},"overage":{"type":"boolean","description":"True when THIS call was priced as overage: it crossed the scope's boundary and the policy is `metered`, so the whole call was re-priced in the overage currency and `denomination` is `minor_units` rather than `credits` or `units`. A replay reports what the original call did.","example":true}},"required":["currency","agent","amount","denomination","breakdown","balance","meters","blocked","warning","overage"]}}}},"402":{"description":"Not enough credits, or a rolling allowance with no room left. Nothing was deducted and no window was incremented.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["telemetry_managed","not_configured","unsupported_mode","customer_not_found","wallet_missing","credit_pot_missing","pricing_unavailable","insufficient_credits","allowance_exhausted","windows_not_configured"],"description":"Machine-readable consumption refusal code.\n\n- not_configured: No billing policy is configured.\n- unsupported_mode: The billing configuration is unsupported.\n- customer_not_found: The customer could not be found.\n- wallet_missing: The monetary wallet is unavailable.\n- credit_pot_missing: The credit balance is unavailable.\n- insufficient_credits: The credit balance cannot cover the required spend.\n- allowance_exhausted: A rolling allowance has no room for the spend.\n- windows_not_configured: Rolling allowance definitions are missing.\n- pricing_unavailable: Legacy compatibility value; no longer returned. Unpriceable usage is recorded with an unpriced_usage warning.","example":"not_configured"},"message":{"type":"string","description":"Human-readable explanation of the refusal.","example":"This customer has no AI billing policy"},"balance":{"type":["object","null"],"properties":{"currency":{"type":["string","null"],"enum":["EUR","AED","AFN","XCD","ALL","AMD","AOA","ARS","USD","AUD","AWG","AZN","BAM","BBD","BDT","BGN","BHD","BIF","XOF","BMD","BND","BOB","BRL","BSD","BTN","NOK","BWP","BYR","BZD","CAD","CDF","XAF","CHF","NZD","CLP","CNY","COP","CRC","CUP","CVE","ANG","CZK","DJF","DKK","DOP","DZD","EGP","MAD","ERN","ETB","FJD","FKP","GBP","GEL","GHS","GIP","GMD","GNF","GTQ","GYD","HKD","HNL","HRK","HTG","HUF","IDR","ILS","INR","IQD","IRR","ISK","JMD","JOD","JPY","KES","KGS","KHR","KMF","KPW","KRW","KWD","KYD","KZT","LAK","LBP","LKR","LRD","LSL","LYD","MDL","MGA","MKD","MMK","MNT","MOP","MRO","MUR","MVR","MWK","MXN","MYR","MZN","NAD","XPF","NGN","NIO","NPR","OMR","PAB","PEN","PGK","PHP","PKR","PLN","PYG","QAR","RON","RSD","RUB","RWF","SAR","SBD","SCR","SDG","SEK","SGD","SHP","SLL","SOS","SRD","SSP","STD","SYP","SZL","THB","TJS","TMT","TND","TOP","TRY","TTD","TWD","TZS","UAH","UGX","UYU","UZS","VEF","VND","VUV","WST","YER","ZAR","ZMW","ZWL"],"description":"ISO 4217 currency code for monetary amounts. Null for counts or historical amounts without recorded currency.","example":"USD"},"denomination":{"type":"string","enum":["minor_units","credits","units"],"description":"Unit of account for amounts.\n\n- minor_units: Fractional minor units of the accompanying currency.\n- credits: Credit counts, without a currency.\n- units: Weighted rolling-allowance units, without a currency.","example":"minor_units"},"wallet":{"type":"string","pattern":"^-?\\d+(\\.\\d+)?(e[+-]?\\d+)?$/i","description":"The settled source balance — the wallet's balance in wallet mode, the credit pot's balance in credits mode.","example":"12500"},"unsettled":{"type":"string","pattern":"^-?\\d+(\\.\\d+)?(e[+-]?\\d+)?$/i","description":"Consumption recorded but not yet rolled into a wallet transaction. Always `0` in credits mode, where a consume decrements the real credit pot inside its own transaction and leaves nothing in flight.","example":"43.218"},"available":{"type":"string","pattern":"^-?\\d+(\\.\\d+)?(e[+-]?\\d+)?$/i","description":"`wallet - unsettled` — what the customer can still spend, and the only one of the three to gate on in either mode. Correct the instant a consume commits; in wallet mode it may go negative if they overspent between settlements.","example":"12456.782"}},"required":["currency","denomination","wallet","unsettled","available"],"description":"The balance at the moment of the refusal, when the refusal is about money — `insufficient_credits` and `allowance_exhausted` carry it so an agent knows how short it was without a second round trip. Null otherwise.","example":{"currency":"USD","denomination":"minor_units","wallet":"12500","unsettled":"43.218","available":"12456.782"}},"meters":{"type":["array","null"],"items":{"type":"object","properties":{"key":{"type":"string","description":"The window this meter is for, as the policy names it — `5h`, `7d`, `monthly`.","example":"5h"},"included_units":{"type":"string","pattern":"^-?\\d+(\\.\\d+)?(e[+-]?\\d+)?$/i","description":"The whole allowance for one instance of this window.","example":"50000"},"used_units":{"type":"string","pattern":"^-?\\d+(\\.\\d+)?(e[+-]?\\d+)?$/i","description":"Weighted units consumed inside the open instance, counting the call that just returned. Zero when no instance is open.","example":"12500"},"remaining_units":{"type":"string","pattern":"^-?\\d+(\\.\\d+)?(e[+-]?\\d+)?$/i","description":"`included_units - used_units`, floored at zero. The whole allowance when no instance is open.","example":"37500"},"window_started_at":{"type":["string","null"],"format":"date-time","description":"When the open instance was anchored — the first consumption after the previous instance expired. Null together with `resets_at` when no instance is open.","example":"2026-08-20T09:14:02.113Z"},"resets_at":{"type":["string","null"],"format":"date-time","description":"When the open instance expires and the allowance comes back in full. Null when no instance is open: nothing has been consumed since the last one ended, so the clock has not started and the next call is what anchors it.","example":"2026-08-20T14:14:02.113Z"}},"required":["key","included_units","used_units","remaining_units","window_started_at","resets_at"],"description":"One rolling allowance window's live state, including the call that just happened.","example":{"key":"5h","included_units":"50000","used_units":"12500","remaining_units":"37500","window_started_at":"2026-08-20T09:14:02.113Z","resets_at":"2026-08-20T14:14:02.113Z"}},"description":"Every window's state at the moment of an `allowance_exhausted` refusal, so the caller can see which one ran out and by how much. Null on every other refusal.","example":[{"key":"5h","included_units":"50000","used_units":"12500","remaining_units":"37500","window_started_at":"2026-08-20T09:14:02.113Z","resets_at":"2026-08-20T14:14:02.113Z"}]},"resets_at":{"type":["string","null"],"format":"date-time","description":"The soonest instant one of the windows that blocked the call rolls over — the earliest of them, since that is the next moment the answer could change. Null when no blocking window has an open instance, which means the call is larger than a whole allowance and waiting will not help. Null on every other refusal.","example":"2026-08-20T14:14:02.113Z"}},"required":["code","message","balance","meters","resets_at"]}}}},"404":{"description":"Customer not found.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["telemetry_managed","not_configured","unsupported_mode","customer_not_found","wallet_missing","credit_pot_missing","pricing_unavailable","insufficient_credits","allowance_exhausted","windows_not_configured"],"description":"Machine-readable consumption refusal code.\n\n- not_configured: No billing policy is configured.\n- unsupported_mode: The billing configuration is unsupported.\n- customer_not_found: The customer could not be found.\n- wallet_missing: The monetary wallet is unavailable.\n- credit_pot_missing: The credit balance is unavailable.\n- insufficient_credits: The credit balance cannot cover the required spend.\n- allowance_exhausted: A rolling allowance has no room for the spend.\n- windows_not_configured: Rolling allowance definitions are missing.\n- pricing_unavailable: Legacy compatibility value; no longer returned. Unpriceable usage is recorded with an unpriced_usage warning.","example":"not_configured"},"message":{"type":"string","description":"Human-readable explanation of the refusal.","example":"This customer has no AI billing policy"},"balance":{"type":["object","null"],"properties":{"currency":{"type":["string","null"],"enum":["EUR","AED","AFN","XCD","ALL","AMD","AOA","ARS","USD","AUD","AWG","AZN","BAM","BBD","BDT","BGN","BHD","BIF","XOF","BMD","BND","BOB","BRL","BSD","BTN","NOK","BWP","BYR","BZD","CAD","CDF","XAF","CHF","NZD","CLP","CNY","COP","CRC","CUP","CVE","ANG","CZK","DJF","DKK","DOP","DZD","EGP","MAD","ERN","ETB","FJD","FKP","GBP","GEL","GHS","GIP","GMD","GNF","GTQ","GYD","HKD","HNL","HRK","HTG","HUF","IDR","ILS","INR","IQD","IRR","ISK","JMD","JOD","JPY","KES","KGS","KHR","KMF","KPW","KRW","KWD","KYD","KZT","LAK","LBP","LKR","LRD","LSL","LYD","MDL","MGA","MKD","MMK","MNT","MOP","MRO","MUR","MVR","MWK","MXN","MYR","MZN","NAD","XPF","NGN","NIO","NPR","OMR","PAB","PEN","PGK","PHP","PKR","PLN","PYG","QAR","RON","RSD","RUB","RWF","SAR","SBD","SCR","SDG","SEK","SGD","SHP","SLL","SOS","SRD","SSP","STD","SYP","SZL","THB","TJS","TMT","TND","TOP","TRY","TTD","TWD","TZS","UAH","UGX","UYU","UZS","VEF","VND","VUV","WST","YER","ZAR","ZMW","ZWL"],"description":"ISO 4217 currency code for monetary amounts. Null for counts or historical amounts without recorded currency.","example":"USD"},"denomination":{"type":"string","enum":["minor_units","credits","units"],"description":"Unit of account for amounts.\n\n- minor_units: Fractional minor units of the accompanying currency.\n- credits: Credit counts, without a currency.\n- units: Weighted rolling-allowance units, without a currency.","example":"minor_units"},"wallet":{"type":"string","pattern":"^-?\\d+(\\.\\d+)?(e[+-]?\\d+)?$/i","description":"The settled source balance — the wallet's balance in wallet mode, the credit pot's balance in credits mode.","example":"12500"},"unsettled":{"type":"string","pattern":"^-?\\d+(\\.\\d+)?(e[+-]?\\d+)?$/i","description":"Consumption recorded but not yet rolled into a wallet transaction. Always `0` in credits mode, where a consume decrements the real credit pot inside its own transaction and leaves nothing in flight.","example":"43.218"},"available":{"type":"string","pattern":"^-?\\d+(\\.\\d+)?(e[+-]?\\d+)?$/i","description":"`wallet - unsettled` — what the customer can still spend, and the only one of the three to gate on in either mode. Correct the instant a consume commits; in wallet mode it may go negative if they overspent between settlements.","example":"12456.782"}},"required":["currency","denomination","wallet","unsettled","available"],"description":"The balance at the moment of the refusal, when the refusal is about money — `insufficient_credits` and `allowance_exhausted` carry it so an agent knows how short it was without a second round trip. Null otherwise.","example":{"currency":"USD","denomination":"minor_units","wallet":"12500","unsettled":"43.218","available":"12456.782"}},"meters":{"type":["array","null"],"items":{"type":"object","properties":{"key":{"type":"string","description":"The window this meter is for, as the policy names it — `5h`, `7d`, `monthly`.","example":"5h"},"included_units":{"type":"string","pattern":"^-?\\d+(\\.\\d+)?(e[+-]?\\d+)?$/i","description":"The whole allowance for one instance of this window.","example":"50000"},"used_units":{"type":"string","pattern":"^-?\\d+(\\.\\d+)?(e[+-]?\\d+)?$/i","description":"Weighted units consumed inside the open instance, counting the call that just returned. Zero when no instance is open.","example":"12500"},"remaining_units":{"type":"string","pattern":"^-?\\d+(\\.\\d+)?(e[+-]?\\d+)?$/i","description":"`included_units - used_units`, floored at zero. The whole allowance when no instance is open.","example":"37500"},"window_started_at":{"type":["string","null"],"format":"date-time","description":"When the open instance was anchored — the first consumption after the previous instance expired. Null together with `resets_at` when no instance is open.","example":"2026-08-20T09:14:02.113Z"},"resets_at":{"type":["string","null"],"format":"date-time","description":"When the open instance expires and the allowance comes back in full. Null when no instance is open: nothing has been consumed since the last one ended, so the clock has not started and the next call is what anchors it.","example":"2026-08-20T14:14:02.113Z"}},"required":["key","included_units","used_units","remaining_units","window_started_at","resets_at"],"description":"One rolling allowance window's live state, including the call that just happened.","example":{"key":"5h","included_units":"50000","used_units":"12500","remaining_units":"37500","window_started_at":"2026-08-20T09:14:02.113Z","resets_at":"2026-08-20T14:14:02.113Z"}},"description":"Every window's state at the moment of an `allowance_exhausted` refusal, so the caller can see which one ran out and by how much. Null on every other refusal.","example":[{"key":"5h","included_units":"50000","used_units":"12500","remaining_units":"37500","window_started_at":"2026-08-20T09:14:02.113Z","resets_at":"2026-08-20T14:14:02.113Z"}]},"resets_at":{"type":["string","null"],"format":"date-time","description":"The soonest instant one of the windows that blocked the call rolls over — the earliest of them, since that is the next moment the answer could change. Null when no blocking window has an open instance, which means the call is larger than a whole allowance and waiting will not help. Null on every other refusal.","example":"2026-08-20T14:14:02.113Z"}},"required":["code","message","balance","meters","resets_at"]}}}},"409":{"description":"No billing policy configured.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["telemetry_managed","not_configured","unsupported_mode","customer_not_found","wallet_missing","credit_pot_missing","pricing_unavailable","insufficient_credits","allowance_exhausted","windows_not_configured"],"description":"Machine-readable consumption refusal code.\n\n- not_configured: No billing policy is configured.\n- unsupported_mode: The billing configuration is unsupported.\n- customer_not_found: The customer could not be found.\n- wallet_missing: The monetary wallet is unavailable.\n- credit_pot_missing: The credit balance is unavailable.\n- insufficient_credits: The credit balance cannot cover the required spend.\n- allowance_exhausted: A rolling allowance has no room for the spend.\n- windows_not_configured: Rolling allowance definitions are missing.\n- pricing_unavailable: Legacy compatibility value; no longer returned. Unpriceable usage is recorded with an unpriced_usage warning.","example":"not_configured"},"message":{"type":"string","description":"Human-readable explanation of the refusal.","example":"This customer has no AI billing policy"},"balance":{"type":["object","null"],"properties":{"currency":{"type":["string","null"],"enum":["EUR","AED","AFN","XCD","ALL","AMD","AOA","ARS","USD","AUD","AWG","AZN","BAM","BBD","BDT","BGN","BHD","BIF","XOF","BMD","BND","BOB","BRL","BSD","BTN","NOK","BWP","BYR","BZD","CAD","CDF","XAF","CHF","NZD","CLP","CNY","COP","CRC","CUP","CVE","ANG","CZK","DJF","DKK","DOP","DZD","EGP","MAD","ERN","ETB","FJD","FKP","GBP","GEL","GHS","GIP","GMD","GNF","GTQ","GYD","HKD","HNL","HRK","HTG","HUF","IDR","ILS","INR","IQD","IRR","ISK","JMD","JOD","JPY","KES","KGS","KHR","KMF","KPW","KRW","KWD","KYD","KZT","LAK","LBP","LKR","LRD","LSL","LYD","MDL","MGA","MKD","MMK","MNT","MOP","MRO","MUR","MVR","MWK","MXN","MYR","MZN","NAD","XPF","NGN","NIO","NPR","OMR","PAB","PEN","PGK","PHP","PKR","PLN","PYG","QAR","RON","RSD","RUB","RWF","SAR","SBD","SCR","SDG","SEK","SGD","SHP","SLL","SOS","SRD","SSP","STD","SYP","SZL","THB","TJS","TMT","TND","TOP","TRY","TTD","TWD","TZS","UAH","UGX","UYU","UZS","VEF","VND","VUV","WST","YER","ZAR","ZMW","ZWL"],"description":"ISO 4217 currency code for monetary amounts. Null for counts or historical amounts without recorded currency.","example":"USD"},"denomination":{"type":"string","enum":["minor_units","credits","units"],"description":"Unit of account for amounts.\n\n- minor_units: Fractional minor units of the accompanying currency.\n- credits: Credit counts, without a currency.\n- units: Weighted rolling-allowance units, without a currency.","example":"minor_units"},"wallet":{"type":"string","pattern":"^-?\\d+(\\.\\d+)?(e[+-]?\\d+)?$/i","description":"The settled source balance — the wallet's balance in wallet mode, the credit pot's balance in credits mode.","example":"12500"},"unsettled":{"type":"string","pattern":"^-?\\d+(\\.\\d+)?(e[+-]?\\d+)?$/i","description":"Consumption recorded but not yet rolled into a wallet transaction. Always `0` in credits mode, where a consume decrements the real credit pot inside its own transaction and leaves nothing in flight.","example":"43.218"},"available":{"type":"string","pattern":"^-?\\d+(\\.\\d+)?(e[+-]?\\d+)?$/i","description":"`wallet - unsettled` — what the customer can still spend, and the only one of the three to gate on in either mode. Correct the instant a consume commits; in wallet mode it may go negative if they overspent between settlements.","example":"12456.782"}},"required":["currency","denomination","wallet","unsettled","available"],"description":"The balance at the moment of the refusal, when the refusal is about money — `insufficient_credits` and `allowance_exhausted` carry it so an agent knows how short it was without a second round trip. Null otherwise.","example":{"currency":"USD","denomination":"minor_units","wallet":"12500","unsettled":"43.218","available":"12456.782"}},"meters":{"type":["array","null"],"items":{"type":"object","properties":{"key":{"type":"string","description":"The window this meter is for, as the policy names it — `5h`, `7d`, `monthly`.","example":"5h"},"included_units":{"type":"string","pattern":"^-?\\d+(\\.\\d+)?(e[+-]?\\d+)?$/i","description":"The whole allowance for one instance of this window.","example":"50000"},"used_units":{"type":"string","pattern":"^-?\\d+(\\.\\d+)?(e[+-]?\\d+)?$/i","description":"Weighted units consumed inside the open instance, counting the call that just returned. Zero when no instance is open.","example":"12500"},"remaining_units":{"type":"string","pattern":"^-?\\d+(\\.\\d+)?(e[+-]?\\d+)?$/i","description":"`included_units - used_units`, floored at zero. The whole allowance when no instance is open.","example":"37500"},"window_started_at":{"type":["string","null"],"format":"date-time","description":"When the open instance was anchored — the first consumption after the previous instance expired. Null together with `resets_at` when no instance is open.","example":"2026-08-20T09:14:02.113Z"},"resets_at":{"type":["string","null"],"format":"date-time","description":"When the open instance expires and the allowance comes back in full. Null when no instance is open: nothing has been consumed since the last one ended, so the clock has not started and the next call is what anchors it.","example":"2026-08-20T14:14:02.113Z"}},"required":["key","included_units","used_units","remaining_units","window_started_at","resets_at"],"description":"One rolling allowance window's live state, including the call that just happened.","example":{"key":"5h","included_units":"50000","used_units":"12500","remaining_units":"37500","window_started_at":"2026-08-20T09:14:02.113Z","resets_at":"2026-08-20T14:14:02.113Z"}},"description":"Every window's state at the moment of an `allowance_exhausted` refusal, so the caller can see which one ran out and by how much. Null on every other refusal.","example":[{"key":"5h","included_units":"50000","used_units":"12500","remaining_units":"37500","window_started_at":"2026-08-20T09:14:02.113Z","resets_at":"2026-08-20T14:14:02.113Z"}]},"resets_at":{"type":["string","null"],"format":"date-time","description":"The soonest instant one of the windows that blocked the call rolls over — the earliest of them, since that is the next moment the answer could change. Null when no blocking window has an open instance, which means the call is larger than a whole allowance and waiting will not help. Null on every other refusal.","example":"2026-08-20T14:14:02.113Z"}},"required":["code","message","balance","meters","resets_at"]}}}},"422":{"description":"The policy cannot bill this: an unsupported mode, a missing wallet or credit pot, an unconfigured window card, or usage no rate card prices.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["telemetry_managed","not_configured","unsupported_mode","customer_not_found","wallet_missing","credit_pot_missing","pricing_unavailable","insufficient_credits","allowance_exhausted","windows_not_configured"],"description":"Machine-readable consumption refusal code.\n\n- not_configured: No billing policy is configured.\n- unsupported_mode: The billing configuration is unsupported.\n- customer_not_found: The customer could not be found.\n- wallet_missing: The monetary wallet is unavailable.\n- credit_pot_missing: The credit balance is unavailable.\n- insufficient_credits: The credit balance cannot cover the required spend.\n- allowance_exhausted: A rolling allowance has no room for the spend.\n- windows_not_configured: Rolling allowance definitions are missing.\n- pricing_unavailable: Legacy compatibility value; no longer returned. Unpriceable usage is recorded with an unpriced_usage warning.","example":"not_configured"},"message":{"type":"string","description":"Human-readable explanation of the refusal.","example":"This customer has no AI billing policy"},"balance":{"type":["object","null"],"properties":{"currency":{"type":["string","null"],"enum":["EUR","AED","AFN","XCD","ALL","AMD","AOA","ARS","USD","AUD","AWG","AZN","BAM","BBD","BDT","BGN","BHD","BIF","XOF","BMD","BND","BOB","BRL","BSD","BTN","NOK","BWP","BYR","BZD","CAD","CDF","XAF","CHF","NZD","CLP","CNY","COP","CRC","CUP","CVE","ANG","CZK","DJF","DKK","DOP","DZD","EGP","MAD","ERN","ETB","FJD","FKP","GBP","GEL","GHS","GIP","GMD","GNF","GTQ","GYD","HKD","HNL","HRK","HTG","HUF","IDR","ILS","INR","IQD","IRR","ISK","JMD","JOD","JPY","KES","KGS","KHR","KMF","KPW","KRW","KWD","KYD","KZT","LAK","LBP","LKR","LRD","LSL","LYD","MDL","MGA","MKD","MMK","MNT","MOP","MRO","MUR","MVR","MWK","MXN","MYR","MZN","NAD","XPF","NGN","NIO","NPR","OMR","PAB","PEN","PGK","PHP","PKR","PLN","PYG","QAR","RON","RSD","RUB","RWF","SAR","SBD","SCR","SDG","SEK","SGD","SHP","SLL","SOS","SRD","SSP","STD","SYP","SZL","THB","TJS","TMT","TND","TOP","TRY","TTD","TWD","TZS","UAH","UGX","UYU","UZS","VEF","VND","VUV","WST","YER","ZAR","ZMW","ZWL"],"description":"ISO 4217 currency code for monetary amounts. Null for counts or historical amounts without recorded currency.","example":"USD"},"denomination":{"type":"string","enum":["minor_units","credits","units"],"description":"Unit of account for amounts.\n\n- minor_units: Fractional minor units of the accompanying currency.\n- credits: Credit counts, without a currency.\n- units: Weighted rolling-allowance units, without a currency.","example":"minor_units"},"wallet":{"type":"string","pattern":"^-?\\d+(\\.\\d+)?(e[+-]?\\d+)?$/i","description":"The settled source balance — the wallet's balance in wallet mode, the credit pot's balance in credits mode.","example":"12500"},"unsettled":{"type":"string","pattern":"^-?\\d+(\\.\\d+)?(e[+-]?\\d+)?$/i","description":"Consumption recorded but not yet rolled into a wallet transaction. Always `0` in credits mode, where a consume decrements the real credit pot inside its own transaction and leaves nothing in flight.","example":"43.218"},"available":{"type":"string","pattern":"^-?\\d+(\\.\\d+)?(e[+-]?\\d+)?$/i","description":"`wallet - unsettled` — what the customer can still spend, and the only one of the three to gate on in either mode. Correct the instant a consume commits; in wallet mode it may go negative if they overspent between settlements.","example":"12456.782"}},"required":["currency","denomination","wallet","unsettled","available"],"description":"The balance at the moment of the refusal, when the refusal is about money — `insufficient_credits` and `allowance_exhausted` carry it so an agent knows how short it was without a second round trip. Null otherwise.","example":{"currency":"USD","denomination":"minor_units","wallet":"12500","unsettled":"43.218","available":"12456.782"}},"meters":{"type":["array","null"],"items":{"type":"object","properties":{"key":{"type":"string","description":"The window this meter is for, as the policy names it — `5h`, `7d`, `monthly`.","example":"5h"},"included_units":{"type":"string","pattern":"^-?\\d+(\\.\\d+)?(e[+-]?\\d+)?$/i","description":"The whole allowance for one instance of this window.","example":"50000"},"used_units":{"type":"string","pattern":"^-?\\d+(\\.\\d+)?(e[+-]?\\d+)?$/i","description":"Weighted units consumed inside the open instance, counting the call that just returned. Zero when no instance is open.","example":"12500"},"remaining_units":{"type":"string","pattern":"^-?\\d+(\\.\\d+)?(e[+-]?\\d+)?$/i","description":"`included_units - used_units`, floored at zero. The whole allowance when no instance is open.","example":"37500"},"window_started_at":{"type":["string","null"],"format":"date-time","description":"When the open instance was anchored — the first consumption after the previous instance expired. Null together with `resets_at` when no instance is open.","example":"2026-08-20T09:14:02.113Z"},"resets_at":{"type":["string","null"],"format":"date-time","description":"When the open instance expires and the allowance comes back in full. Null when no instance is open: nothing has been consumed since the last one ended, so the clock has not started and the next call is what anchors it.","example":"2026-08-20T14:14:02.113Z"}},"required":["key","included_units","used_units","remaining_units","window_started_at","resets_at"],"description":"One rolling allowance window's live state, including the call that just happened.","example":{"key":"5h","included_units":"50000","used_units":"12500","remaining_units":"37500","window_started_at":"2026-08-20T09:14:02.113Z","resets_at":"2026-08-20T14:14:02.113Z"}},"description":"Every window's state at the moment of an `allowance_exhausted` refusal, so the caller can see which one ran out and by how much. Null on every other refusal.","example":[{"key":"5h","included_units":"50000","used_units":"12500","remaining_units":"37500","window_started_at":"2026-08-20T09:14:02.113Z","resets_at":"2026-08-20T14:14:02.113Z"}]},"resets_at":{"type":["string","null"],"format":"date-time","description":"The soonest instant one of the windows that blocked the call rolls over — the earliest of them, since that is the next moment the answer could change. Null when no blocking window has an open instance, which means the call is larger than a whole allowance and waiting will not help. Null on every other refusal.","example":"2026-08-20T14:14:02.113Z"}},"required":["code","message","balance","meters","resets_at"]}}}}}}},"/v1/ai/billing/check":{"post":{"operationId":"checkAiBilling","tags":["AI > Ingest"],"security":[{"bearer":[]}],"summary":"Check AI spend allowance","description":"Ask whether a customer may spend right now. A read only — it reserves nothing. A customer with no billing policy is answered with `allowed: false, reason: \"not_configured\"` rather than an error, so an agent always gets a verdict it can act on.","requestBody":{"description":"Check payload.","content":{"application/json":{"schema":{"type":"object","properties":{"customer":{"type":"string","minLength":1,"maxLength":255,"description":"Customer to bill — the external id your application knows them by, or a Hyperline `cus_…` id. Resolved exactly the way AI telemetry resolves it.","example":"acme-corp"},"agent":{"type":"string","minLength":1,"maxLength":128,"description":"The agent making the call, as `run({ agent })` names it. Optional, and absent means the customer's shared pool — which is what every call did before per-agent billing existed. Naming an agent only changes anything once an operator has given that agent a billing policy of its own; until then it resolves to the same shared pool and the response says so with `agent: null`.","example":"invoice-copilot"},"action":{"type":"string","minLength":1,"maxLength":128,"description":"Optional action name. Accepted and reserved for per-action allowances; it does not change the verdict in any mode today.","example":"deep_research"}},"required":["customer"]}}}},"responses":{"200":{"description":"Verdict.","content":{"application/json":{"schema":{"type":"object","properties":{"agent":{"type":["string","null"],"description":"The billing scope that answered: the agent's own slug when it has a policy of its own, and null when the customer's shared pool answered — including when an agent was named but has no policy of its own.","example":"invoice-copilot"},"allowed":{"type":"boolean","description":"Whether the customer may spend right now.","example":true},"reason":{"type":["string","null"],"enum":["not_configured","unsupported_mode","customer_not_found","wallet_missing","credit_pot_missing","blocked","insufficient_balance","insufficient_credits","allowance_exhausted","windows_not_configured"],"description":"Reason spending was denied. Null when allowed.\n\n- not_configured: No billing policy is configured.\n- unsupported_mode: The billing configuration is unsupported.\n- customer_not_found: The customer could not be found.\n- wallet_missing: The monetary wallet is unavailable.\n- credit_pot_missing: The credit balance is unavailable.\n- blocked: Spending is disabled for the scope.\n- insufficient_balance: The wallet balance is at or below the policy floor.\n- insufficient_credits: The credit balance cannot cover the required spend.\n- allowance_exhausted: A rolling allowance has no room for the spend.\n- windows_not_configured: Rolling allowance definitions are missing.","example":null},"balance":{"type":"object","properties":{"currency":{"type":["string","null"],"enum":["EUR","AED","AFN","XCD","ALL","AMD","AOA","ARS","USD","AUD","AWG","AZN","BAM","BBD","BDT","BGN","BHD","BIF","XOF","BMD","BND","BOB","BRL","BSD","BTN","NOK","BWP","BYR","BZD","CAD","CDF","XAF","CHF","NZD","CLP","CNY","COP","CRC","CUP","CVE","ANG","CZK","DJF","DKK","DOP","DZD","EGP","MAD","ERN","ETB","FJD","FKP","GBP","GEL","GHS","GIP","GMD","GNF","GTQ","GYD","HKD","HNL","HRK","HTG","HUF","IDR","ILS","INR","IQD","IRR","ISK","JMD","JOD","JPY","KES","KGS","KHR","KMF","KPW","KRW","KWD","KYD","KZT","LAK","LBP","LKR","LRD","LSL","LYD","MDL","MGA","MKD","MMK","MNT","MOP","MRO","MUR","MVR","MWK","MXN","MYR","MZN","NAD","XPF","NGN","NIO","NPR","OMR","PAB","PEN","PGK","PHP","PKR","PLN","PYG","QAR","RON","RSD","RUB","RWF","SAR","SBD","SCR","SDG","SEK","SGD","SHP","SLL","SOS","SRD","SSP","STD","SYP","SZL","THB","TJS","TMT","TND","TOP","TRY","TTD","TWD","TZS","UAH","UGX","UYU","UZS","VEF","VND","VUV","WST","YER","ZAR","ZMW","ZWL"],"description":"ISO 4217 currency code for monetary amounts. Null for counts or historical amounts without recorded currency.","example":"USD"},"denomination":{"type":"string","enum":["minor_units","credits","units"],"description":"Unit of account for amounts.\n\n- minor_units: Fractional minor units of the accompanying currency.\n- credits: Credit counts, without a currency.\n- units: Weighted rolling-allowance units, without a currency.","example":"minor_units"},"wallet":{"type":"string","pattern":"^-?\\d+(\\.\\d+)?(e[+-]?\\d+)?$/i","description":"The settled source balance — the wallet's balance in wallet mode, the credit pot's balance in credits mode.","example":"12500"},"unsettled":{"type":"string","pattern":"^-?\\d+(\\.\\d+)?(e[+-]?\\d+)?$/i","description":"Consumption recorded but not yet rolled into a wallet transaction. Always `0` in credits mode, where a consume decrements the real credit pot inside its own transaction and leaves nothing in flight.","example":"43.218"},"available":{"type":"string","pattern":"^-?\\d+(\\.\\d+)?(e[+-]?\\d+)?$/i","description":"`wallet - unsettled` — what the customer can still spend, and the only one of the three to gate on in either mode. Correct the instant a consume commits; in wallet mode it may go negative if they overspent between settlements.","example":"12456.782"}},"required":["currency","denomination","wallet","unsettled","available"],"description":"What the customer can spend. In wallet mode this is the shadow balance — micro-consumption never touches the wallet ledger directly. In credits mode it is the credit pot itself, read live. In windows mode the three numbers describe the *binding* window, the one with least room left and therefore the one that will refuse the next call; `meters` carries every window separately.","example":{"currency":"USD","denomination":"minor_units","wallet":"12500","unsettled":"43.218","available":"12456.782"}},"meters":{"type":["array","null"],"items":{"type":"object","properties":{"key":{"type":"string","description":"The window this meter is for, as the policy names it — `5h`, `7d`, `monthly`.","example":"5h"},"included_units":{"type":"string","pattern":"^-?\\d+(\\.\\d+)?(e[+-]?\\d+)?$/i","description":"The whole allowance for one instance of this window.","example":"50000"},"used_units":{"type":"string","pattern":"^-?\\d+(\\.\\d+)?(e[+-]?\\d+)?$/i","description":"Weighted units consumed inside the open instance, counting the call that just returned. Zero when no instance is open.","example":"12500"},"remaining_units":{"type":"string","pattern":"^-?\\d+(\\.\\d+)?(e[+-]?\\d+)?$/i","description":"`included_units - used_units`, floored at zero. The whole allowance when no instance is open.","example":"37500"},"window_started_at":{"type":["string","null"],"format":"date-time","description":"When the open instance was anchored — the first consumption after the previous instance expired. Null together with `resets_at` when no instance is open.","example":"2026-08-20T09:14:02.113Z"},"resets_at":{"type":["string","null"],"format":"date-time","description":"When the open instance expires and the allowance comes back in full. Null when no instance is open: nothing has been consumed since the last one ended, so the clock has not started and the next call is what anchors it.","example":"2026-08-20T14:14:02.113Z"}},"required":["key","included_units","used_units","remaining_units","window_started_at","resets_at"],"description":"One rolling allowance window's live state, including the call that just happened.","example":{"key":"5h","included_units":"50000","used_units":"12500","remaining_units":"37500","window_started_at":"2026-08-20T09:14:02.113Z","resets_at":"2026-08-20T14:14:02.113Z"}},"description":"Every rolling allowance window, in `windows` mode. Null in every other mode. `allowed` is false as soon as any one of them is at or below the policy floor.","example":[{"key":"5h","included_units":"50000","used_units":"12500","remaining_units":"37500","window_started_at":"2026-08-20T09:14:02.113Z","resets_at":"2026-08-20T14:14:02.113Z"}]},"overage":{"type":"boolean","description":"True when this `allowed: true` is an overage verdict — the scope is past its boundary and the next call will be priced in the overage currency rather than refused. Never a denial of its own: `allowed` still answers \"may I proceed\".","example":true}},"required":["agent","allowed","reason","balance","meters","overage"]}}}},"402":{"description":"Not enough credits, or a rolling allowance with no room left. Nothing was deducted and no window was incremented.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["telemetry_managed","not_configured","unsupported_mode","customer_not_found","wallet_missing","credit_pot_missing","pricing_unavailable","insufficient_credits","allowance_exhausted","windows_not_configured"],"description":"Machine-readable consumption refusal code.\n\n- not_configured: No billing policy is configured.\n- unsupported_mode: The billing configuration is unsupported.\n- customer_not_found: The customer could not be found.\n- wallet_missing: The monetary wallet is unavailable.\n- credit_pot_missing: The credit balance is unavailable.\n- insufficient_credits: The credit balance cannot cover the required spend.\n- allowance_exhausted: A rolling allowance has no room for the spend.\n- windows_not_configured: Rolling allowance definitions are missing.\n- pricing_unavailable: Legacy compatibility value; no longer returned. Unpriceable usage is recorded with an unpriced_usage warning.","example":"not_configured"},"message":{"type":"string","description":"Human-readable explanation of the refusal.","example":"This customer has no AI billing policy"},"balance":{"type":["object","null"],"properties":{"currency":{"type":["string","null"],"enum":["EUR","AED","AFN","XCD","ALL","AMD","AOA","ARS","USD","AUD","AWG","AZN","BAM","BBD","BDT","BGN","BHD","BIF","XOF","BMD","BND","BOB","BRL","BSD","BTN","NOK","BWP","BYR","BZD","CAD","CDF","XAF","CHF","NZD","CLP","CNY","COP","CRC","CUP","CVE","ANG","CZK","DJF","DKK","DOP","DZD","EGP","MAD","ERN","ETB","FJD","FKP","GBP","GEL","GHS","GIP","GMD","GNF","GTQ","GYD","HKD","HNL","HRK","HTG","HUF","IDR","ILS","INR","IQD","IRR","ISK","JMD","JOD","JPY","KES","KGS","KHR","KMF","KPW","KRW","KWD","KYD","KZT","LAK","LBP","LKR","LRD","LSL","LYD","MDL","MGA","MKD","MMK","MNT","MOP","MRO","MUR","MVR","MWK","MXN","MYR","MZN","NAD","XPF","NGN","NIO","NPR","OMR","PAB","PEN","PGK","PHP","PKR","PLN","PYG","QAR","RON","RSD","RUB","RWF","SAR","SBD","SCR","SDG","SEK","SGD","SHP","SLL","SOS","SRD","SSP","STD","SYP","SZL","THB","TJS","TMT","TND","TOP","TRY","TTD","TWD","TZS","UAH","UGX","UYU","UZS","VEF","VND","VUV","WST","YER","ZAR","ZMW","ZWL"],"description":"ISO 4217 currency code for monetary amounts. Null for counts or historical amounts without recorded currency.","example":"USD"},"denomination":{"type":"string","enum":["minor_units","credits","units"],"description":"Unit of account for amounts.\n\n- minor_units: Fractional minor units of the accompanying currency.\n- credits: Credit counts, without a currency.\n- units: Weighted rolling-allowance units, without a currency.","example":"minor_units"},"wallet":{"type":"string","pattern":"^-?\\d+(\\.\\d+)?(e[+-]?\\d+)?$/i","description":"The settled source balance — the wallet's balance in wallet mode, the credit pot's balance in credits mode.","example":"12500"},"unsettled":{"type":"string","pattern":"^-?\\d+(\\.\\d+)?(e[+-]?\\d+)?$/i","description":"Consumption recorded but not yet rolled into a wallet transaction. Always `0` in credits mode, where a consume decrements the real credit pot inside its own transaction and leaves nothing in flight.","example":"43.218"},"available":{"type":"string","pattern":"^-?\\d+(\\.\\d+)?(e[+-]?\\d+)?$/i","description":"`wallet - unsettled` — what the customer can still spend, and the only one of the three to gate on in either mode. Correct the instant a consume commits; in wallet mode it may go negative if they overspent between settlements.","example":"12456.782"}},"required":["currency","denomination","wallet","unsettled","available"],"description":"The balance at the moment of the refusal, when the refusal is about money — `insufficient_credits` and `allowance_exhausted` carry it so an agent knows how short it was without a second round trip. Null otherwise.","example":{"currency":"USD","denomination":"minor_units","wallet":"12500","unsettled":"43.218","available":"12456.782"}},"meters":{"type":["array","null"],"items":{"type":"object","properties":{"key":{"type":"string","description":"The window this meter is for, as the policy names it — `5h`, `7d`, `monthly`.","example":"5h"},"included_units":{"type":"string","pattern":"^-?\\d+(\\.\\d+)?(e[+-]?\\d+)?$/i","description":"The whole allowance for one instance of this window.","example":"50000"},"used_units":{"type":"string","pattern":"^-?\\d+(\\.\\d+)?(e[+-]?\\d+)?$/i","description":"Weighted units consumed inside the open instance, counting the call that just returned. Zero when no instance is open.","example":"12500"},"remaining_units":{"type":"string","pattern":"^-?\\d+(\\.\\d+)?(e[+-]?\\d+)?$/i","description":"`included_units - used_units`, floored at zero. The whole allowance when no instance is open.","example":"37500"},"window_started_at":{"type":["string","null"],"format":"date-time","description":"When the open instance was anchored — the first consumption after the previous instance expired. Null together with `resets_at` when no instance is open.","example":"2026-08-20T09:14:02.113Z"},"resets_at":{"type":["string","null"],"format":"date-time","description":"When the open instance expires and the allowance comes back in full. Null when no instance is open: nothing has been consumed since the last one ended, so the clock has not started and the next call is what anchors it.","example":"2026-08-20T14:14:02.113Z"}},"required":["key","included_units","used_units","remaining_units","window_started_at","resets_at"],"description":"One rolling allowance window's live state, including the call that just happened.","example":{"key":"5h","included_units":"50000","used_units":"12500","remaining_units":"37500","window_started_at":"2026-08-20T09:14:02.113Z","resets_at":"2026-08-20T14:14:02.113Z"}},"description":"Every window's state at the moment of an `allowance_exhausted` refusal, so the caller can see which one ran out and by how much. Null on every other refusal.","example":[{"key":"5h","included_units":"50000","used_units":"12500","remaining_units":"37500","window_started_at":"2026-08-20T09:14:02.113Z","resets_at":"2026-08-20T14:14:02.113Z"}]},"resets_at":{"type":["string","null"],"format":"date-time","description":"The soonest instant one of the windows that blocked the call rolls over — the earliest of them, since that is the next moment the answer could change. Null when no blocking window has an open instance, which means the call is larger than a whole allowance and waiting will not help. Null on every other refusal.","example":"2026-08-20T14:14:02.113Z"}},"required":["code","message","balance","meters","resets_at"]}}}},"404":{"description":"Customer not found.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["telemetry_managed","not_configured","unsupported_mode","customer_not_found","wallet_missing","credit_pot_missing","pricing_unavailable","insufficient_credits","allowance_exhausted","windows_not_configured"],"description":"Machine-readable consumption refusal code.\n\n- not_configured: No billing policy is configured.\n- unsupported_mode: The billing configuration is unsupported.\n- customer_not_found: The customer could not be found.\n- wallet_missing: The monetary wallet is unavailable.\n- credit_pot_missing: The credit balance is unavailable.\n- insufficient_credits: The credit balance cannot cover the required spend.\n- allowance_exhausted: A rolling allowance has no room for the spend.\n- windows_not_configured: Rolling allowance definitions are missing.\n- pricing_unavailable: Legacy compatibility value; no longer returned. Unpriceable usage is recorded with an unpriced_usage warning.","example":"not_configured"},"message":{"type":"string","description":"Human-readable explanation of the refusal.","example":"This customer has no AI billing policy"},"balance":{"type":["object","null"],"properties":{"currency":{"type":["string","null"],"enum":["EUR","AED","AFN","XCD","ALL","AMD","AOA","ARS","USD","AUD","AWG","AZN","BAM","BBD","BDT","BGN","BHD","BIF","XOF","BMD","BND","BOB","BRL","BSD","BTN","NOK","BWP","BYR","BZD","CAD","CDF","XAF","CHF","NZD","CLP","CNY","COP","CRC","CUP","CVE","ANG","CZK","DJF","DKK","DOP","DZD","EGP","MAD","ERN","ETB","FJD","FKP","GBP","GEL","GHS","GIP","GMD","GNF","GTQ","GYD","HKD","HNL","HRK","HTG","HUF","IDR","ILS","INR","IQD","IRR","ISK","JMD","JOD","JPY","KES","KGS","KHR","KMF","KPW","KRW","KWD","KYD","KZT","LAK","LBP","LKR","LRD","LSL","LYD","MDL","MGA","MKD","MMK","MNT","MOP","MRO","MUR","MVR","MWK","MXN","MYR","MZN","NAD","XPF","NGN","NIO","NPR","OMR","PAB","PEN","PGK","PHP","PKR","PLN","PYG","QAR","RON","RSD","RUB","RWF","SAR","SBD","SCR","SDG","SEK","SGD","SHP","SLL","SOS","SRD","SSP","STD","SYP","SZL","THB","TJS","TMT","TND","TOP","TRY","TTD","TWD","TZS","UAH","UGX","UYU","UZS","VEF","VND","VUV","WST","YER","ZAR","ZMW","ZWL"],"description":"ISO 4217 currency code for monetary amounts. Null for counts or historical amounts without recorded currency.","example":"USD"},"denomination":{"type":"string","enum":["minor_units","credits","units"],"description":"Unit of account for amounts.\n\n- minor_units: Fractional minor units of the accompanying currency.\n- credits: Credit counts, without a currency.\n- units: Weighted rolling-allowance units, without a currency.","example":"minor_units"},"wallet":{"type":"string","pattern":"^-?\\d+(\\.\\d+)?(e[+-]?\\d+)?$/i","description":"The settled source balance — the wallet's balance in wallet mode, the credit pot's balance in credits mode.","example":"12500"},"unsettled":{"type":"string","pattern":"^-?\\d+(\\.\\d+)?(e[+-]?\\d+)?$/i","description":"Consumption recorded but not yet rolled into a wallet transaction. Always `0` in credits mode, where a consume decrements the real credit pot inside its own transaction and leaves nothing in flight.","example":"43.218"},"available":{"type":"string","pattern":"^-?\\d+(\\.\\d+)?(e[+-]?\\d+)?$/i","description":"`wallet - unsettled` — what the customer can still spend, and the only one of the three to gate on in either mode. Correct the instant a consume commits; in wallet mode it may go negative if they overspent between settlements.","example":"12456.782"}},"required":["currency","denomination","wallet","unsettled","available"],"description":"The balance at the moment of the refusal, when the refusal is about money — `insufficient_credits` and `allowance_exhausted` carry it so an agent knows how short it was without a second round trip. Null otherwise.","example":{"currency":"USD","denomination":"minor_units","wallet":"12500","unsettled":"43.218","available":"12456.782"}},"meters":{"type":["array","null"],"items":{"type":"object","properties":{"key":{"type":"string","description":"The window this meter is for, as the policy names it — `5h`, `7d`, `monthly`.","example":"5h"},"included_units":{"type":"string","pattern":"^-?\\d+(\\.\\d+)?(e[+-]?\\d+)?$/i","description":"The whole allowance for one instance of this window.","example":"50000"},"used_units":{"type":"string","pattern":"^-?\\d+(\\.\\d+)?(e[+-]?\\d+)?$/i","description":"Weighted units consumed inside the open instance, counting the call that just returned. Zero when no instance is open.","example":"12500"},"remaining_units":{"type":"string","pattern":"^-?\\d+(\\.\\d+)?(e[+-]?\\d+)?$/i","description":"`included_units - used_units`, floored at zero. The whole allowance when no instance is open.","example":"37500"},"window_started_at":{"type":["string","null"],"format":"date-time","description":"When the open instance was anchored — the first consumption after the previous instance expired. Null together with `resets_at` when no instance is open.","example":"2026-08-20T09:14:02.113Z"},"resets_at":{"type":["string","null"],"format":"date-time","description":"When the open instance expires and the allowance comes back in full. Null when no instance is open: nothing has been consumed since the last one ended, so the clock has not started and the next call is what anchors it.","example":"2026-08-20T14:14:02.113Z"}},"required":["key","included_units","used_units","remaining_units","window_started_at","resets_at"],"description":"One rolling allowance window's live state, including the call that just happened.","example":{"key":"5h","included_units":"50000","used_units":"12500","remaining_units":"37500","window_started_at":"2026-08-20T09:14:02.113Z","resets_at":"2026-08-20T14:14:02.113Z"}},"description":"Every window's state at the moment of an `allowance_exhausted` refusal, so the caller can see which one ran out and by how much. Null on every other refusal.","example":[{"key":"5h","included_units":"50000","used_units":"12500","remaining_units":"37500","window_started_at":"2026-08-20T09:14:02.113Z","resets_at":"2026-08-20T14:14:02.113Z"}]},"resets_at":{"type":["string","null"],"format":"date-time","description":"The soonest instant one of the windows that blocked the call rolls over — the earliest of them, since that is the next moment the answer could change. Null when no blocking window has an open instance, which means the call is larger than a whole allowance and waiting will not help. Null on every other refusal.","example":"2026-08-20T14:14:02.113Z"}},"required":["code","message","balance","meters","resets_at"]}}}},"409":{"description":"No billing policy configured.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["telemetry_managed","not_configured","unsupported_mode","customer_not_found","wallet_missing","credit_pot_missing","pricing_unavailable","insufficient_credits","allowance_exhausted","windows_not_configured"],"description":"Machine-readable consumption refusal code.\n\n- not_configured: No billing policy is configured.\n- unsupported_mode: The billing configuration is unsupported.\n- customer_not_found: The customer could not be found.\n- wallet_missing: The monetary wallet is unavailable.\n- credit_pot_missing: The credit balance is unavailable.\n- insufficient_credits: The credit balance cannot cover the required spend.\n- allowance_exhausted: A rolling allowance has no room for the spend.\n- windows_not_configured: Rolling allowance definitions are missing.\n- pricing_unavailable: Legacy compatibility value; no longer returned. Unpriceable usage is recorded with an unpriced_usage warning.","example":"not_configured"},"message":{"type":"string","description":"Human-readable explanation of the refusal.","example":"This customer has no AI billing policy"},"balance":{"type":["object","null"],"properties":{"currency":{"type":["string","null"],"enum":["EUR","AED","AFN","XCD","ALL","AMD","AOA","ARS","USD","AUD","AWG","AZN","BAM","BBD","BDT","BGN","BHD","BIF","XOF","BMD","BND","BOB","BRL","BSD","BTN","NOK","BWP","BYR","BZD","CAD","CDF","XAF","CHF","NZD","CLP","CNY","COP","CRC","CUP","CVE","ANG","CZK","DJF","DKK","DOP","DZD","EGP","MAD","ERN","ETB","FJD","FKP","GBP","GEL","GHS","GIP","GMD","GNF","GTQ","GYD","HKD","HNL","HRK","HTG","HUF","IDR","ILS","INR","IQD","IRR","ISK","JMD","JOD","JPY","KES","KGS","KHR","KMF","KPW","KRW","KWD","KYD","KZT","LAK","LBP","LKR","LRD","LSL","LYD","MDL","MGA","MKD","MMK","MNT","MOP","MRO","MUR","MVR","MWK","MXN","MYR","MZN","NAD","XPF","NGN","NIO","NPR","OMR","PAB","PEN","PGK","PHP","PKR","PLN","PYG","QAR","RON","RSD","RUB","RWF","SAR","SBD","SCR","SDG","SEK","SGD","SHP","SLL","SOS","SRD","SSP","STD","SYP","SZL","THB","TJS","TMT","TND","TOP","TRY","TTD","TWD","TZS","UAH","UGX","UYU","UZS","VEF","VND","VUV","WST","YER","ZAR","ZMW","ZWL"],"description":"ISO 4217 currency code for monetary amounts. Null for counts or historical amounts without recorded currency.","example":"USD"},"denomination":{"type":"string","enum":["minor_units","credits","units"],"description":"Unit of account for amounts.\n\n- minor_units: Fractional minor units of the accompanying currency.\n- credits: Credit counts, without a currency.\n- units: Weighted rolling-allowance units, without a currency.","example":"minor_units"},"wallet":{"type":"string","pattern":"^-?\\d+(\\.\\d+)?(e[+-]?\\d+)?$/i","description":"The settled source balance — the wallet's balance in wallet mode, the credit pot's balance in credits mode.","example":"12500"},"unsettled":{"type":"string","pattern":"^-?\\d+(\\.\\d+)?(e[+-]?\\d+)?$/i","description":"Consumption recorded but not yet rolled into a wallet transaction. Always `0` in credits mode, where a consume decrements the real credit pot inside its own transaction and leaves nothing in flight.","example":"43.218"},"available":{"type":"string","pattern":"^-?\\d+(\\.\\d+)?(e[+-]?\\d+)?$/i","description":"`wallet - unsettled` — what the customer can still spend, and the only one of the three to gate on in either mode. Correct the instant a consume commits; in wallet mode it may go negative if they overspent between settlements.","example":"12456.782"}},"required":["currency","denomination","wallet","unsettled","available"],"description":"The balance at the moment of the refusal, when the refusal is about money — `insufficient_credits` and `allowance_exhausted` carry it so an agent knows how short it was without a second round trip. Null otherwise.","example":{"currency":"USD","denomination":"minor_units","wallet":"12500","unsettled":"43.218","available":"12456.782"}},"meters":{"type":["array","null"],"items":{"type":"object","properties":{"key":{"type":"string","description":"The window this meter is for, as the policy names it — `5h`, `7d`, `monthly`.","example":"5h"},"included_units":{"type":"string","pattern":"^-?\\d+(\\.\\d+)?(e[+-]?\\d+)?$/i","description":"The whole allowance for one instance of this window.","example":"50000"},"used_units":{"type":"string","pattern":"^-?\\d+(\\.\\d+)?(e[+-]?\\d+)?$/i","description":"Weighted units consumed inside the open instance, counting the call that just returned. Zero when no instance is open.","example":"12500"},"remaining_units":{"type":"string","pattern":"^-?\\d+(\\.\\d+)?(e[+-]?\\d+)?$/i","description":"`included_units - used_units`, floored at zero. The whole allowance when no instance is open.","example":"37500"},"window_started_at":{"type":["string","null"],"format":"date-time","description":"When the open instance was anchored — the first consumption after the previous instance expired. Null together with `resets_at` when no instance is open.","example":"2026-08-20T09:14:02.113Z"},"resets_at":{"type":["string","null"],"format":"date-time","description":"When the open instance expires and the allowance comes back in full. Null when no instance is open: nothing has been consumed since the last one ended, so the clock has not started and the next call is what anchors it.","example":"2026-08-20T14:14:02.113Z"}},"required":["key","included_units","used_units","remaining_units","window_started_at","resets_at"],"description":"One rolling allowance window's live state, including the call that just happened.","example":{"key":"5h","included_units":"50000","used_units":"12500","remaining_units":"37500","window_started_at":"2026-08-20T09:14:02.113Z","resets_at":"2026-08-20T14:14:02.113Z"}},"description":"Every window's state at the moment of an `allowance_exhausted` refusal, so the caller can see which one ran out and by how much. Null on every other refusal.","example":[{"key":"5h","included_units":"50000","used_units":"12500","remaining_units":"37500","window_started_at":"2026-08-20T09:14:02.113Z","resets_at":"2026-08-20T14:14:02.113Z"}]},"resets_at":{"type":["string","null"],"format":"date-time","description":"The soonest instant one of the windows that blocked the call rolls over — the earliest of them, since that is the next moment the answer could change. Null when no blocking window has an open instance, which means the call is larger than a whole allowance and waiting will not help. Null on every other refusal.","example":"2026-08-20T14:14:02.113Z"}},"required":["code","message","balance","meters","resets_at"]}}}},"422":{"description":"The policy cannot bill this: an unsupported mode, a missing wallet or credit pot, an unconfigured window card, or usage no rate card prices.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["telemetry_managed","not_configured","unsupported_mode","customer_not_found","wallet_missing","credit_pot_missing","pricing_unavailable","insufficient_credits","allowance_exhausted","windows_not_configured"],"description":"Machine-readable consumption refusal code.\n\n- not_configured: No billing policy is configured.\n- unsupported_mode: The billing configuration is unsupported.\n- customer_not_found: The customer could not be found.\n- wallet_missing: The monetary wallet is unavailable.\n- credit_pot_missing: The credit balance is unavailable.\n- insufficient_credits: The credit balance cannot cover the required spend.\n- allowance_exhausted: A rolling allowance has no room for the spend.\n- windows_not_configured: Rolling allowance definitions are missing.\n- pricing_unavailable: Legacy compatibility value; no longer returned. Unpriceable usage is recorded with an unpriced_usage warning.","example":"not_configured"},"message":{"type":"string","description":"Human-readable explanation of the refusal.","example":"This customer has no AI billing policy"},"balance":{"type":["object","null"],"properties":{"currency":{"type":["string","null"],"enum":["EUR","AED","AFN","XCD","ALL","AMD","AOA","ARS","USD","AUD","AWG","AZN","BAM","BBD","BDT","BGN","BHD","BIF","XOF","BMD","BND","BOB","BRL","BSD","BTN","NOK","BWP","BYR","BZD","CAD","CDF","XAF","CHF","NZD","CLP","CNY","COP","CRC","CUP","CVE","ANG","CZK","DJF","DKK","DOP","DZD","EGP","MAD","ERN","ETB","FJD","FKP","GBP","GEL","GHS","GIP","GMD","GNF","GTQ","GYD","HKD","HNL","HRK","HTG","HUF","IDR","ILS","INR","IQD","IRR","ISK","JMD","JOD","JPY","KES","KGS","KHR","KMF","KPW","KRW","KWD","KYD","KZT","LAK","LBP","LKR","LRD","LSL","LYD","MDL","MGA","MKD","MMK","MNT","MOP","MRO","MUR","MVR","MWK","MXN","MYR","MZN","NAD","XPF","NGN","NIO","NPR","OMR","PAB","PEN","PGK","PHP","PKR","PLN","PYG","QAR","RON","RSD","RUB","RWF","SAR","SBD","SCR","SDG","SEK","SGD","SHP","SLL","SOS","SRD","SSP","STD","SYP","SZL","THB","TJS","TMT","TND","TOP","TRY","TTD","TWD","TZS","UAH","UGX","UYU","UZS","VEF","VND","VUV","WST","YER","ZAR","ZMW","ZWL"],"description":"ISO 4217 currency code for monetary amounts. Null for counts or historical amounts without recorded currency.","example":"USD"},"denomination":{"type":"string","enum":["minor_units","credits","units"],"description":"Unit of account for amounts.\n\n- minor_units: Fractional minor units of the accompanying currency.\n- credits: Credit counts, without a currency.\n- units: Weighted rolling-allowance units, without a currency.","example":"minor_units"},"wallet":{"type":"string","pattern":"^-?\\d+(\\.\\d+)?(e[+-]?\\d+)?$/i","description":"The settled source balance — the wallet's balance in wallet mode, the credit pot's balance in credits mode.","example":"12500"},"unsettled":{"type":"string","pattern":"^-?\\d+(\\.\\d+)?(e[+-]?\\d+)?$/i","description":"Consumption recorded but not yet rolled into a wallet transaction. Always `0` in credits mode, where a consume decrements the real credit pot inside its own transaction and leaves nothing in flight.","example":"43.218"},"available":{"type":"string","pattern":"^-?\\d+(\\.\\d+)?(e[+-]?\\d+)?$/i","description":"`wallet - unsettled` — what the customer can still spend, and the only one of the three to gate on in either mode. Correct the instant a consume commits; in wallet mode it may go negative if they overspent between settlements.","example":"12456.782"}},"required":["currency","denomination","wallet","unsettled","available"],"description":"The balance at the moment of the refusal, when the refusal is about money — `insufficient_credits` and `allowance_exhausted` carry it so an agent knows how short it was without a second round trip. Null otherwise.","example":{"currency":"USD","denomination":"minor_units","wallet":"12500","unsettled":"43.218","available":"12456.782"}},"meters":{"type":["array","null"],"items":{"type":"object","properties":{"key":{"type":"string","description":"The window this meter is for, as the policy names it — `5h`, `7d`, `monthly`.","example":"5h"},"included_units":{"type":"string","pattern":"^-?\\d+(\\.\\d+)?(e[+-]?\\d+)?$/i","description":"The whole allowance for one instance of this window.","example":"50000"},"used_units":{"type":"string","pattern":"^-?\\d+(\\.\\d+)?(e[+-]?\\d+)?$/i","description":"Weighted units consumed inside the open instance, counting the call that just returned. Zero when no instance is open.","example":"12500"},"remaining_units":{"type":"string","pattern":"^-?\\d+(\\.\\d+)?(e[+-]?\\d+)?$/i","description":"`included_units - used_units`, floored at zero. The whole allowance when no instance is open.","example":"37500"},"window_started_at":{"type":["string","null"],"format":"date-time","description":"When the open instance was anchored — the first consumption after the previous instance expired. Null together with `resets_at` when no instance is open.","example":"2026-08-20T09:14:02.113Z"},"resets_at":{"type":["string","null"],"format":"date-time","description":"When the open instance expires and the allowance comes back in full. Null when no instance is open: nothing has been consumed since the last one ended, so the clock has not started and the next call is what anchors it.","example":"2026-08-20T14:14:02.113Z"}},"required":["key","included_units","used_units","remaining_units","window_started_at","resets_at"],"description":"One rolling allowance window's live state, including the call that just happened.","example":{"key":"5h","included_units":"50000","used_units":"12500","remaining_units":"37500","window_started_at":"2026-08-20T09:14:02.113Z","resets_at":"2026-08-20T14:14:02.113Z"}},"description":"Every window's state at the moment of an `allowance_exhausted` refusal, so the caller can see which one ran out and by how much. Null on every other refusal.","example":[{"key":"5h","included_units":"50000","used_units":"12500","remaining_units":"37500","window_started_at":"2026-08-20T09:14:02.113Z","resets_at":"2026-08-20T14:14:02.113Z"}]},"resets_at":{"type":["string","null"],"format":"date-time","description":"The soonest instant one of the windows that blocked the call rolls over — the earliest of them, since that is the next moment the answer could change. Null when no blocking window has an open instance, which means the call is larger than a whole allowance and waiting will not help. Null on every other refusal.","example":"2026-08-20T14:14:02.113Z"}},"required":["code","message","balance","meters","resets_at"]}}}}}}},"/v1/ai/billing/snapshot":{"get":{"operationId":"getAiBillingSnapshot","tags":["AI > Ingest"],"security":[{"bearer":[]}],"summary":"Get AI billing snapshot","description":"The customer's consumption state: mode, balance, kill switch and policy. `balance` carries the same three numbers in either mode with a `denomination` saying what they count, so a consumer that only wants \"how much is left\" never has to branch. `credits` is populated in credits mode with the pot, its upcoming expiries and a summary of the rate card; `meters` is populated in windows mode with one live entry per rolling allowance — used, remaining and the instant it resets, counting the open instance — which is the read to poll for a limits UI.","parameters":[{"schema":{"type":"string","minLength":1,"maxLength":255,"description":"Customer to bill — the external id your application knows them by, or a Hyperline `cus_…` id. Resolved exactly the way AI telemetry resolves it.","example":"acme-corp"},"required":true,"description":"Customer to bill — the external id your application knows them by, or a Hyperline `cus_…` id. Resolved exactly the way AI telemetry resolves it.","name":"customer","in":"query"},{"schema":{"type":"string","minLength":1,"maxLength":128,"description":"The agent making the call, as `run({ agent })` names it. Optional, and absent means the customer's shared pool — which is what every call did before per-agent billing existed. Naming an agent only changes anything once an operator has given that agent a billing policy of its own; until then it resolves to the same shared pool and the response says so with `agent: null`.","example":"invoice-copilot"},"required":false,"description":"The agent making the call, as `run({ agent })` names it. Optional, and absent means the customer's shared pool — which is what every call did before per-agent billing existed. Naming an agent only changes anything once an operator has given that agent a billing policy of its own; until then it resolves to the same shared pool and the response says so with `agent: null`.","name":"agent","in":"query"}],"responses":{"200":{"description":"Snapshot.","content":{"application/json":{"schema":{"type":"object","properties":{"agent":{"type":["string","null"],"description":"The billing scope that answered: the agent's own slug when it has a policy of its own, and null when the customer's shared pool answered — including when an agent was named but has no policy of its own.","example":"invoice-copilot"},"mode":{"type":["string","null"],"enum":["wallet","credits","windows"],"description":"Billing mode. Null when no policy is configured.\n\n- wallet: Charges a monetary wallet.\n- credits: Consumes a credit balance.\n- windows: Meters weighted units against rolling allowances.","example":"wallet"},"balance":{"type":"object","properties":{"currency":{"type":["string","null"],"enum":["EUR","AED","AFN","XCD","ALL","AMD","AOA","ARS","USD","AUD","AWG","AZN","BAM","BBD","BDT","BGN","BHD","BIF","XOF","BMD","BND","BOB","BRL","BSD","BTN","NOK","BWP","BYR","BZD","CAD","CDF","XAF","CHF","NZD","CLP","CNY","COP","CRC","CUP","CVE","ANG","CZK","DJF","DKK","DOP","DZD","EGP","MAD","ERN","ETB","FJD","FKP","GBP","GEL","GHS","GIP","GMD","GNF","GTQ","GYD","HKD","HNL","HRK","HTG","HUF","IDR","ILS","INR","IQD","IRR","ISK","JMD","JOD","JPY","KES","KGS","KHR","KMF","KPW","KRW","KWD","KYD","KZT","LAK","LBP","LKR","LRD","LSL","LYD","MDL","MGA","MKD","MMK","MNT","MOP","MRO","MUR","MVR","MWK","MXN","MYR","MZN","NAD","XPF","NGN","NIO","NPR","OMR","PAB","PEN","PGK","PHP","PKR","PLN","PYG","QAR","RON","RSD","RUB","RWF","SAR","SBD","SCR","SDG","SEK","SGD","SHP","SLL","SOS","SRD","SSP","STD","SYP","SZL","THB","TJS","TMT","TND","TOP","TRY","TTD","TWD","TZS","UAH","UGX","UYU","UZS","VEF","VND","VUV","WST","YER","ZAR","ZMW","ZWL"],"description":"ISO 4217 currency code for monetary amounts. Null for counts or historical amounts without recorded currency.","example":"USD"},"denomination":{"type":"string","enum":["minor_units","credits","units"],"description":"Unit of account for amounts.\n\n- minor_units: Fractional minor units of the accompanying currency.\n- credits: Credit counts, without a currency.\n- units: Weighted rolling-allowance units, without a currency.","example":"minor_units"},"wallet":{"type":"string","pattern":"^-?\\d+(\\.\\d+)?(e[+-]?\\d+)?$/i","description":"The settled source balance — the wallet's balance in wallet mode, the credit pot's balance in credits mode.","example":"12500"},"unsettled":{"type":"string","pattern":"^-?\\d+(\\.\\d+)?(e[+-]?\\d+)?$/i","description":"Consumption recorded but not yet rolled into a wallet transaction. Always `0` in credits mode, where a consume decrements the real credit pot inside its own transaction and leaves nothing in flight.","example":"43.218"},"available":{"type":"string","pattern":"^-?\\d+(\\.\\d+)?(e[+-]?\\d+)?$/i","description":"`wallet - unsettled` — what the customer can still spend, and the only one of the three to gate on in either mode. Correct the instant a consume commits; in wallet mode it may go negative if they overspent between settlements.","example":"12456.782"}},"required":["currency","denomination","wallet","unsettled","available"],"description":"What the customer can spend. In wallet mode this is the shadow balance — micro-consumption never touches the wallet ledger directly. In credits mode it is the credit pot itself, read live. In windows mode the three numbers describe the *binding* window, the one with least room left and therefore the one that will refuse the next call; `meters` carries every window separately.","example":{"currency":"USD","denomination":"minor_units","wallet":"12500","unsettled":"43.218","available":"12456.782"}},"blocked":{"type":"boolean","description":"Whether the customer's kill switch is on. Consumption is still recorded when it is — blocking is a gate for `check`, not a way to lose ledger entries.","example":false},"policy":{"type":["object","null"],"properties":{"markup_percent":{"type":"string","pattern":"^-?\\d+(\\.\\d+)?(e[+-]?\\d+)?$/i","description":"Percentage added on top of the priced usage.","example":"20"},"floor":{"type":"string","pattern":"^-?\\d+(\\.\\d+)?(e[+-]?\\d+)?$/i","description":"Balance at or below which the customer is refused.","example":"0"}},"required":["markup_percent","floor"],"description":"Null when no policy is configured.","example":{"markup_percent":"20","floor":"0"}},"meters":{"type":["array","null"],"items":{"type":"object","properties":{"key":{"type":"string","description":"The window this meter is for, as the policy names it — `5h`, `7d`, `monthly`.","example":"5h"},"included_units":{"type":"string","pattern":"^-?\\d+(\\.\\d+)?(e[+-]?\\d+)?$/i","description":"The whole allowance for one instance of this window.","example":"50000"},"used_units":{"type":"string","pattern":"^-?\\d+(\\.\\d+)?(e[+-]?\\d+)?$/i","description":"Weighted units consumed inside the open instance, counting the call that just returned. Zero when no instance is open.","example":"12500"},"remaining_units":{"type":"string","pattern":"^-?\\d+(\\.\\d+)?(e[+-]?\\d+)?$/i","description":"`included_units - used_units`, floored at zero. The whole allowance when no instance is open.","example":"37500"},"window_started_at":{"type":["string","null"],"format":"date-time","description":"When the open instance was anchored — the first consumption after the previous instance expired. Null together with `resets_at` when no instance is open.","example":"2026-08-20T09:14:02.113Z"},"resets_at":{"type":["string","null"],"format":"date-time","description":"When the open instance expires and the allowance comes back in full. Null when no instance is open: nothing has been consumed since the last one ended, so the clock has not started and the next call is what anchors it.","example":"2026-08-20T14:14:02.113Z"}},"required":["key","included_units","used_units","remaining_units","window_started_at","resets_at"],"description":"One rolling allowance window's live state, including the call that just happened.","example":{"key":"5h","included_units":"50000","used_units":"12500","remaining_units":"37500","window_started_at":"2026-08-20T09:14:02.113Z","resets_at":"2026-08-20T14:14:02.113Z"}},"description":"The customer's rolling allowances, in `windows` mode — one entry per window the policy defines, in declaration order, counting the currently open instance. Null in every other mode. This is the live-meters read: poll it to render \"37,500 of 50,000 left, resets at 14:14\".","example":[{"key":"5h","included_units":"50000","used_units":"12500","remaining_units":"37500","window_started_at":"2026-08-20T09:14:02.113Z","resets_at":"2026-08-20T14:14:02.113Z"}]},"credits":{"type":["object","null"],"properties":{"balance":{"type":"string","pattern":"^-?\\d+(\\.\\d+)?(e[+-]?\\d+)?$/i","description":"Credits left on the pot, at full decimal precision. The same number as `balance.available`.","example":"48120.5"},"currency":{"type":"null","description":"Credits are a count, not money, so they have no currency. Always null — stated rather than omitted so the field does not appear later and change the shape.","example":null},"product_id":{"type":"string","description":"The credit product the pot is keyed by. Credits in Hyperline are one pot per (customer, credit product).","example":"pro_2f8c1ab4e77d31"},"low_balance_threshold":{"type":["string","null"],"pattern":"^-?\\d+(\\.\\d+)?(e[+-]?\\d+)?$/i","description":"The pot's own low-balance warning threshold, when one is configured. Independent of the AI policy's `floor`.","example":"1000"},"expiring_soon":{"type":"array","items":{"type":"object","properties":{"amount":{"type":"string","pattern":"^-?\\d+(\\.\\d+)?(e[+-]?\\d+)?$/i","description":"Exact decimal string. Interpret the unit using the field description and denomination.","example":"5000"},"expires_at":{"type":"string","format":"date-time","description":"UTC date time string in the [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601) format.","example":"2026-09-18T00:00:00.000Z"}},"required":["amount","expires_at"]},"description":"Top-ups expiring within 30 days, soonest first, grouped by expiry instant. `amount` is what the top-up granted, not what is left of it — the credit domain only works the unconsumed remainder out at expiry time — so read it as a ceiling on what the customer stands to lose.","example":[{"amount":"5000","expires_at":"2026-09-18T00:00:00Z"}]},"rate_card_summary":{"type":"object","properties":{"llm_rows":{"type":"number","example":12},"item_rows":{"type":"number","example":4},"has_default_llm_row":{"type":"boolean","description":"Whether the card prices models it does not name individually.","example":true},"fallback_credits_per_usd":{"type":["string","null"],"pattern":"^-?\\d+(\\.\\d+)?(e[+-]?\\d+)?$/i","description":"Credits per USD for usage the card does not price. Null means such usage is recorded at 0 credits and flagged `price_status: \"unpriced\"` on its breakdown line, with an `unpriced_usage` warning on the response — it is not billed, and it is not silently treated as free either.","example":"1000"}},"required":["llm_rows","item_rows","has_default_llm_row","fallback_credits_per_usd"],"description":"What the customer's rate card covers, without reprinting it. The card itself is workspace configuration and is not exposed on this endpoint.","example":{"llm_rows":12,"item_rows":4,"has_default_llm_row":true,"fallback_credits_per_usd":"1000"}}},"required":["balance","currency","product_id","low_balance_threshold","expiring_soon","rate_card_summary"],"description":"The customer's credit pot and rate card. Populated in `credits` mode, null in every other — including a credits-mode policy whose credit product the customer has no balance for, which `check` reports as `credit_pot_missing`.","example":{"balance":"48120.5","currency":null,"product_id":"pro_credits","low_balance_threshold":"1000","expiring_soon":[{"amount":"5000","expires_at":"2026-09-18T00:00:00Z"}],"rate_card_summary":{"llm_rows":12,"item_rows":4,"has_default_llm_row":true,"fallback_credits_per_usd":"1000"}}},"overage":{"type":["object","null"],"properties":{"currency":{"type":["string","null"],"enum":["EUR","AED","AFN","XCD","ALL","AMD","AOA","ARS","USD","AUD","AWG","AZN","BAM","BBD","BDT","BGN","BHD","BIF","XOF","BMD","BND","BOB","BRL","BSD","BTN","NOK","BWP","BYR","BZD","CAD","CDF","XAF","CHF","NZD","CLP","CNY","COP","CRC","CUP","CVE","ANG","CZK","DJF","DKK","DOP","DZD","EGP","MAD","ERN","ETB","FJD","FKP","GBP","GEL","GHS","GIP","GMD","GNF","GTQ","GYD","HKD","HNL","HRK","HTG","HUF","IDR","ILS","INR","IQD","IRR","ISK","JMD","JOD","JPY","KES","KGS","KHR","KMF","KPW","KRW","KWD","KYD","KZT","LAK","LBP","LKR","LRD","LSL","LYD","MDL","MGA","MKD","MMK","MNT","MOP","MRO","MUR","MVR","MWK","MXN","MYR","MZN","NAD","XPF","NGN","NIO","NPR","OMR","PAB","PEN","PGK","PHP","PKR","PLN","PYG","QAR","RON","RSD","RUB","RWF","SAR","SBD","SCR","SDG","SEK","SGD","SHP","SLL","SOS","SRD","SSP","STD","SYP","SZL","THB","TJS","TMT","TND","TOP","TRY","TTD","TWD","TZS","UAH","UGX","UYU","UZS","VEF","VND","VUV","WST","YER","ZAR","ZMW","ZWL"],"description":"ISO 4217 currency code for monetary amounts. Null for counts or historical amounts without recorded currency.","example":"USD"},"mode":{"type":"string","enum":["refuse","metered"],"description":"Behavior when credits or an allowance are exhausted. Policy values may inherit the attached plan.\n\n- refuse: Rejects the call that crosses the boundary without deducting usage.\n- metered: Prices the whole call as monetary overage, using the overage card or USD provider cost plus markup.","example":"metered"},"active":{"type":"boolean","description":"Whether this scope is past its boundary RIGHT NOW — the credit pot at or below the floor, or a rolling allowance with no room. It describes the scope's position, not the policy's stance, so it is true under `refuse` as well.","example":true},"unsettled":{"type":"string","pattern":"^-?\\d+(\\.\\d+)?(e[+-]?\\d+)?$/i","description":"Overage recorded but not yet settled, in wallet minor units. Non-zero only once a call has actually crossed the boundary under `metered`: a credits or windows call that stayed inside its allowance is settled the instant it is recorded and never enters this number.","example":"412.75"}},"required":["currency","mode","active","unsettled"],"description":"What this scope does when it runs out, and where it stands right now. Null in `wallet` mode, which has no exhaustion boundary — its shadow balance already accrues past zero. `mode: \"refuse\"` is the default and is today's behaviour: the call that would cross the boundary is refused whole. `mode: \"metered\"` re-prices that whole call in the overage currency instead and records it as overage.","example":{"currency":"USD","mode":"metered","active":true,"unsettled":"412.75"}},"agents":{"type":"array","items":{"type":"object","properties":{"agent":{"type":"string","description":"The agent making the call, as `run({ agent })` names it. Optional, and absent means the customer's shared pool — which is what every call did before per-agent billing existed. Naming an agent only changes anything once an operator has given that agent a billing policy of its own; until then it resolves to the same shared pool and the response says so with `agent: null`.","example":"invoice-copilot"},"mode":{"type":"string","enum":["wallet","credits","windows"],"description":"Billing mode.\n\n- wallet: Charges a monetary wallet.\n- credits: Consumes a credit balance.\n- windows: Meters weighted units against rolling allowances.","example":"wallet"},"balance":{"type":"object","properties":{"currency":{"type":["string","null"],"enum":["EUR","AED","AFN","XCD","ALL","AMD","AOA","ARS","USD","AUD","AWG","AZN","BAM","BBD","BDT","BGN","BHD","BIF","XOF","BMD","BND","BOB","BRL","BSD","BTN","NOK","BWP","BYR","BZD","CAD","CDF","XAF","CHF","NZD","CLP","CNY","COP","CRC","CUP","CVE","ANG","CZK","DJF","DKK","DOP","DZD","EGP","MAD","ERN","ETB","FJD","FKP","GBP","GEL","GHS","GIP","GMD","GNF","GTQ","GYD","HKD","HNL","HRK","HTG","HUF","IDR","ILS","INR","IQD","IRR","ISK","JMD","JOD","JPY","KES","KGS","KHR","KMF","KPW","KRW","KWD","KYD","KZT","LAK","LBP","LKR","LRD","LSL","LYD","MDL","MGA","MKD","MMK","MNT","MOP","MRO","MUR","MVR","MWK","MXN","MYR","MZN","NAD","XPF","NGN","NIO","NPR","OMR","PAB","PEN","PGK","PHP","PKR","PLN","PYG","QAR","RON","RSD","RUB","RWF","SAR","SBD","SCR","SDG","SEK","SGD","SHP","SLL","SOS","SRD","SSP","STD","SYP","SZL","THB","TJS","TMT","TND","TOP","TRY","TTD","TWD","TZS","UAH","UGX","UYU","UZS","VEF","VND","VUV","WST","YER","ZAR","ZMW","ZWL"],"description":"ISO 4217 currency code for monetary amounts. Null for counts or historical amounts without recorded currency.","example":"USD"},"denomination":{"type":"string","enum":["minor_units","credits","units"],"description":"Unit of account for amounts.\n\n- minor_units: Fractional minor units of the accompanying currency.\n- credits: Credit counts, without a currency.\n- units: Weighted rolling-allowance units, without a currency.","example":"minor_units"},"wallet":{"type":"string","pattern":"^-?\\d+(\\.\\d+)?(e[+-]?\\d+)?$/i","description":"The settled source balance — the wallet's balance in wallet mode, the credit pot's balance in credits mode.","example":"12500"},"unsettled":{"type":"string","pattern":"^-?\\d+(\\.\\d+)?(e[+-]?\\d+)?$/i","description":"Consumption recorded but not yet rolled into a wallet transaction. Always `0` in credits mode, where a consume decrements the real credit pot inside its own transaction and leaves nothing in flight.","example":"43.218"},"available":{"type":"string","pattern":"^-?\\d+(\\.\\d+)?(e[+-]?\\d+)?$/i","description":"`wallet - unsettled` — what the customer can still spend, and the only one of the three to gate on in either mode. Correct the instant a consume commits; in wallet mode it may go negative if they overspent between settlements.","example":"12456.782"}},"required":["currency","denomination","wallet","unsettled","available"],"description":"What the customer can spend. In wallet mode this is the shadow balance — micro-consumption never touches the wallet ledger directly. In credits mode it is the credit pot itself, read live. In windows mode the three numbers describe the *binding* window, the one with least room left and therefore the one that will refuse the next call; `meters` carries every window separately.","example":{"currency":"USD","denomination":"minor_units","wallet":"12500","unsettled":"43.218","available":"12456.782"}},"blocked":{"type":"boolean","description":"Whether this agent's own pool is blocked.","example":false},"meters":{"type":["array","null"],"items":{"type":"object","properties":{"key":{"type":"string","description":"The window this meter is for, as the policy names it — `5h`, `7d`, `monthly`.","example":"5h"},"included_units":{"type":"string","pattern":"^-?\\d+(\\.\\d+)?(e[+-]?\\d+)?$/i","description":"The whole allowance for one instance of this window.","example":"50000"},"used_units":{"type":"string","pattern":"^-?\\d+(\\.\\d+)?(e[+-]?\\d+)?$/i","description":"Weighted units consumed inside the open instance, counting the call that just returned. Zero when no instance is open.","example":"12500"},"remaining_units":{"type":"string","pattern":"^-?\\d+(\\.\\d+)?(e[+-]?\\d+)?$/i","description":"`included_units - used_units`, floored at zero. The whole allowance when no instance is open.","example":"37500"},"window_started_at":{"type":["string","null"],"format":"date-time","description":"When the open instance was anchored — the first consumption after the previous instance expired. Null together with `resets_at` when no instance is open.","example":"2026-08-20T09:14:02.113Z"},"resets_at":{"type":["string","null"],"format":"date-time","description":"When the open instance expires and the allowance comes back in full. Null when no instance is open: nothing has been consumed since the last one ended, so the clock has not started and the next call is what anchors it.","example":"2026-08-20T14:14:02.113Z"}},"required":["key","included_units","used_units","remaining_units","window_started_at","resets_at"],"description":"One rolling allowance window's live state, including the call that just happened.","example":{"key":"5h","included_units":"50000","used_units":"12500","remaining_units":"37500","window_started_at":"2026-08-20T09:14:02.113Z","resets_at":"2026-08-20T14:14:02.113Z"}},"description":"The customer's rolling allowances, in `windows` mode — one entry per window the policy defines, in declaration order, counting the currently open instance. Null in every other mode. This is the live-meters read: poll it to render \"37,500 of 50,000 left, resets at 14:14\".","example":[{"key":"5h","included_units":"50000","used_units":"12500","remaining_units":"37500","window_started_at":"2026-08-20T09:14:02.113Z","resets_at":"2026-08-20T14:14:02.113Z"}]},"overage":{"type":["object","null"],"properties":{"currency":{"type":["string","null"],"enum":["EUR","AED","AFN","XCD","ALL","AMD","AOA","ARS","USD","AUD","AWG","AZN","BAM","BBD","BDT","BGN","BHD","BIF","XOF","BMD","BND","BOB","BRL","BSD","BTN","NOK","BWP","BYR","BZD","CAD","CDF","XAF","CHF","NZD","CLP","CNY","COP","CRC","CUP","CVE","ANG","CZK","DJF","DKK","DOP","DZD","EGP","MAD","ERN","ETB","FJD","FKP","GBP","GEL","GHS","GIP","GMD","GNF","GTQ","GYD","HKD","HNL","HRK","HTG","HUF","IDR","ILS","INR","IQD","IRR","ISK","JMD","JOD","JPY","KES","KGS","KHR","KMF","KPW","KRW","KWD","KYD","KZT","LAK","LBP","LKR","LRD","LSL","LYD","MDL","MGA","MKD","MMK","MNT","MOP","MRO","MUR","MVR","MWK","MXN","MYR","MZN","NAD","XPF","NGN","NIO","NPR","OMR","PAB","PEN","PGK","PHP","PKR","PLN","PYG","QAR","RON","RSD","RUB","RWF","SAR","SBD","SCR","SDG","SEK","SGD","SHP","SLL","SOS","SRD","SSP","STD","SYP","SZL","THB","TJS","TMT","TND","TOP","TRY","TTD","TWD","TZS","UAH","UGX","UYU","UZS","VEF","VND","VUV","WST","YER","ZAR","ZMW","ZWL"],"description":"ISO 4217 currency code for monetary amounts. Null for counts or historical amounts without recorded currency.","example":"USD"},"mode":{"type":"string","enum":["refuse","metered"],"description":"Behavior when credits or an allowance are exhausted. Policy values may inherit the attached plan.\n\n- refuse: Rejects the call that crosses the boundary without deducting usage.\n- metered: Prices the whole call as monetary overage, using the overage card or USD provider cost plus markup.","example":"metered"},"active":{"type":"boolean","description":"Whether this scope is past its boundary RIGHT NOW — the credit pot at or below the floor, or a rolling allowance with no room. It describes the scope's position, not the policy's stance, so it is true under `refuse` as well.","example":true},"unsettled":{"type":"string","pattern":"^-?\\d+(\\.\\d+)?(e[+-]?\\d+)?$/i","description":"Overage recorded but not yet settled, in wallet minor units. Non-zero only once a call has actually crossed the boundary under `metered`: a credits or windows call that stayed inside its allowance is settled the instant it is recorded and never enters this number.","example":"412.75"}},"required":["currency","mode","active","unsettled"],"description":"What this scope does when it runs out, and where it stands right now. Null in `wallet` mode, which has no exhaustion boundary — its shadow balance already accrues past zero. `mode: \"refuse\"` is the default and is today's behaviour: the call that would cross the boundary is refused whole. `mode: \"metered\"` re-prices that whole call in the overage currency instead and records it as overage.","example":{"currency":"USD","mode":"metered","active":true,"unsettled":"412.75"}}},"required":["agent","mode","balance","blocked","meters","overage"]},"description":"The customer's agents that have a pool of their own, each with its own numbers. Never a total: two pools can be denominated in credits and in weighted allowance units, which have no common unit, so a summed figure across them would mean nothing. Empty when this snapshot was asked about one specific agent.","example":[{"agent":"invoice-copilot","mode":"wallet","balance":{"currency":"USD","denomination":"minor_units","wallet":"12500","unsettled":"43.218","available":"12456.782"},"blocked":false,"meters":null,"overage":null}]}},"required":["agent","mode","balance","blocked","policy","meters","credits","overage","agents"]}}}},"402":{"description":"Not enough credits, or a rolling allowance with no room left. Nothing was deducted and no window was incremented.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["telemetry_managed","not_configured","unsupported_mode","customer_not_found","wallet_missing","credit_pot_missing","pricing_unavailable","insufficient_credits","allowance_exhausted","windows_not_configured"],"description":"Machine-readable consumption refusal code.\n\n- not_configured: No billing policy is configured.\n- unsupported_mode: The billing configuration is unsupported.\n- customer_not_found: The customer could not be found.\n- wallet_missing: The monetary wallet is unavailable.\n- credit_pot_missing: The credit balance is unavailable.\n- insufficient_credits: The credit balance cannot cover the required spend.\n- allowance_exhausted: A rolling allowance has no room for the spend.\n- windows_not_configured: Rolling allowance definitions are missing.\n- pricing_unavailable: Legacy compatibility value; no longer returned. Unpriceable usage is recorded with an unpriced_usage warning.","example":"not_configured"},"message":{"type":"string","description":"Human-readable explanation of the refusal.","example":"This customer has no AI billing policy"},"balance":{"type":["object","null"],"properties":{"currency":{"type":["string","null"],"enum":["EUR","AED","AFN","XCD","ALL","AMD","AOA","ARS","USD","AUD","AWG","AZN","BAM","BBD","BDT","BGN","BHD","BIF","XOF","BMD","BND","BOB","BRL","BSD","BTN","NOK","BWP","BYR","BZD","CAD","CDF","XAF","CHF","NZD","CLP","CNY","COP","CRC","CUP","CVE","ANG","CZK","DJF","DKK","DOP","DZD","EGP","MAD","ERN","ETB","FJD","FKP","GBP","GEL","GHS","GIP","GMD","GNF","GTQ","GYD","HKD","HNL","HRK","HTG","HUF","IDR","ILS","INR","IQD","IRR","ISK","JMD","JOD","JPY","KES","KGS","KHR","KMF","KPW","KRW","KWD","KYD","KZT","LAK","LBP","LKR","LRD","LSL","LYD","MDL","MGA","MKD","MMK","MNT","MOP","MRO","MUR","MVR","MWK","MXN","MYR","MZN","NAD","XPF","NGN","NIO","NPR","OMR","PAB","PEN","PGK","PHP","PKR","PLN","PYG","QAR","RON","RSD","RUB","RWF","SAR","SBD","SCR","SDG","SEK","SGD","SHP","SLL","SOS","SRD","SSP","STD","SYP","SZL","THB","TJS","TMT","TND","TOP","TRY","TTD","TWD","TZS","UAH","UGX","UYU","UZS","VEF","VND","VUV","WST","YER","ZAR","ZMW","ZWL"],"description":"ISO 4217 currency code for monetary amounts. Null for counts or historical amounts without recorded currency.","example":"USD"},"denomination":{"type":"string","enum":["minor_units","credits","units"],"description":"Unit of account for amounts.\n\n- minor_units: Fractional minor units of the accompanying currency.\n- credits: Credit counts, without a currency.\n- units: Weighted rolling-allowance units, without a currency.","example":"minor_units"},"wallet":{"type":"string","pattern":"^-?\\d+(\\.\\d+)?(e[+-]?\\d+)?$/i","description":"The settled source balance — the wallet's balance in wallet mode, the credit pot's balance in credits mode.","example":"12500"},"unsettled":{"type":"string","pattern":"^-?\\d+(\\.\\d+)?(e[+-]?\\d+)?$/i","description":"Consumption recorded but not yet rolled into a wallet transaction. Always `0` in credits mode, where a consume decrements the real credit pot inside its own transaction and leaves nothing in flight.","example":"43.218"},"available":{"type":"string","pattern":"^-?\\d+(\\.\\d+)?(e[+-]?\\d+)?$/i","description":"`wallet - unsettled` — what the customer can still spend, and the only one of the three to gate on in either mode. Correct the instant a consume commits; in wallet mode it may go negative if they overspent between settlements.","example":"12456.782"}},"required":["currency","denomination","wallet","unsettled","available"],"description":"The balance at the moment of the refusal, when the refusal is about money — `insufficient_credits` and `allowance_exhausted` carry it so an agent knows how short it was without a second round trip. Null otherwise.","example":{"currency":"USD","denomination":"minor_units","wallet":"12500","unsettled":"43.218","available":"12456.782"}},"meters":{"type":["array","null"],"items":{"type":"object","properties":{"key":{"type":"string","description":"The window this meter is for, as the policy names it — `5h`, `7d`, `monthly`.","example":"5h"},"included_units":{"type":"string","pattern":"^-?\\d+(\\.\\d+)?(e[+-]?\\d+)?$/i","description":"The whole allowance for one instance of this window.","example":"50000"},"used_units":{"type":"string","pattern":"^-?\\d+(\\.\\d+)?(e[+-]?\\d+)?$/i","description":"Weighted units consumed inside the open instance, counting the call that just returned. Zero when no instance is open.","example":"12500"},"remaining_units":{"type":"string","pattern":"^-?\\d+(\\.\\d+)?(e[+-]?\\d+)?$/i","description":"`included_units - used_units`, floored at zero. The whole allowance when no instance is open.","example":"37500"},"window_started_at":{"type":["string","null"],"format":"date-time","description":"When the open instance was anchored — the first consumption after the previous instance expired. Null together with `resets_at` when no instance is open.","example":"2026-08-20T09:14:02.113Z"},"resets_at":{"type":["string","null"],"format":"date-time","description":"When the open instance expires and the allowance comes back in full. Null when no instance is open: nothing has been consumed since the last one ended, so the clock has not started and the next call is what anchors it.","example":"2026-08-20T14:14:02.113Z"}},"required":["key","included_units","used_units","remaining_units","window_started_at","resets_at"],"description":"One rolling allowance window's live state, including the call that just happened.","example":{"key":"5h","included_units":"50000","used_units":"12500","remaining_units":"37500","window_started_at":"2026-08-20T09:14:02.113Z","resets_at":"2026-08-20T14:14:02.113Z"}},"description":"Every window's state at the moment of an `allowance_exhausted` refusal, so the caller can see which one ran out and by how much. Null on every other refusal.","example":[{"key":"5h","included_units":"50000","used_units":"12500","remaining_units":"37500","window_started_at":"2026-08-20T09:14:02.113Z","resets_at":"2026-08-20T14:14:02.113Z"}]},"resets_at":{"type":["string","null"],"format":"date-time","description":"The soonest instant one of the windows that blocked the call rolls over — the earliest of them, since that is the next moment the answer could change. Null when no blocking window has an open instance, which means the call is larger than a whole allowance and waiting will not help. Null on every other refusal.","example":"2026-08-20T14:14:02.113Z"}},"required":["code","message","balance","meters","resets_at"]}}}},"404":{"description":"Customer not found.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["telemetry_managed","not_configured","unsupported_mode","customer_not_found","wallet_missing","credit_pot_missing","pricing_unavailable","insufficient_credits","allowance_exhausted","windows_not_configured"],"description":"Machine-readable consumption refusal code.\n\n- not_configured: No billing policy is configured.\n- unsupported_mode: The billing configuration is unsupported.\n- customer_not_found: The customer could not be found.\n- wallet_missing: The monetary wallet is unavailable.\n- credit_pot_missing: The credit balance is unavailable.\n- insufficient_credits: The credit balance cannot cover the required spend.\n- allowance_exhausted: A rolling allowance has no room for the spend.\n- windows_not_configured: Rolling allowance definitions are missing.\n- pricing_unavailable: Legacy compatibility value; no longer returned. Unpriceable usage is recorded with an unpriced_usage warning.","example":"not_configured"},"message":{"type":"string","description":"Human-readable explanation of the refusal.","example":"This customer has no AI billing policy"},"balance":{"type":["object","null"],"properties":{"currency":{"type":["string","null"],"enum":["EUR","AED","AFN","XCD","ALL","AMD","AOA","ARS","USD","AUD","AWG","AZN","BAM","BBD","BDT","BGN","BHD","BIF","XOF","BMD","BND","BOB","BRL","BSD","BTN","NOK","BWP","BYR","BZD","CAD","CDF","XAF","CHF","NZD","CLP","CNY","COP","CRC","CUP","CVE","ANG","CZK","DJF","DKK","DOP","DZD","EGP","MAD","ERN","ETB","FJD","FKP","GBP","GEL","GHS","GIP","GMD","GNF","GTQ","GYD","HKD","HNL","HRK","HTG","HUF","IDR","ILS","INR","IQD","IRR","ISK","JMD","JOD","JPY","KES","KGS","KHR","KMF","KPW","KRW","KWD","KYD","KZT","LAK","LBP","LKR","LRD","LSL","LYD","MDL","MGA","MKD","MMK","MNT","MOP","MRO","MUR","MVR","MWK","MXN","MYR","MZN","NAD","XPF","NGN","NIO","NPR","OMR","PAB","PEN","PGK","PHP","PKR","PLN","PYG","QAR","RON","RSD","RUB","RWF","SAR","SBD","SCR","SDG","SEK","SGD","SHP","SLL","SOS","SRD","SSP","STD","SYP","SZL","THB","TJS","TMT","TND","TOP","TRY","TTD","TWD","TZS","UAH","UGX","UYU","UZS","VEF","VND","VUV","WST","YER","ZAR","ZMW","ZWL"],"description":"ISO 4217 currency code for monetary amounts. Null for counts or historical amounts without recorded currency.","example":"USD"},"denomination":{"type":"string","enum":["minor_units","credits","units"],"description":"Unit of account for amounts.\n\n- minor_units: Fractional minor units of the accompanying currency.\n- credits: Credit counts, without a currency.\n- units: Weighted rolling-allowance units, without a currency.","example":"minor_units"},"wallet":{"type":"string","pattern":"^-?\\d+(\\.\\d+)?(e[+-]?\\d+)?$/i","description":"The settled source balance — the wallet's balance in wallet mode, the credit pot's balance in credits mode.","example":"12500"},"unsettled":{"type":"string","pattern":"^-?\\d+(\\.\\d+)?(e[+-]?\\d+)?$/i","description":"Consumption recorded but not yet rolled into a wallet transaction. Always `0` in credits mode, where a consume decrements the real credit pot inside its own transaction and leaves nothing in flight.","example":"43.218"},"available":{"type":"string","pattern":"^-?\\d+(\\.\\d+)?(e[+-]?\\d+)?$/i","description":"`wallet - unsettled` — what the customer can still spend, and the only one of the three to gate on in either mode. Correct the instant a consume commits; in wallet mode it may go negative if they overspent between settlements.","example":"12456.782"}},"required":["currency","denomination","wallet","unsettled","available"],"description":"The balance at the moment of the refusal, when the refusal is about money — `insufficient_credits` and `allowance_exhausted` carry it so an agent knows how short it was without a second round trip. Null otherwise.","example":{"currency":"USD","denomination":"minor_units","wallet":"12500","unsettled":"43.218","available":"12456.782"}},"meters":{"type":["array","null"],"items":{"type":"object","properties":{"key":{"type":"string","description":"The window this meter is for, as the policy names it — `5h`, `7d`, `monthly`.","example":"5h"},"included_units":{"type":"string","pattern":"^-?\\d+(\\.\\d+)?(e[+-]?\\d+)?$/i","description":"The whole allowance for one instance of this window.","example":"50000"},"used_units":{"type":"string","pattern":"^-?\\d+(\\.\\d+)?(e[+-]?\\d+)?$/i","description":"Weighted units consumed inside the open instance, counting the call that just returned. Zero when no instance is open.","example":"12500"},"remaining_units":{"type":"string","pattern":"^-?\\d+(\\.\\d+)?(e[+-]?\\d+)?$/i","description":"`included_units - used_units`, floored at zero. The whole allowance when no instance is open.","example":"37500"},"window_started_at":{"type":["string","null"],"format":"date-time","description":"When the open instance was anchored — the first consumption after the previous instance expired. Null together with `resets_at` when no instance is open.","example":"2026-08-20T09:14:02.113Z"},"resets_at":{"type":["string","null"],"format":"date-time","description":"When the open instance expires and the allowance comes back in full. Null when no instance is open: nothing has been consumed since the last one ended, so the clock has not started and the next call is what anchors it.","example":"2026-08-20T14:14:02.113Z"}},"required":["key","included_units","used_units","remaining_units","window_started_at","resets_at"],"description":"One rolling allowance window's live state, including the call that just happened.","example":{"key":"5h","included_units":"50000","used_units":"12500","remaining_units":"37500","window_started_at":"2026-08-20T09:14:02.113Z","resets_at":"2026-08-20T14:14:02.113Z"}},"description":"Every window's state at the moment of an `allowance_exhausted` refusal, so the caller can see which one ran out and by how much. Null on every other refusal.","example":[{"key":"5h","included_units":"50000","used_units":"12500","remaining_units":"37500","window_started_at":"2026-08-20T09:14:02.113Z","resets_at":"2026-08-20T14:14:02.113Z"}]},"resets_at":{"type":["string","null"],"format":"date-time","description":"The soonest instant one of the windows that blocked the call rolls over — the earliest of them, since that is the next moment the answer could change. Null when no blocking window has an open instance, which means the call is larger than a whole allowance and waiting will not help. Null on every other refusal.","example":"2026-08-20T14:14:02.113Z"}},"required":["code","message","balance","meters","resets_at"]}}}},"409":{"description":"No billing policy configured.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["telemetry_managed","not_configured","unsupported_mode","customer_not_found","wallet_missing","credit_pot_missing","pricing_unavailable","insufficient_credits","allowance_exhausted","windows_not_configured"],"description":"Machine-readable consumption refusal code.\n\n- not_configured: No billing policy is configured.\n- unsupported_mode: The billing configuration is unsupported.\n- customer_not_found: The customer could not be found.\n- wallet_missing: The monetary wallet is unavailable.\n- credit_pot_missing: The credit balance is unavailable.\n- insufficient_credits: The credit balance cannot cover the required spend.\n- allowance_exhausted: A rolling allowance has no room for the spend.\n- windows_not_configured: Rolling allowance definitions are missing.\n- pricing_unavailable: Legacy compatibility value; no longer returned. Unpriceable usage is recorded with an unpriced_usage warning.","example":"not_configured"},"message":{"type":"string","description":"Human-readable explanation of the refusal.","example":"This customer has no AI billing policy"},"balance":{"type":["object","null"],"properties":{"currency":{"type":["string","null"],"enum":["EUR","AED","AFN","XCD","ALL","AMD","AOA","ARS","USD","AUD","AWG","AZN","BAM","BBD","BDT","BGN","BHD","BIF","XOF","BMD","BND","BOB","BRL","BSD","BTN","NOK","BWP","BYR","BZD","CAD","CDF","XAF","CHF","NZD","CLP","CNY","COP","CRC","CUP","CVE","ANG","CZK","DJF","DKK","DOP","DZD","EGP","MAD","ERN","ETB","FJD","FKP","GBP","GEL","GHS","GIP","GMD","GNF","GTQ","GYD","HKD","HNL","HRK","HTG","HUF","IDR","ILS","INR","IQD","IRR","ISK","JMD","JOD","JPY","KES","KGS","KHR","KMF","KPW","KRW","KWD","KYD","KZT","LAK","LBP","LKR","LRD","LSL","LYD","MDL","MGA","MKD","MMK","MNT","MOP","MRO","MUR","MVR","MWK","MXN","MYR","MZN","NAD","XPF","NGN","NIO","NPR","OMR","PAB","PEN","PGK","PHP","PKR","PLN","PYG","QAR","RON","RSD","RUB","RWF","SAR","SBD","SCR","SDG","SEK","SGD","SHP","SLL","SOS","SRD","SSP","STD","SYP","SZL","THB","TJS","TMT","TND","TOP","TRY","TTD","TWD","TZS","UAH","UGX","UYU","UZS","VEF","VND","VUV","WST","YER","ZAR","ZMW","ZWL"],"description":"ISO 4217 currency code for monetary amounts. Null for counts or historical amounts without recorded currency.","example":"USD"},"denomination":{"type":"string","enum":["minor_units","credits","units"],"description":"Unit of account for amounts.\n\n- minor_units: Fractional minor units of the accompanying currency.\n- credits: Credit counts, without a currency.\n- units: Weighted rolling-allowance units, without a currency.","example":"minor_units"},"wallet":{"type":"string","pattern":"^-?\\d+(\\.\\d+)?(e[+-]?\\d+)?$/i","description":"The settled source balance — the wallet's balance in wallet mode, the credit pot's balance in credits mode.","example":"12500"},"unsettled":{"type":"string","pattern":"^-?\\d+(\\.\\d+)?(e[+-]?\\d+)?$/i","description":"Consumption recorded but not yet rolled into a wallet transaction. Always `0` in credits mode, where a consume decrements the real credit pot inside its own transaction and leaves nothing in flight.","example":"43.218"},"available":{"type":"string","pattern":"^-?\\d+(\\.\\d+)?(e[+-]?\\d+)?$/i","description":"`wallet - unsettled` — what the customer can still spend, and the only one of the three to gate on in either mode. Correct the instant a consume commits; in wallet mode it may go negative if they overspent between settlements.","example":"12456.782"}},"required":["currency","denomination","wallet","unsettled","available"],"description":"The balance at the moment of the refusal, when the refusal is about money — `insufficient_credits` and `allowance_exhausted` carry it so an agent knows how short it was without a second round trip. Null otherwise.","example":{"currency":"USD","denomination":"minor_units","wallet":"12500","unsettled":"43.218","available":"12456.782"}},"meters":{"type":["array","null"],"items":{"type":"object","properties":{"key":{"type":"string","description":"The window this meter is for, as the policy names it — `5h`, `7d`, `monthly`.","example":"5h"},"included_units":{"type":"string","pattern":"^-?\\d+(\\.\\d+)?(e[+-]?\\d+)?$/i","description":"The whole allowance for one instance of this window.","example":"50000"},"used_units":{"type":"string","pattern":"^-?\\d+(\\.\\d+)?(e[+-]?\\d+)?$/i","description":"Weighted units consumed inside the open instance, counting the call that just returned. Zero when no instance is open.","example":"12500"},"remaining_units":{"type":"string","pattern":"^-?\\d+(\\.\\d+)?(e[+-]?\\d+)?$/i","description":"`included_units - used_units`, floored at zero. The whole allowance when no instance is open.","example":"37500"},"window_started_at":{"type":["string","null"],"format":"date-time","description":"When the open instance was anchored — the first consumption after the previous instance expired. Null together with `resets_at` when no instance is open.","example":"2026-08-20T09:14:02.113Z"},"resets_at":{"type":["string","null"],"format":"date-time","description":"When the open instance expires and the allowance comes back in full. Null when no instance is open: nothing has been consumed since the last one ended, so the clock has not started and the next call is what anchors it.","example":"2026-08-20T14:14:02.113Z"}},"required":["key","included_units","used_units","remaining_units","window_started_at","resets_at"],"description":"One rolling allowance window's live state, including the call that just happened.","example":{"key":"5h","included_units":"50000","used_units":"12500","remaining_units":"37500","window_started_at":"2026-08-20T09:14:02.113Z","resets_at":"2026-08-20T14:14:02.113Z"}},"description":"Every window's state at the moment of an `allowance_exhausted` refusal, so the caller can see which one ran out and by how much. Null on every other refusal.","example":[{"key":"5h","included_units":"50000","used_units":"12500","remaining_units":"37500","window_started_at":"2026-08-20T09:14:02.113Z","resets_at":"2026-08-20T14:14:02.113Z"}]},"resets_at":{"type":["string","null"],"format":"date-time","description":"The soonest instant one of the windows that blocked the call rolls over — the earliest of them, since that is the next moment the answer could change. Null when no blocking window has an open instance, which means the call is larger than a whole allowance and waiting will not help. Null on every other refusal.","example":"2026-08-20T14:14:02.113Z"}},"required":["code","message","balance","meters","resets_at"]}}}},"422":{"description":"The policy cannot bill this: an unsupported mode, a missing wallet or credit pot, an unconfigured window card, or usage no rate card prices.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["telemetry_managed","not_configured","unsupported_mode","customer_not_found","wallet_missing","credit_pot_missing","pricing_unavailable","insufficient_credits","allowance_exhausted","windows_not_configured"],"description":"Machine-readable consumption refusal code.\n\n- not_configured: No billing policy is configured.\n- unsupported_mode: The billing configuration is unsupported.\n- customer_not_found: The customer could not be found.\n- wallet_missing: The monetary wallet is unavailable.\n- credit_pot_missing: The credit balance is unavailable.\n- insufficient_credits: The credit balance cannot cover the required spend.\n- allowance_exhausted: A rolling allowance has no room for the spend.\n- windows_not_configured: Rolling allowance definitions are missing.\n- pricing_unavailable: Legacy compatibility value; no longer returned. Unpriceable usage is recorded with an unpriced_usage warning.","example":"not_configured"},"message":{"type":"string","description":"Human-readable explanation of the refusal.","example":"This customer has no AI billing policy"},"balance":{"type":["object","null"],"properties":{"currency":{"type":["string","null"],"enum":["EUR","AED","AFN","XCD","ALL","AMD","AOA","ARS","USD","AUD","AWG","AZN","BAM","BBD","BDT","BGN","BHD","BIF","XOF","BMD","BND","BOB","BRL","BSD","BTN","NOK","BWP","BYR","BZD","CAD","CDF","XAF","CHF","NZD","CLP","CNY","COP","CRC","CUP","CVE","ANG","CZK","DJF","DKK","DOP","DZD","EGP","MAD","ERN","ETB","FJD","FKP","GBP","GEL","GHS","GIP","GMD","GNF","GTQ","GYD","HKD","HNL","HRK","HTG","HUF","IDR","ILS","INR","IQD","IRR","ISK","JMD","JOD","JPY","KES","KGS","KHR","KMF","KPW","KRW","KWD","KYD","KZT","LAK","LBP","LKR","LRD","LSL","LYD","MDL","MGA","MKD","MMK","MNT","MOP","MRO","MUR","MVR","MWK","MXN","MYR","MZN","NAD","XPF","NGN","NIO","NPR","OMR","PAB","PEN","PGK","PHP","PKR","PLN","PYG","QAR","RON","RSD","RUB","RWF","SAR","SBD","SCR","SDG","SEK","SGD","SHP","SLL","SOS","SRD","SSP","STD","SYP","SZL","THB","TJS","TMT","TND","TOP","TRY","TTD","TWD","TZS","UAH","UGX","UYU","UZS","VEF","VND","VUV","WST","YER","ZAR","ZMW","ZWL"],"description":"ISO 4217 currency code for monetary amounts. Null for counts or historical amounts without recorded currency.","example":"USD"},"denomination":{"type":"string","enum":["minor_units","credits","units"],"description":"Unit of account for amounts.\n\n- minor_units: Fractional minor units of the accompanying currency.\n- credits: Credit counts, without a currency.\n- units: Weighted rolling-allowance units, without a currency.","example":"minor_units"},"wallet":{"type":"string","pattern":"^-?\\d+(\\.\\d+)?(e[+-]?\\d+)?$/i","description":"The settled source balance — the wallet's balance in wallet mode, the credit pot's balance in credits mode.","example":"12500"},"unsettled":{"type":"string","pattern":"^-?\\d+(\\.\\d+)?(e[+-]?\\d+)?$/i","description":"Consumption recorded but not yet rolled into a wallet transaction. Always `0` in credits mode, where a consume decrements the real credit pot inside its own transaction and leaves nothing in flight.","example":"43.218"},"available":{"type":"string","pattern":"^-?\\d+(\\.\\d+)?(e[+-]?\\d+)?$/i","description":"`wallet - unsettled` — what the customer can still spend, and the only one of the three to gate on in either mode. Correct the instant a consume commits; in wallet mode it may go negative if they overspent between settlements.","example":"12456.782"}},"required":["currency","denomination","wallet","unsettled","available"],"description":"The balance at the moment of the refusal, when the refusal is about money — `insufficient_credits` and `allowance_exhausted` carry it so an agent knows how short it was without a second round trip. Null otherwise.","example":{"currency":"USD","denomination":"minor_units","wallet":"12500","unsettled":"43.218","available":"12456.782"}},"meters":{"type":["array","null"],"items":{"type":"object","properties":{"key":{"type":"string","description":"The window this meter is for, as the policy names it — `5h`, `7d`, `monthly`.","example":"5h"},"included_units":{"type":"string","pattern":"^-?\\d+(\\.\\d+)?(e[+-]?\\d+)?$/i","description":"The whole allowance for one instance of this window.","example":"50000"},"used_units":{"type":"string","pattern":"^-?\\d+(\\.\\d+)?(e[+-]?\\d+)?$/i","description":"Weighted units consumed inside the open instance, counting the call that just returned. Zero when no instance is open.","example":"12500"},"remaining_units":{"type":"string","pattern":"^-?\\d+(\\.\\d+)?(e[+-]?\\d+)?$/i","description":"`included_units - used_units`, floored at zero. The whole allowance when no instance is open.","example":"37500"},"window_started_at":{"type":["string","null"],"format":"date-time","description":"When the open instance was anchored — the first consumption after the previous instance expired. Null together with `resets_at` when no instance is open.","example":"2026-08-20T09:14:02.113Z"},"resets_at":{"type":["string","null"],"format":"date-time","description":"When the open instance expires and the allowance comes back in full. Null when no instance is open: nothing has been consumed since the last one ended, so the clock has not started and the next call is what anchors it.","example":"2026-08-20T14:14:02.113Z"}},"required":["key","included_units","used_units","remaining_units","window_started_at","resets_at"],"description":"One rolling allowance window's live state, including the call that just happened.","example":{"key":"5h","included_units":"50000","used_units":"12500","remaining_units":"37500","window_started_at":"2026-08-20T09:14:02.113Z","resets_at":"2026-08-20T14:14:02.113Z"}},"description":"Every window's state at the moment of an `allowance_exhausted` refusal, so the caller can see which one ran out and by how much. Null on every other refusal.","example":[{"key":"5h","included_units":"50000","used_units":"12500","remaining_units":"37500","window_started_at":"2026-08-20T09:14:02.113Z","resets_at":"2026-08-20T14:14:02.113Z"}]},"resets_at":{"type":["string","null"],"format":"date-time","description":"The soonest instant one of the windows that blocked the call rolls over — the earliest of them, since that is the next moment the answer could change. Null when no blocking window has an open instance, which means the call is larger than a whole allowance and waiting will not help. Null on every other refusal.","example":"2026-08-20T14:14:02.113Z"}},"required":["code","message","balance","meters","resets_at"]}}}}}}},"/v1/ai/calls":{"post":{"operationId":"ingestAiCalls","tags":["AI > Ingest"],"security":[{"bearer":[]}],"summary":"Ingest AI calls","description":"Ingest a batch of AI records (limited to max 2000 per request) — model calls and non-LLM cost items, told apart by `record_kind` (omitted means `llm_call`). Records are processed asynchronously; a record with the same id is deduplicated on storage.","requestBody":{"description":"AI calls payload.","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":128,"description":"Caller-generated record id. A record with the same id is deduplicated on storage.","example":"aic_01JT4E2Q4N8N0F0X4S2M3R7YQK"},"run_id":{"type":"string","minLength":1,"maxLength":128,"description":"The run this record belongs to. Every record captured inside one `hyperline.run()` shares it.","example":"run_01JT4E2Q4N8N0F0X4S2M3R7YQL"},"parent_run_id":{"type":["string","null"],"minLength":1,"maxLength":128,"description":"The enclosing run, when this one was opened inside another. Null at the top of a run tree.","example":null},"customer_id":{"type":"string","minLength":1,"maxLength":255,"description":"The customer this usage is attributed to — the external id your application knows them by, or a Hyperline `cus_…` id.","example":"cus_xyz789"},"agent":{"type":"string","minLength":1,"maxLength":128,"description":"Stable agent identity, e.g. the agent's name or type.","example":"invoice-copilot"},"action":{"type":["string","null"],"minLength":1,"maxLength":128,"description":"What the run does, e.g. `deep_research`. Null when unnamed.","example":"monitoring_analysis"},"record_kind":{"type":"string","enum":["llm_call","cost"],"default":"llm_call","description":"Type of usage record. Defaults to llm_call when omitted.\n\n- llm_call: Model invocation with token usage.\n- cost: Non-LLM cost item; provider and model identify the vendor and item, and usage_extra carries the quantity.","example":"llm_call"},"provider":{"type":"string","minLength":1,"maxLength":64,"description":"The model's provider, or the vendor on a `cost` record.","example":"anthropic"},"model":{"type":"string","minLength":1,"maxLength":128,"description":"The model invoked, or the item purchased on a `cost` record.","example":"claude-sonnet-5"},"input_tokens":{"type":"integer","minimum":0,"maximum":1000000000,"description":"Uncached input tokens.","example":12400},"output_tokens":{"type":"integer","minimum":0,"maximum":1000000000,"description":"Output tokens.","example":1300},"cached_input_tokens":{"type":"integer","minimum":0,"maximum":1000000000,"description":"Input tokens served from the provider's prompt cache.","example":9000},"cache_write_tokens":{"type":"integer","minimum":0,"maximum":1000000000,"description":"Input tokens written into the provider's prompt cache.","example":0},"reasoning_tokens":{"type":"integer","minimum":0,"maximum":1000000000,"description":"Reasoning tokens, on models that bill them separately.","example":0},"status":{"type":"string","enum":["ok","error"],"description":"Call outcome.\n\n- ok: Call succeeded.\n- error: Call failed.","example":"ok"},"duration_ms":{"type":"integer","minimum":0,"description":"Wall-clock duration of the call.","example":1840},"started_at":{"type":"string","format":"date-time","description":"When the call started, as an ISO instant.","example":"2026-08-18T10:22:31.201Z"},"metadata":{"type":["object","null"],"additionalProperties":{"anyOf":[{"type":"string","maxLength":1024},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"null"}]},"description":"Free-form bag carried alongside the record. At most 50 keys, string values at most 1024 characters, 4096 bytes once serialized.","example":{"conversation_id":"cnv_123"}},"usage_extra":{"type":["object","null"],"additionalProperties":{"type":"number","minimum":0,"maximum":1000000000000},"description":"Cost dimensions beyond the token classes — provider extras (web searches, image generations) or the caller's own units (vector queries, gpu_seconds). Keys must match `[a-z0-9_.]{1,64}`, values must be finite and at most 1e12, at most 20 keys.","example":{"web_search":2}}},"required":["id","run_id","parent_run_id","customer_id","agent","action","provider","model","input_tokens","output_tokens","cached_input_tokens","cache_write_tokens","reasoning_tokens","status","duration_ms","started_at","metadata"],"description":"One record captured by the Hyperline AI SDK — a model call (`record_kind: \"llm_call\"`, the default when the field is absent) or a non-LLM cost item (`record_kind: \"cost\"`, where `provider`/`model` carry the vendor/item and the quantity rides in `usage_extra`).","example":{"id":"aic_01JT4E2Q4N8N0F0X4S2M3R7YQK","run_id":"run_01JT4E2Q4N8N0F0X4S2M3R7YQL","parent_run_id":null,"customer_id":"cus_xyz789","agent":"invoice-copilot","action":"monitoring_analysis","record_kind":"llm_call","provider":"anthropic","model":"claude-sonnet-5","input_tokens":12400,"output_tokens":1300,"cached_input_tokens":9000,"cache_write_tokens":0,"reasoning_tokens":0,"status":"ok","duration_ms":1840,"started_at":"2026-08-18T10:22:31.201Z","metadata":{"conversation_id":"cnv_123"},"usage_extra":{"web_search":2}}},"minItems":1,"maxItems":2000}}}},"responses":{"202":{"description":"Calls accepted.","content":{"application/json":{"schema":{"type":"object","properties":{"calls_accepted":{"type":"integer","description":"Number of calls accepted for asynchronous processing.","example":42}},"required":["calls_accepted"]}}}}}}},"/v1/events":{"get":{"operationId":"getEvents","tags":["Billable events"],"security":[{"bearer":[]}],"summary":"Get events","description":"Retrieve billable events filtered by event type.","parameters":[{"schema":{"type":["number","null"],"minimum":0,"maximum":100,"default":50},"required":false,"name":"take","in":"query"},{"schema":{"type":["number","null"],"minimum":0,"default":0},"required":false,"name":"skip","in":"query"},{"schema":{"type":"string","enum":["asc","desc"],"default":"desc","description":"Sort direction.","example":"desc"},"required":false,"description":"Sort direction.","name":"order","in":"query"},{"schema":{"type":"string","enum":["timestamp"],"description":"Field used to sort the results."},"required":false,"description":"Field used to sort the results.","name":"sort","in":"query"},{"schema":{"type":"string","description":"Event type to filter by","example":"api_call"},"required":true,"description":"Event type to filter by","name":"event_type","in":"query"},{"schema":{"type":"string","description":"Filter by customer ID","example":"cus_xyz789"},"required":false,"description":"Filter by customer ID","name":"customer_id","in":"query"},{"schema":{"type":"string","description":"Filter by record ID. Supports comma-separated list for multiple records.","example":"rec_123"},"required":false,"description":"Filter by record ID. Supports comma-separated list for multiple records.","name":"record_id__in","in":"query"},{"schema":{"type":"object","additionalProperties":{"type":"string"},"description":"Filter on properties of the event record, passed as `record[<property>]=<value>` (for example `record[case_id]=cas_123`). Append `__in` to the property name to match a comma-separated list, such as `record[case_id__in]=cas_123,cas_456`. Values are compared as strings, several properties can be combined and are joined with a logical AND, and at most 5 properties can be filtered at once.","example":{"case_id":"cas_123"}},"required":false,"description":"Filter on properties of the event record, passed as `record[<property>]=<value>` (for example `record[case_id]=cas_123`). Append `__in` to the property name to match a comma-separated list, such as `record[case_id__in]=cas_123,cas_456`. Values are compared as strings, several properties can be combined and are joined with a logical AND, and at most 5 properties can be filtered at once.","name":"record","in":"query"},{"schema":{"type":"string","format":"date-time","description":"Filter events with timestamp greater than or equal to this ISO8601 date.","example":"2024-01-01T00:00:00Z"},"required":false,"description":"Filter events with timestamp greater than or equal to this ISO8601 date.","name":"timestamp_gte","in":"query"},{"schema":{"type":"string","format":"date-time","description":"Filter events with timestamp less than or equal to this ISO8601 date.","example":"2024-01-31T23:59:59Z"},"required":false,"description":"Filter events with timestamp less than or equal to this ISO8601 date.","name":"timestamp_lte","in":"query"}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaginatedEvent"}}}}}},"post":{"operationId":"ingestBillableEvent","tags":["Billable events"],"security":[{"bearer":[]}],"summary":"Ingest billable event","description":"Ingest a new billable event. This endpoint is idempotent, an event with the same id will be updated if it already exists.","requestBody":{"description":"Event payload","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BillableEvent"}}}},"responses":{"201":{"description":"Event ingested"},"503":{"description":"Ingestion is temporarily overloaded. The request was not processed: retry after the delay given by the `Retry-After` header, with exponential backoff and jitter.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IngestionOverloadedError"}}}}}},"delete":{"operationId":"deleteBillableEvents","tags":["Billable events"],"security":[{"bearer":[]}],"summary":"Delete billable events","description":"Delete existing billable events.","requestBody":{"description":"Delete billable events payload","content":{"application/json":{"schema":{"oneOf":[{"type":"object","properties":{"matching":{"type":"string","enum":["record_ids"]},"record_ids":{"type":"array","items":{"type":"string"},"maxItems":5000,"description":"List of event record IDs to delete."}},"required":["matching","record_ids"]},{"type":"object","properties":{"matching":{"type":"string","enum":["customer_id"]},"customer_id":{"type":"string","description":"Customer ID for which the events will be deleted."},"event_type":{"type":"string","minLength":1,"description":"Type corresponding to the event. When creating a dynamic product, this type will be used to map the related events to specific prices.","example":"api_call"}},"required":["matching","customer_id"]},{"type":"object","properties":{"matching":{"type":"string","enum":["event_type"]},"event_type":{"type":"string","minLength":1,"description":"When matching by `event_type`, every event of this type will be deleted across all customers.","example":"api_call"}},"required":["matching","event_type"]},{"type":"object","properties":{"matching":{"type":"string","enum":["all"],"description":"All events will be deleted."}},"required":["matching"]}]}}}},"responses":{"200":{"description":"Events deleted","content":{"application/json":{"schema":{"type":"number","description":"Number of events deleted","example":1}}}},"503":{"description":"Ingestion is temporarily overloaded. The request was not processed: retry after the delay given by the `Retry-After` header, with exponential backoff and jitter.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IngestionOverloadedError"}}}}}}},"/v1/events/batch":{"post":{"operationId":"ingestBillableEvents","tags":["Billable events"],"security":[{"bearer":[]}],"summary":"Ingest billable events","description":"Ingest several billable events in batch (limited to max 5000 events per request). This endpoint is idempotent, an event with the same id, will be updated if it already exists.","requestBody":{"description":"Events payload","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/BillableEvent"},"minItems":1,"maxItems":5000}}}},"responses":{"201":{"description":"Events ingested","content":{"application/json":{"schema":{"type":"object","properties":{"events_created":{"type":"array","items":{"$ref":"#/components/schemas/BillableEvent"}},"events_failed":{"type":"array","items":{"$ref":"#/components/schemas/BillableEvent"}}},"required":["events_created","events_failed"]}}}},"503":{"description":"Ingestion is temporarily overloaded. The request was not processed: retry after the delay given by the `Retry-After` header, with exponential backoff and jitter.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IngestionOverloadedError"}}}}}}}},"webhooks":{}}