Δημιουργήστε μια αναφορά χρήσης τεχνητής νοημοσύνης που αντιμετωπίζει πελάτες API για μεταπωλητές και ενοικιαστές SaaS
Ένας πρακτικός οδηγός για το σχεδιασμό μιας αναφοράς χρήσης τεχνητής νοημοσύνης API API που μπορούν να εμπιστεύονται οι μεταγενέστεροι πελάτες: διαστάσεις με εμβέλεια ενοικιαστή, προσωρινό και τελικό κόστος, σελιδοποίηση δρομέα, προσαρμογές, εναρμόνιση και έλεγχος πρόσβασης με ασφάλεια ως προς το απόρρητο.
Your internal gateway ledger is not the same thing as a customer-facing reporting API. A ledger proves what happened inside your platform. A customer report explains what a tenant, client, workspace, or end customer can safely see, query, reconcile, and use before invoice time.
That distinction matters for resellers, agencies, embedded AI products, and SaaS teams that expose AI usage to their own customers. Customers do not only ask, “How much did I spend?” They ask which key, model, endpoint, workflow, user cohort, or time bucket caused the spend; whether the number is final; why the invoice differs from yesterday’s dashboard; and whether prompts or provider credentials are exposed in the process.
The practical answer is to publish a stable AI API usage reporting API backed by immutable usage events, versioned pricing, scoped access tokens, and reconciliation endpoints. The API should be boring, explicit, and hard to misinterpret.
Define the Reporting Contract Before the Data Model
Start with the customer problem, not the storage schema. A reporting API should answer four questions:
- What did this tenant use?
- What did it cost under the customer-visible pricing rules?
- Is the number estimated, adjusted, or final?
- How does it connect to invoices, credits, top-ups, or partner margin?
This is different from an internal operations dashboard. Internal systems may expose provider request IDs, routing decisions, raw error payloads, retry state, or credential pool names. A customer-facing API should expose only the fields needed for attribution, cost explanation, audit, and product analytics.
Fact: AI providers and billing systems expose usage and cost data with different field names, grouping options, and aggregation behavior. Some usage APIs group by dimensions such as model, workspace, key, or service tier; other surfaces vary by endpoint type. A gateway should normalize this before publishing customer reports.
Recommendation: Treat the reporting API as a product contract. Version it from the first release, even if the first version has only a few endpoints.
Use Tenant-Scoped Dimensions
The reporting API should make tenant boundaries impossible to bypass. Every query must resolve to an authorized tenant scope before it touches usage data.
Useful dimensions include:
customer_id: the downstream customer or tenant.project_id: an app, environment, team, or workspace inside the customer.api_key_id: the gateway-issued key, never the upstream provider key.model_alias: the customer-visible model name or profile.provider: optional, and only if exposing provider choice is part of the contract.endpoint_family: chat, responses, embeddings, images, audio, batch, realtime, tools, or another stable category.workflow_tag: a customer-supplied tag such as support-bot, invoice-parser, coding-agent, or qa-eval.user_hash: a pseudonymous end-user identifier for attribution without exposing personal data by default.time_bucket: hourly, daily, monthly, or custom interval boundaries.
For resellers and agencies, this reporting contract belongs near the partner provisioning surface. If customers and keys are created through Partner API automation, usage reporting should use the same customer and key identifiers rather than inventing a second naming system.
Expose Usage Units and Money Fields Separately
A good report separates physical usage from pricing. Tokens, tool calls, images, audio seconds, and batch jobs are not money. Money is calculated from usage, pricing rules, discounts, credits, margin, and adjustments.
At minimum, each aggregate row should include fields like:
{
"bucket_start": "2026-09-01T00:00:00Z",
"bucket_end": "2026-09-02T00:00:00Z",
"customer_id": "cus_123",
"project_id": "proj_support",
"api_key_id": "key_789",
"model_alias": "support-fast",
"endpoint_family": "chat",
"request_count": 18420,
"input_tokens": 9821000,
"cached_input_tokens": 2410000,
"output_tokens": 1268000,
"reasoning_tokens": 310000,
"tool_calls": 860,
"estimated_cost": "142.36",
"settled_cost": "141.91",
"currency": "USD",
"pricing_catalog_version": "2026-09-01",
"invoice_status": "pending"
}
Do not hide token categories just because the invoice is denominated in money. Customers need unit fields to debug behavior. Cached input tokens, reasoning tokens, hosted tool charges, and media units often explain why two similar workflows cost different amounts.
Recommendation: Store decimal money as strings in API responses. Avoid floating-point values for cost fields. Use a currency field on every row instead of assuming one global currency.
Separate Provisional, Adjusted, and Final Usage
Customer-facing AI reports often fail because they pretend every number is final immediately. In practice, usage can change after the first request completes.
Common causes include:
- Streaming responses where the client disconnects before the provider returns final usage.
- Provider-delayed usage for batch, media, or hosted tools.
- Retries where an application sees one logical request but the gateway sees multiple billable attempts.
- Refunds, credits, pricing corrections, or fraud reversals.
- Model alias changes where customer-visible names differ from upstream model IDs.
Do not silently overwrite rows in a way that makes yesterday’s API response impossible to explain. Instead, publish a state model:
provisional: calculated from gateway estimates or partial provider data.settled: calculated from normalized provider usage and the active pricing catalog.adjusted: changed by a later correction, credit, refund, or reconciliation event.invoiced: included in a customer-visible invoice or statement.
Raw usage events should be immutable. Corrections should appear as adjustment rows linked to the original event or aggregate period.
{
"adjustment_id": "adj_456",
"original_event_id": "evt_abc",
"customer_id": "cus_123",
"reason": "provider_usage_correction",
"cost_delta": "-0.45",
"currency": "USD",
"created_at": "2026-09-03T10:15:00Z"
}
Trade-off: Near-real-time reporting is better for budget alerts and customer trust, but it requires visible provisional states. Finalized-only reporting is easier to reconcile, but it is much less useful when customers are trying to stop overspend before the invoice arrives.
Provide Aggregates and Raw Event Access
One endpoint cannot serve every use case. Dashboards need cheap aggregates. Finance teams and enterprise customers may need row-level evidence.
A practical reporting API usually has at least three endpoint families:
GET /v1/usage/summary
GET /v1/usage/events
GET /v1/usage/reconciliation
Summary Endpoint
The summary endpoint should return pre-aggregated usage by a small set of dimensions and time buckets.
GET /v1/usage/summary?customer_id=cus_123&from=2026-09-01T00:00:00Z&to=2026-09-08T00:00:00Z&bucket=day&group_by=model_alias,api_key_id
Use it for dashboards, budget pages, and customer-facing cost breakdowns. It should be fast enough to call repeatedly without scanning the raw event table. If the product includes an AI API usage analytics dashboard, this endpoint is usually the backend contract that keeps the UI consistent with exported reports.
Events Endpoint
The events endpoint should expose immutable usage records with cursor pagination. Use it for audit-heavy customers, support investigations, and warehouse exports.
GET /v1/usage/events?customer_id=cus_123&from=2026-09-01T00:00:00Z&limit=500&cursor=eyJpZCI6...
Each row should include a stable event_id, timestamps, request family, model alias, key ID, normalized usage units, cost fields, and status. It should not include raw prompts or completions by default.
Reconciliation Endpoint
The reconciliation endpoint connects usage to customer-visible billing objects.
GET /v1/usage/reconciliation?customer_id=cus_123&invoice_id=inv_2026_09
Return invoice line items, usage totals, applied credits, top-ups, taxes if applicable, partner margin rules if customer-visible, and any adjustments made after the first estimate. This is where usage reporting becomes explainable billing rather than a pile of counters.
Recommendation: Keep invoices and usage reports related but not identical. A usage API explains consumption. An invoice explains payable amounts. They should reconcile through stable IDs, not collapse into one overloaded endpoint.
Use Cursor Pagination and Stable Ordering
Offset pagination is fragile for usage events because new records and late adjustments can arrive while a customer is paginating. Use cursor pagination with a stable sort.
A durable pattern is:
- Sort by
event_timeandevent_id. - Return
next_cursorwhen more records exist. - Make cursors opaque.
- Document whether late-arriving events can appear in already-read windows.
- Provide an
updated_sincefilter for reconciliation jobs.
For aggregate endpoints, customers may want repeatable reports. Support a finalized_before or report_version parameter so finance exports can be rerun consistently.
GET /v1/usage/summary?customer_id=cus_123&month=2026-09&status=finalized&report_version=2026-10-02
Prediction: Reporting schemas for AI usage will keep changing as providers add new token types, tool charges, service tiers, and media billing units. Versioned report contracts will age better than endpoints that expose whatever the current provider response happens to contain.
Version Pricing and Schema Together
Usage fields and pricing rules change independently. A model may gain cached-token pricing. A provider may introduce reasoning-token controls. A reseller may change margin rules for new customers while honoring old contracts.
Every cost row should include:
pricing_catalog_versionschema_versionrate_effective_atcurrencycost_basis: estimated, settled, adjusted, invoiced
This is especially important when the platform offers unified AI API billing across multiple model providers. A single bill is useful only if customers can understand how heterogeneous usage was normalized into consistent cost categories.
Fact: Open cost-and-usage schemas are evolving to cover AI, cloud, SaaS, data center, and other technology vendors. That supports a versioned approach rather than hard-coding one permanent export shape.
Design Access Control as Part of the API
Usage data is sensitive. It can reveal customer growth, product launches, failed automation, abuse incidents, or internal workflows. Access control should be part of the reporting design, not an afterthought.
Define roles explicitly:
customer_admin: can view all usage for their customer scope.project_admin: can view usage for assigned projects.billing_viewer: can view cost and invoice reconciliation but not user-level breakdowns.support_operator: can retrieve narrow slices for a support case, with audit logging.partner_operator: can view assigned tenants, not every tenant by default.
Use scoped tokens for machine access. A token that can query usage for cus_123 should not be able to change keys, modify pricing, or read another customer’s usage by guessing IDs.
Also decide which dimensions are privacy-sensitive. A user_hash field may be safe for some customers and too revealing for others. Workflow tags can leak business context if customers put names such as acquisition-target or legal-review into metadata. Document retention and redaction behavior clearly.
A Minimal Implementation Checklist
Use this sequence to avoid building a reporting API that looks complete but cannot reconcile.
- Create immutable usage events. Assign every billable event a stable ID, tenant scope, request family, model alias, normalized units, timestamps, and source status.
- Normalize provider usage into internal units. Keep raw provider payloads internally if needed, but expose stable customer fields.
- Apply a versioned pricing catalog. Store the catalog version used for every estimate, settlement, and adjustment.
- Materialize hourly and daily aggregates. Do not make dashboard queries scan raw events at customer scale.
- Add adjustment rows. Never hide corrections by mutating old cost totals without explanation.
- Build cursor-paginated event exports. Include opaque cursors, stable ordering, and updated-since filters.
- Build invoice reconciliation. Link usage rows to invoice lines, credits, top-ups, and margin rules.
- Enforce tenant-scoped authorization. Test for broken object-level authorization across every report endpoint.
- Publish schema versions. Give clients a way to request a stable report shape.
- Default to no raw prompt retention. Usage reporting should not require prompt or completion storage.
Common Trade-Offs
Aggregate-first or event-first: Aggregate-first APIs are safer and cheaper for most customers. Event exports are more powerful but create larger privacy, pagination, and support burdens. Offer aggregates first unless your buyers have audit requirements.
Expose provider names or hide them: Exposing upstream providers can help sophisticated customers analyze performance and cost. Hiding providers keeps the product abstraction cleaner. If routing is part of your value proposition, consider exposing provider as an optional dimension controlled by plan or role.
Real-time estimates or final reports: Real-time estimates help customers act before spend becomes a billing problem. Final reports are better for accounting. Most mature systems need both.
Strict finance schema or product-friendly schema: Finance-oriented schemas can reduce integration work, but they may be too heavy for a customer product API. A practical compromise is to use finance-inspired fields internally while publishing a simpler, versioned customer schema.
Actionable Conclusion
A customer-facing AI usage reporting API should not be a thin wrapper around provider billing responses or an internal admin table. It should be a stable contract that lets tenants understand usage before invoice time, drill into the right dimensions, distinguish provisional from final cost, and reconcile charges without exposing prompts or upstream credentials.
Build the first version around three endpoints: summaries, events, and reconciliation. Back them with immutable usage events, adjustment rows, versioned pricing, cursor pagination, and tenant-scoped access tokens. That foundation is enough to support dashboards, customer exports, reseller operations, and billing disputes without turning every invoice question into a manual support investigation.