OpenAI Usage API api_key_id: Reconcile Tokens and Costs by Key A developer has published a .NET sample that reconciles OpenAI's Usage and Costs APIs by API key, using a full-outer join to surface gaps such as missing cost rows or unattributed buckets. The approach ensures both endpoints are grouped by day and API key, and it rejects mismatched grains or pagination errors to keep the report deterministic. 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. api key id needs a full-outer join OpenAI's August 4, 2026 API changelog https://developers.openai.com/api/docs/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 https://developers.openai.com/api/reference/python/resources/admin/subresources/organization/subresources/usage/methods/completions reports measures such as input tokens, output tokens, and model requests. Its api key id can be null. The costs endpoint https://developers.openai.com/api/reference/python/resources/admin/subresources/organization/subresources/usage/methods/costs 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