OpenAI Usage API api_key_id: Reconcile Tokens and Costs by Key
OpenAI Usage API api_key_id grouping solves a practical reporting gap: I can see which API key produced completion-token activity and which key accumulated cost. The tricky part is not making the two requests. It is joining their daily buckets without dropping unattributed or unmatched data. I want a reconciliation report to expose gaps, not smooth them over. A missing cost row, a cost-only row, or a null key ID can each be useful evidence. This pattern keeps those cases visible with a deterministic .NET sample that needs no credentials or paid calls. Why OpenAI Usage API api_key_id needs a full-outer join OpenAI's August 4, 2026 API changelog added API-key filtering and grouping to the usage and cost APIs. That gives both responses a shared operational dimension, but it does not make them identical datasets. The completions usage endpoint reports measures such as input tokens, output tokens, and model requests. Its api_key_id can be null. The costs endpoint returns monetary amounts and currency, also with a nullable API-key dimension. An inner join would retain only rows present in both responses. That is attractive for a tidy chart, but unsafe for reconciliation. It can hide a key that has token usage but no matching cost row, a key with cost but no completion row, or an unattributed bucket. I use a full-outer join keyed by (start_time, end_time, api_key_id) instead. Null or blank IDs become an explicit display value such as <unattributed> ; they do not disappear. Query both APIs at the same daily grain The Costs API supports daily buckets, so I request bucket_width=1d from both endpoints. I also group by the same single dimension: GET /v1/organization/usage/completions ?start_time=... &end_time=... &bucket_width=1d &group_by=api_key_id GET /v1/organization/costs ?start_time=... &end_time=... &bucket_width=1d &group_by=api_key_id Both resources paginate with has_more and next_page . I keep requesting pages until has_more is false. If a response says more data exis