AI API Billing Reconciliation: Match Every Job to Its Final Charge
Reconcile AI API billing by linking jobs, retries, and final charges. Use an 18-record audio example to check totals, rounding, and unresolved costs.
A successful AI response tells you that an output was returned. It does not, by itself, tell you the final cost of delivering that output. A customer action may create several attempts; an asynchronous job may finish before its billing record settles; and a dashboard total may cover a different time window from your application report.
Quick answer: reconcile AI API billing by linking each application job to every provider attempt, matching those attempts to recorded charges, and separating settled amounts from unresolved records. Compare totals only after aligning currency, account scope, and time boundaries. Missing charge data is an unknown amount, not a zero-dollar result.
This guide includes a worked reconciliation subtotal using 18 tester-reported Sonilo charges from our earlier audio pilots. The amounts were supplied by the tester in USD. We verify the arithmetic here; we have not matched those samples to an authenticated request-level billing export or invoice.
1. Keep estimates, usage, and charges in separate fields
An estimate is a forecast based on expected inputs and a price assumption. Usage describes the metered work, such as input tokens, output tokens, or generated seconds. A recorded charge is the amount assigned to that work under the applicable billing rule. They answer different questions and should not overwrite each other.
Record
Useful for
Does not establish
Pre-request estimate
Budget approval before generation
The eventual settled amount
Response usage
Understanding metered work
Every pricing component or adjustment
Request-level charge
Assigning recorded cost to an attempt
A complete monthly invoice total
Customer acceptance
Calculating cost per usable output
Whether the provider billed the attempt
Token360’s Billing and Usage documentation distinguishes estimates from final charges, directs readers to the selected model’s pricing rules, and notes that asynchronous billing can finalize after a resource reaches a terminal state. Preserve that distinction in your own records.
For example, “HTTP 200, 18 total tokens” is useful execution evidence but still leaves the charge unknown if no amount is recorded. Do not substitute a public list price from a different provider route and label the result an observed cost. A reconstructed estimate can be useful, provided it remains labeled as an estimate.
2. Link one application job to every attempt
Create an application job identifier before submission. Give each outbound attempt its own local identifier, then attach the provider identifiers returned for that attempt. One user click can produce an original attempt, a retry after a timeout, and a fallback to another model. Keeping only the final successful response can hide the earlier work.
The following is a proposed application ledger, not a Token360 response schema. Adapt its fields to the actual metadata your endpoint returns.
Application field
Purpose
job_id / attempt_id
Connect the user-visible task to each outbound operation.
request_id / resource_id
Preserve returned identifiers with their original field names.
model_id / settings
Identify the requested route and relevant billing options.
submitted_at_utc / completed_at_utc
Define execution timing without substituting settlement timing.
execution_status / billing_status
Track completion and charge availability independently.
charge / currency / evidence_source
Store an amount together with its unit and provenance.
last_checked_at / owner
Make unresolved records actionable.
Keep the charge nullable. A confirmed zero is a value supported by a billing record; null means the amount is not yet known. Store money as exact decimal values at the precision supplied, rather than binary floating-point approximations.
Token360’s observability guidance identifies request, trace, and asynchronous resource identifiers as useful correlation data. Do not assume that every identifier is interchangeable. Preserve its type and verify which one the billing lookup accepts for the relevant operation.
Illustrative application data model. Two attempts do not automatically mean two charges.
3. Check settlement separately from execution
Use the documented request-level lookup, GET /v1/billing/requests/{request_id}, to inspect whether billing is recorded and which usage and charge components are available. The billing documentation also describes account-level summaries through GET /v1/billing. Confirm the current API reference for authentication, identifier format, filters, and response fields before implementing an adapter; the ledger names above are not promised API fields.
A useful application state model is: awaiting reconciliation, amount recorded, discrepancy under review, and closed. These are your operational labels. An application job may be complete while its reconciliation record is still open.
If no charge is available, retain the record and check again within a bounded schedule appropriate to the service. Do not poll indefinitely or invent a fixed settlement deadline. Escalate an aged unresolved record with its identifiers and timestamps. A missing record could reflect an incorrect identifier, permission scope, or unsettled billing; it is not evidence that the generation was free.
Repeatedly fetching the same billing record should update the matching ledger entry, not append another full charge. Likewise, distinguish a revised total from a separate adjustment before adding it. Deduplicate by the billing record’s documented identity and preserve enough history to explain a changed amount.
4. Worked example: reconcile 18 reported audio charges
Our earlier Sonilo pilots contained nine sound-effect generations and nine music generations. The tester reported the same charge within each group and confirmed USD. The sample names are local labels, not provider request IDs.
This establishes the sum of the supplied amounts. It does not establish an independently reconciled account debit, tax-inclusive invoice total, current price, or a general price comparison between sound effects and music. The workloads differ, and we have not supplied billing-record identifiers for these 18 samples.
The next reconciliation step is to attach the corresponding request records and compare the reported amounts with their recorded charges. If all 18 match, that closes this sample ledger at the request level. A monthly statement may still contain other activity or adjustments outside the sample’s scope.
Why rounding every row changes this subtotal
If an analyst first rounds each sound-effect charge to $0.02 and each music charge to $0.09, the summed display values become $0.99. Summing the supplied precision first gives $0.9545445, which displays as $0.95 at two decimals. The row-rounded sum is $0.0354555 higher than the unrounded subtotal; the two displayed totals differ by four cents.
This is a calculation artifact, not evidence of overbilling. Retain source precision in the ledger, apply the documented settlement rules when comparing financial records, and round separately for presentation. Do not force the provider’s ledger to match a locally rounded display.
Recomputed from tester-reported amounts; no invoice rounding policy is inferred.
5. Investigate differences in a fixed order
Start with scope before investigating arithmetic. Compare the same account or workspace, currency, model set, and UTC window. Decide whether your report groups by submission time, completion time, or billing time. A job crossing midnight can belong to different daily reports without either report being wrong.
Observed difference
Check first
Avoid concluding
Dashboard total exceeds application total
Other callers, retries, missing attempts, and window boundaries
Every difference is duplicate charging.
Completed output has no charge yet
Identifier mapping and settlement state
The output was free.
Two records look similar
Distinct attempt IDs versus duplicate imports
Matching prompts identify the same request.
Usage-based estimate differs from recorded cost
Route, units, pricing components, and effective rule
The estimate is the authoritative amount.
Sum differs by a small fraction
Source precision and rounding stage
A tiny variance can be silently discarded.
Keep disputed amounts visible instead of deleting them to make totals agree. Assign an owner and resolution note. If a request’s usage is revised or a credit appears later, preserve the original observation and the subsequent adjustment so the reconciliation can be reproduced.
Also keep wallet movement separate from consumption. A deposit changes available funds without being an inference charge. A balance snapshot alone is not a request ledger, especially when other activity occurs between snapshots.
6. Separate provider cost from customer billing
The cost of fulfilling one customer job may include several provider attempts. Whether you charge the customer for those attempts is your product’s pricing policy. A fixed-price product, a credit package, and a pass-through usage product can all allocate the same underlying cost differently.
Attach customer or project ownership before work is submitted, using identifiers that your application controls. An API key shared across customers is not enough to reconstruct customer ownership later. Avoid placing personal data or secrets in correlation fields.
The FinOps Foundation’s Allocation capability describes using account structures, tags, and metadata to assign costs to responsible teams or projects. Applied here, that means separating the evidence of a provider charge from the business rule that allocates it.
Define how you handle retries, quality failures, refunds, and shared overhead in the customer-facing policy. A technically successful output that fails a creative brief can still carry provider cost. Keep quality acceptance as a separate field; otherwise a “cost per accepted output” calculation can accidentally discard the expense of rejected attempts.
7. Close a report with an exception list
A useful reconciliation report states its scope, currency, time basis, source precision, recorded-charge subtotal, and unresolved-attempt count. Unknown amounts should remain unknown; do not add invented estimates to a settled total.
For the audio example, the honest closing statement is: “18 tester-reported charges sum to $0.9545445 USD; request-level verification is outstanding.” That is more informative than claiming a fully reconciled bill because the arithmetic balances.
Before closing an actual reporting period, check that every application attempt either has supporting billing evidence or a documented exception. Match the report to the corresponding account summary only after accounting for differences in scope and timing. Retain a compact evidence bundle with identifiers, timestamps, amounts, and resolution notes, excluding credentials.
FAQ
Can I calculate the final bill from token usage alone?
You can make an estimate if you know the applicable pricing rules. For reconciliation, use the recorded charge and available components. Usage alone may not capture every priced category, adjustment, or route-specific rule.
Does an API error mean the request costs nothing?
No universal conclusion follows from the error alone. Inspect the billing record for the attempt. A timeout also leaves uncertainty about remote execution; do not treat an absent response as proof of zero work.
Is a missing charge the same as a zero charge?
No. Store missing amounts as unresolved. Record zero only when supported by the relevant billing evidence, and retain the source that establishes it.
How should retries appear in the ledger?
Give each outbound attempt its own record linked to the original application job. Match charges individually, then calculate the job cost from those records. Deduplicate repeated imports of the same billing record.
Should I round each request to cents?
Preserve the precision supplied by the source. Round for display separately and follow the documented settlement policy when comparing invoices. In our 18-record example, rounding rows before summing changes the displayed total.
Does this example prove Token360’s billing is accurate?
No. It verifies arithmetic on tester-reported charges. A billing accuracy claim would require matching the underlying request records and applicable pricing evidence, which this article has not done.
Next step: choose a small completed batch, preserve every attempt, and use Token360’s billing documentation to connect those records to their charges before scaling your reporting workflow.
API
Billing
Cost Management
Build faster with one AI API.
Use Token360 to call video, image, audio, and text models with one key and one bill.