The account page offers one gzipped CSV per UTC day with a row for every request you sent through Kottos AI, exactly as the tape recorded it. This page explains the columns in order they appear in the file.
t0_utc is UTC, written YYYY-MM-DD HH:MM:SS. Each daily file covers one UTC day._udollars are micro-dollars (divide by 1,000,000 for dollars). Columns ending _pdollars are picodollars (divide by 1012), used where a single request's amount is often below a micro-dollar. The two quote_*_utok columns are micro-dollars per million tokens, so 3000000 is $3.00 per million tokens.1 or 0. Named values (errors, tiers, decisions) print as words; a number such as error-14 means a code newer than the reader that wrote the file.=, +, - or @ gets a leading apostrophe inside the quotes, so a spreadsheet shows it as text and never runs it as a formula.flags and flags2 are internal bitfields printed as one number each; add up the bits that are set. Most bits that matter to you also have a column of their own. The others:
For each row, what identifies each request, who sent it, and where it went.
| # | Column | Unit or type | Meaning |
|---|---|---|---|
| 1 | t0_utc | date-time, UTC | When the gateway had your whole request, as YYYY-MM-DD HH:MM:SS in UTC, to the second. |
| 2 | gateway_id | id | The Kottos AI gateway node that served the request. |
| 6 | tenant | id | Your account's numeric id; every row in your file carries the same one. |
| 7 | status | HTTP status | The HTTP status your client received; 0 on a hedge leg that was cut because another leg won. |
| 8 | venue_id | id | The venue that served the request: a provider and, where it has several, a region (for example a Bedrock region). |
| 9 | product_id | id | The listing that was bought at that venue, which names the model and its grade. |
| 10 | step | text | The step your request named in the x-kottos-step header, empty when it named none. |
| 11 | run_id | text | The run id your client sent, stored exactly, so you can sum cost and time per run. |
| 43 | request_bytes | bytes | The size of your request as it reached the gateway, headers and body; empty on rows that did not record it. |
| 54 | venue_req_id | id | The venue's own id for the request; quote it in a support ticket with that provider. Empty when the venue sent none. |
We store the usage venues report. Counts are tokens by default unless the name says requests or calls.
| # | Column | Unit or type | Meaning |
|---|---|---|---|
| 12 | tokens_in | tokens | Input tokens the venue reported, including the cached and cache-write parts below; 0 when the venue stated no count (flags2 bit 8). |
| 13 | tokens_out | tokens | Output tokens the venue reported, including reasoning tokens. |
| 14 | cached | tokens | The part of tokens_in served from the venue's prompt cache, billed at the cheaper cache-read rate. |
| 15 | cache_write | tokens | The part of tokens_in written to the venue's prompt cache. |
| 16 | cache_write_5m | tokens | Of cache_write, the tokens written with a five-minute lifetime. |
| 17 | cache_write_1h | tokens | Of cache_write, the tokens written with a one-hour lifetime, which venues price higher. |
| 18 | cache_write_unsplit | flag 0/1 | 1 when the venue gave a cache-write total without the lifetime split, so the two columns before it are 0 because nothing measured them. |
| 56 | reasoning_tokens | tokens | Reasoning tokens the venue reported, part of tokens_out; empty when the venue stated none of these details. |
| 57 | audio_in_tokens | tokens | Audio input tokens, priced at their own rate; empty when the venue stated no details. |
| 58 | audio_out_tokens | tokens | Audio output tokens, priced at their own rate; empty when the venue stated no details. |
| 59 | accepted_prediction_tokens | tokens | OpenAI predicted-output tokens that were accepted; empty when the venue stated no details. |
| 60 | rejected_prediction_tokens | tokens | OpenAI predicted-output tokens that were rejected, billed but never shown; empty when the venue stated no details. |
| 61 | tool_prompt_tokens | tokens | Tokens Gemini added to the prompt for its server tools; empty when the venue stated no details. |
| 84 | image_in_tokens | tokens | Image input tokens, part of tokens_in. Empty on rows written before 0.95.0 recorded the venue's extra usage. |
| 85 | web_search_requests | requests | Server-side web searches the venue billed per call; in actual_cost_udollars, not in the fee. Empty on rows written before 0.95.0 recorded the venue's extra usage. |
| 86 | web_fetch_requests | requests | Server-side web fetches the venue billed per call. Empty on rows written before 0.95.0 recorded the venue's extra usage. |
| 87 | code_exec_requests | requests | Server-side code executions the venue billed per call. Empty on rows written before 0.95.0 recorded the venue's extra usage. |
| 88 | file_search_calls | calls | File search calls counted from a Responses API reply. Empty on rows written before 0.95.0 recorded the venue's extra usage. |
| 90 | compaction_in_tokens | tokens | Input tokens of Anthropic context-compaction passes, billed by the venue beside the main counts and included in actual_cost_udollars; the Kottos AI fee does not charge them. Empty on rows written before 0.95.0 recorded the venue's extra usage. |
| 91 | compaction_out_tokens | tokens | Output tokens of those compaction passes. Empty on rows written before 0.95.0 recorded the venue's extra usage. |
| 92 | compaction_cached_tokens | tokens | Cached input tokens of those compaction passes. Empty on rows written before 0.95.0 recorded the venue's extra usage. |
| 93 | prior_in_tokens | tokens | Input tokens of attempts the venue declined before a fallback model ran (see prior_model); not in actual_cost_udollars. Empty on rows written before 0.95.0 recorded the venue's extra usage. |
| 94 | prior_out_tokens | tokens | Output tokens of those declined attempts. Empty on rows written before 0.95.0 recorded the venue's extra usage. |
| 95 | prior_cached_tokens | tokens | Cached input tokens of those declined attempts. Empty on rows written before 0.95.0 recorded the venue's extra usage. |
| 96 | prior_cache_write_tokens | tokens | Cache-write tokens of those declined attempts. Empty on rows written before 0.95.0 recorded the venue's extra usage. |
| 97 | prior_attempts | count | How many attempts the venue declined before the fallback. Empty on rows written before 0.95.0 recorded the venue's extra usage. |
| 114 | tokens_out_unknown | flag 0/1 | 1 when the venue stated the input count and left only the output count unstated; 0 on rows before 0.110.0. |
Quoted prices, request cost at quoted prices, and Kottos AI fee.
| # | Column | Unit or type | Meaning |
|---|---|---|---|
| 19 | quote_in_utok | micro-dollars per million tokens | The listing's input price when the request was routed; divide by 1,000,000 for dollars per million tokens. |
| 20 | quote_out_utok | micro-dollars per million tokens | The listing's output price when the request was routed, in the same unit. |
| 53 | actual_cost_udollars | micro-dollars | What the request cost at the listing's list prices, every token class at its own rate, the same prices the estimate used; empty when it could not be priced. |
| 76 | kottos_fee_pdollars | picodollars | The Kottos AI fee for this request, final, in picodollars (divide by 1e12 for dollars); 0 on a refused or failed request, empty where not recorded. |
| 89 | venue_cost_pdollars | picodollars | The venue's own stated price for the request (DeepInfra states one), a check on actual_cost_udollars; empty where the venue stated none. |
Durations are in microseconds unless stated differently (1,000 µs is one millisecond).
| # | Column | Unit or type | Meaning |
|---|---|---|---|
| 21 | client_upload_us | µs | How long your request took to arrive, from its first byte to its last; 0 when it arrived in one read, as small requests do. |
| 22 | gateway_us | µs | The gateway's own work on the request, excluding the connection handshake and the provider; on a streamed body much of it overlaps your upload, so read added_us for the wait we added. |
| 23 | connect_us | µs | The TCP and TLS handshake to the venue; 0 when a pooled connection was reused. |
| 24 | upwrite_us | µs | Writing the request to the venue's connection, part of gateway_us; it grows with request_bytes. |
| 25 | ttfb_us | µs | From the end of your request body to the venue's first response byte; 0 unless the request was streamed. |
| 26 | ttft_us | µs | From the end of your request body to the first visible content token. |
| 27 | first_thinking_us | µs | From the end of your request body to the first reasoning token; 0 when the model did not reason. ttft_us minus this is time spent reasoning. |
| 28 | max_chunk_gap_us | µs | The longest silence between two chunks after the first visible token; 0 without two chunks to measure. |
| 34 | upstream_us | µs | From the last byte of your request reaching the venue to the venue's response head. |
| 35 | total_us | µs | From the gateway having your whole request to the end of its reply. |
| 62 | upstream_min_rtt_us | µs | The lowest network round trip to the venue the kernel had measured on the connection; empty when not recorded. |
| 63 | upstream_srtt_us | µs | The smoothed network round trip to the venue at its response; empty when not recorded. |
| 64 | body_streamed | flag 0/1 | 1 when the gateway forwarded your request body to the venue while it was still arriving, instead of waiting for its last byte. |
| 65 | body_cut_short | flag 0/1 | 1 when the venue answered before your whole body was in or sent; the rest was read and dropped. |
| 66 | body_end_us | µs | When your body's last byte arrived, counted from the request start; 0 for a held body and for one cut short. |
| 67 | body_sent_us | µs | When your body's last byte was handed to the venue's connection, counted from the request start; the venue's wait starts here. |
| 68 | body_work_us | µs | Gateway work on a streamed body after the request was framed, part of gateway_us; 0 for a held body. |
| 83 | added_us | µs | The wait the gateway added to your request: our time after your last byte, not work done while you were still uploading. On rows before 0.91.0 it repeats gateway_us. |
We track what failed, and what a venue says about its own limits.
| # | Column | Unit or type | Meaning |
|---|---|---|---|
| 29 | quota_exhausted | code | Which venue limit was exhausted: 0 none, 1 requests, 2 input tokens, 3 output tokens, 4 tokens. |
| 30 | retry_after_s | seconds | The venue's Retry-After value, 0 when it sent none. |
| 31 | upstream_error | name | How the venue described a failure, empty when it did not fail (names below). |
| 32 | gateway_reply | flag 0/1 | 1 when the gateway wrote the reply itself (for example a refusal) and no venue produced it. |
| 39 | attempt | count | 0 on the first upstream attempt; higher when earlier attempts failed and the request was retried or failed over. |
| 69 | stream_truncated | flag 0/1 | 1 when a stream ended without its clean finish (a timeout, a reset or a cut from the venue); its token counts may be incomplete. |
| 70 | client_encoded | flag 0/1 | 1 when your client sent a compressed request body, which the gateway refuses; this is why. |
upstream_error names: unnamed (the venue failed and its body named nothing readable), other, invalid_request, context_length, authentication, permission, not_found, request_too_large, rate_limit, quota (billing, not pacing), api (the venue's own 5xx), overloaded, timeout.
We store the values that let us understand the routing decisions for each request.
| # | Column | Unit or type | Meaning |
|---|---|---|---|
| 44 | prefix_hash | hash, 16 hex digits | A hash of the request's leading bytes; rows sharing one are turns of the same conversation. Empty when no route asked for it. |
| 45 | predicted | flag 0/1 | 1 when the cost-aware router estimated this request, which fills the expected_* columns. |
| 46 | expected_cost_udollars | micro-dollars | The estimated cost at the venue that was picked. Empty when the cost estimate did not run (see predicted). |
| 47 | expected_cost_best_udollars | micro-dollars | The estimated cost at the cheapest candidate venue. Empty when the cost estimate did not run (see predicted). |
| 48 | expected_tokens_in | tokens | The input tokens the estimate assumed; compare with tokens_in. Empty when the cost estimate did not run (see predicted). |
| 49 | expected_cached_tokens | tokens | The cached tokens the estimate assumed; compare with cached. Empty when the cost estimate did not run (see predicted). |
| 50 | warm_guess | code | The router's guess about the venue's cache: 0 cold, 1 warm, 2 no cache for this request. Empty when the cost estimate did not run (see predicted). |
| 51 | route_switch | flag 0/1 | 1 when the pick moved this conversation to a different venue from its previous turn. Empty when the cost estimate did not run (see predicted). |
| 52 | expected_tokens_out | tokens | The output tokens the estimate priced; compare with tokens_out. Empty when the cost estimate did not run (see predicted). |
| 73 | decided_on_head | flag 0/1 | 1 when the router chose the venue from the start of your body, before it had all arrived. |
| 74 | confirm_outcome | name | What the check at the body's last byte made of that early choice: none, kept, redone (sent again under a new decision) or refused. |
| 75 | wasted_upload | flag 0/1 | 1 when an early choice was redone or refused after a venue had already received part of the body. |
| 78 | step_fell_back | flag 0/1 | 1 when your request named a step your account does not configure, so the default route served it; empty when unknown, including rows before 0.89.0. |
| 79 | step_cut | flag 0/1 | 1 when the step value was longer than 48 characters and the step column holds only its start; empty on rows before 0.89.0. |
| 107 | decision | name | The route's objective: ordered, expected_cost, escalate or hedge. Empty when no routing decision was recorded for the row (a refusal before routing, or rows before 0.110.0). |
| 108 | decision_why | name | Why the rule decided as it did, read with decision (names below); empty when the rule had nothing to add. |
| 109 | predicted_venue | number | The position in the venue table of the venue the decision picked; when it differs from the serving venue, failed_over is 1. Empty when no routing decision was recorded for the row (a refusal before routing, or rows before 0.110.0). |
| 110 | failed_over | flag 0/1 | 1 when the request was served by another venue than the decision picked, after a failure. Empty when no routing decision was recorded for the row (a refusal before routing, or rows before 0.110.0). |
| 111 | escalate_signal | tokens | The number the rule compared: prompt tokens for an escalation on context or a hedge cap, the last reply's reasoning tokens for an escalation on thinking; 0 when none. Empty when no routing decision was recorded for the row (a refusal before routing, or rows before 0.110.0). |
| 112 | expected_cost_current_udollars | micro-dollars | The estimated cost at the conversation's current venue, the one the switch threshold compared the cheapest against; 0 when the conversation had none. Empty when the cost estimate did not run (see predicted). |
| 113 | measured_cached_extent | tokens | How much of the prompt the venue was measured to hold in cache when last seen; filled only on a warm guess. |
decision_why by decision: for expected_cost, empty when the cheapest venue was chosen or the conversation moved, held_by_floor when a cheaper venue existed and the switch threshold kept the current one; for escalate, empty on the first model, context or thinking for the rule that moved it up; for hedge, hedged when it raced venues, otherwise why it went to one venue: over_cap (prompt over the hedge cap), no_keys (no key per venue), model_unsold, one_venue (no second healthy venue) or held (the decision never completed). The routing block from decision to expected_cost_current_udollars was added in 0.110.0.
For hedged requests we store each leg's information.
| # | Column | Unit or type | Meaning |
|---|---|---|---|
| 104 | hedge_group | id | Shared by every leg of one hedged request, so you can group them; empty when the row is not a hedge leg. |
| 105 | hedge_leg | number | Which leg this row is, 0 being the decided venue's own leg; empty when not a hedge leg. |
| 106 | hedge | name | How the leg ended: won (it served you), cut (another leg won first; no fee) or failed; empty when not a hedge leg. |
We store the model and grade you asked for, and what the venue tells us it served.
| # | Column | Unit or type | Meaning |
|---|---|---|---|
| 33 | served_tier | name | The service tier the venue said it served: default, flex, priority, scale, batch, reserved, auto or other; empty when it named none. |
| 42 | requested_model | text | The model you asked for, filled only when it is not listed at the serving venue, so the row was priced as the route's product; at most 32 characters. |
| 71 | asked_model | text | The model named in your request body, empty when it named none. |
| 72 | served_model | text | The model the venue's reply named, which is what you were served; often a dated id for an alias you asked for. |
| 77 | model_substituted | flag 0/1 | 1 when the venue was sent the route's model in place of the "auto" your client asked for. |
| 80 | tier_spliced | flag 0/1 | 1 when the listing's service tier was written into a body that streamed to the venue, replacing your own value. |
| 81 | speed_spliced | flag 0/1 | 1 when the listing's speed setting was written into a streamed body, replacing your own value. |
| 82 | geo_spliced | flag 0/1 | 1 when the listing's inference region was written into a streamed body, replacing your own value. |
| 98 | prior_model | text | The model the declined attempts ran on, before the venue fell back. Empty on rows written before 0.95.0 recorded the venue's extra usage. |
| 99 | served_speed | text | The speed the venue said it served, in its own words (Anthropic's usage.speed). Empty on rows written before 0.95.0 recorded the venue's extra usage. |
| 100 | served_geo | text | The inference region the venue said it served (Anthropic's usage.inference_geo). Empty on rows written before 0.95.0 recorded the venue's extra usage. |
| 101 | served_latency | text | The latency setting the venue said it served (Bedrock's latency header). Empty on rows written before 0.95.0 recorded the venue's extra usage. |
| 102 | served_other_grade | flag 0/1 | 1 when the venue served a speed or region other than the listing buys, so the listing's rates, cost and fee do not fit the row. Empty on rows written before 0.95.0 recorded the venue's extra usage. |
| 103 | asked_cache_ttl | text | The cache lifetime your request asked for in prompt_cache_options.ttl. Empty on rows written before 0.95.0 recorded the venue's extra usage. |
These are Kottos AI columns we use to reconcile and debug the tape.
| # | Column | Unit or type | Meaning |
|---|---|---|---|
| 3 | instance_nonce | id | Internal: a random number per gateway process start; with gateway_id and seq it identifies a row uniquely. |
| 4 | worker | id | Internal: the gateway worker thread that handled the request. |
| 5 | seq | id | Internal: a per-process request counter that restarts at 0; unique only with gateway_id and instance_nonce. |
| 36 | snapshot_id | id | Internal: the routing snapshot the decision used; 0 when none. |
| 37 | venues_version | id | Internal: the version of the venue table in force. |
| 38 | venue_table_hash | hash | Internal: a hash of the venue table in force. |
| 40 | flags | bitfield | Internal bitfield, printed as a number (bits below). |
| 41 | flags2 | bitfield | Internal bitfield, printed as a number (bits below). |
| 55 | upstream_ip | IPv4 address | Internal: the venue address the gateway connected to; empty when none was dialled. |