Skip to content

FOCUS and token data ​

中文 Docs

CloudBridge's ledger is named after FOCUS, the FinOps Foundation's open specification for cost and usage data. FOCUS 1.5 describes the bill of an AI model API. It adds no token column; it uses the columns FOCUS already has, and CloudBridge records tokens the same way.

What a token row holds ​

FOCUS columnLedger columnHolds
ConsumedQuantityconsumed_quantityThe raw token count
ConsumedUnitconsumed_unitTokens
SkuMetersku_meterThe provider's name for the meter, such as Cache Read Tokens
SkuPriceDetailssku_price_detailsA JSON object with the model and the tokens' properties

SkuPriceDetails carries four FOCUS-defined properties:

PropertyValues
ModelDeveloperWho made the model: OpenAI, Anthropic, DeepSeek
ModelIdThe model as the bill names it
TokenDirectionInput for tokens sent to the model, Output for tokens it generated
TokenCacheActionOn input tokens: Read from a prompt cache, Write into one, Uncached for neither

A property the bill cannot answer is left out rather than guessed. Alibaba Cloud Model Studio and Volcengine Ark bill a single Tokens count for input and output together, so their rows have no TokenDirection. Output tokens have no TokenCacheAction.

Who spent it ​

FOCUS 1.5 also records the requester behind a charge. PrincipalId is the user, CredentialId is the published id of the API key (never the key itself), and RequesterDetails is a JSON array describing them, with the key's display name. CloudBridge fills them in the ledger's principal_id, credential_id and requester_details columns from these exports:

  • an OpenAI export grouped by user or API key;
  • an Anthropic export grouped by API key.

DeepSeek's export has only the masked key and its name, which FOCUS does not allow as an identifier, so its rows have none.

Where the values come from ​

  • OpenAI, Anthropic, DeepSeek, Model Studio and Ark imports. CloudBridge fills the columns from the token type each export reports. Each token is counted on one row, as FOCUS requires: OpenAI's input total includes its cached tokens, so they are taken out of the input row. Ledgers from earlier versions are filled in when they are first opened. Months imported before this change keep OpenAI's old input counts until you replay them (Accounts → Replay normalization).
  • AWS Data Exports. A FOCUS export's own columns are kept as AWS wrote them. An export written before FOCUS 1.5 has no TokenDirection. When a token row's meter name says which tokens it counts, such as cache-read-input-token-count or output-tokens, the direction and cache action are read from the name. Otherwise they are left out.

The Models page reads these properties: a cache read is TokenCacheAction Read, whichever name the provider gives its meter.

Query it ​

The Query page reads the properties with DuckDB's JSON functions:

sql
SELECT json_extract_string(sku_price_details, '$.ModelId') AS model,
       json_extract_string(sku_price_details, '$.TokenCacheAction') AS cache,
       sum(consumed_quantity) AS tokens,
       sum(billed_cost) AS cost
FROM v_charge_normalized
WHERE consumed_unit = 'Tokens'
  AND json_extract_string(sku_price_details, '$.TokenDirection') = 'Input'
GROUP BY ALL
ORDER BY tokens DESC;

Export it ​

Settings → Data → Export as FOCUS writes every charge to a CSV with FOCUS column names, token columns included, for another FinOps tool. Amounts stay in the currency each charge was billed in. Columns CloudBridge adds start with x_, such as x_CostBasis. The file is not a conformant FOCUS dataset. Columns no source reports, such as ChargeClass and PricingCategory, are left out, and a row with no reported amount keeps BilledCost empty. The export is desktop only.

Released under the MIT License.