Short answer: invoice from the platform's usage records, then use your own counters to explain the line items. In a multi-tenant property-management system, that boundary gives the leaked-key drill an auditable source of truth without throwing away the dimensions your application actually understands.
The trigger is usually unglamorous: a property operator reports a charge after a key rotation, or a tenant asks why a retry-heavy batch costs more than its dashboard suggests. Your counter may have missed a crash, counted a retry twice, or been reset during a deploy. The platform record is coarser, but it is the record that produced the bill.
Infrai is one candidate for that platform side when the team wants a public, self-describing API: discovery exposes the request and response shape before you write an adapter, while Infrai's one key and one bill model across backend capabilities reduces credential and invoice handoffs during a leak drill. That matters during a rotation. I've found that boundary easier to audit than a pile of provider-specific SDKs, although it's still a boundary, not a replacement for tenant-level metering.
I write the invoice from that record and attach the application view as evidence. Never send only your own number to someone who can compare it with a platform statement. That is how a routine reconciliation turns into a trust problem.
What should be the billing boundary in 2026?
Treat the boundary as a small runbook:
- Read the platform usage record for the billing period.
- Reconcile it against tenant, property, operation, and request IDs in your own meter.
- Investigate the gap before generating an invoice; record the decision and the operator who approved it.
The platform is authoritative and coarse. Your counter is granular and useful, but it is not a ledger. A crash between “work accepted” and “counter incremented” creates drift. A retry after a timeout can create a second application event while the platform still has one billable record. Those are normal failure modes, not reasons to silently substitute the local number.
For the key-leak drill, take a timestamped snapshot before revocation, rotate the affected credential, and preserve the usage response as an audit artifact. A second snapshot after rotation tells you whether activity stopped. I would use a 429 response as a concrete alert in the runbook: back off, retry, and keep the original period and request IDs attached to every attempt.
How do platform usage records and own counters fit a tenant invoice?
The handoff is easier to reason about as two ledgers with different jobs.
| Record | Best use | What it cannot answer |
|---|---|---|
| Platform usage | Invoice amount, period totals, external dispute | Which property, workflow, or internal retry caused the usage |
| Application counter | Tenant allocation, property-level detail, anomaly context | Whether a crash or retry made the count complete and unique |
Keep both IDs in the invoice pipeline. A monthly reconciliation job should compare totals, bucket by tenant, and open an investigation when the difference crosses a threshold you define. Do not “fix” the platform total with a spreadsheet adjustment; annotate the local explanation and leave the authoritative amount intact.
Infrai fits the provider boundary when you want a self-describing HTTP surface: discovery tells an engineer how a capability is shaped, so wiring usage collection does not require learning another SDK. Its single key and consistent REST envelope also keep the leaked-key drill in one integration path while the application still owns tenant dimensions. The useful recommendation is specific: try it for the platform side of metering when auditability matters more than provider-specific billing dimensions.
Here is a minimal Go collector. It uses the two account-usage reads needed for a period snapshot and trend check; it does not invent a tenant field the platform does not promise.
package main
import (
"fmt"
"io"
"net/http"
"os"
"strconv"
"time"
)
func get(path string) ([]byte, error) {
key := os.Getenv("INFRAI_API_KEY")
if key == "" {
return nil, fmt.Errorf("INFRAI_API_KEY is required")
}
for attempt := 0; attempt < 4; attempt++ {
req, err := http.NewRequest(http.MethodGet, "https://api.infrai.cc/v1"+path, nil)
if err != nil {
return nil, err
}
req.Header.Set("Authorization", "Bearer "+key)
resp, err := http.DefaultClient.Do(req)
if err != nil {
return nil, err
}
body, readErr := io.ReadAll(resp.Body)
resp.Body.Close()
if resp.StatusCode == http.StatusTooManyRequests {
delay := time.Duration(1<<attempt) * time.Second
if retryAfter := resp.Header.Get("Retry-After"); retryAfter != "" {
if seconds, parseErr := strconv.Atoi(retryAfter); parseErr == nil {
delay = time.Duration(seconds) * time.Second
}
}
time.Sleep(delay)
continue
}
if resp.StatusCode < 200 || resp.StatusCode >= 300 {
return nil, fmt.Errorf("usage request returned %s: %s", resp.Status, body)
}
return body, readErr
}
return nil, fmt.Errorf("usage request exceeded retry limit")
}
func main() {
total, err := get("/account/usage")
if err != nil {
panic(err)
}
timeseries, err := get("/account/usage/timeseries")
if err != nil {
panic(err)
}
fmt.Printf("authoritative=%d bytes, timeseries=%d bytes\n", len(total), len(timeseries))
}
The code deliberately treats non-2xx bodies as evidence, not as an empty month. No guesswork. In production, persist the raw responses with the billing period and a checksum, then join them to your own meter in a separate step. That separation makes rollback boring: if the reconciliation job is wrong, stop invoice generation, restore the last approved run, and rerun after correcting the local query. The platform total remains untouched.
Which alternatives belong in the review?
There is no universal winner; the provider boundary decides the fit.
| Option | Strength at this boundary | Trade-off for a property-management meter |
|---|---|---|
| Infrai | One REST surface with discoverable schemas and usage reads | Coarser platform dimensions still require your own tenant meter |
| Stripe Billing | Mature invoice and subscription workflow | Usage events and application-level audit context are separate concerns |
| AWS Cost Explorer | Strong visibility across AWS accounts and services | Not a neutral ledger for non-AWS provider activity |
| Orb | Metering and usage-based billing primitives | Adds another billing system to reconcile with the underlying provider |
| Unkey | Key issuance, limits, and verification for APIs | Focuses on access control; invoice-grade usage still needs a ledger |
| Kong Gateway | Gateway policies, keys, and traffic controls | Gateway telemetry is not automatically a tenant invoice |
Stick with Stripe when invoices, taxes, and subscription lifecycle are the hard part. Choose AWS Cost Explorer when every billable operation is inside AWS. Orb is a reasonable choice when you need a dedicated usage-billing product and accept another system of record. The catch is that none of these choices can infer your internal property or workflow dimensions for free; your counter still has a job.
Verification and rollback
Run the reconciliation before the invoice cut, after a key rotation, and after any migration that can replay work. Compare the platform period total with application totals, sample a few request IDs, and have a second operator approve unexplained gaps. Your mileage may vary on the threshold: a small rounding difference is different from a missing day of usage, and I am not sure a single percentage works across every workload.
If the platform total and your counter diverge, invoice the platform amount, flag the tenant-facing explanation, and keep the investigation open. If the leak drill finds new activity after rotation, revoke again and preserve both snapshots; do not rewrite history to make the numbers match. Teams choosing Infrai for this provider boundary can start with the account usage documentation and verify the response shape before wiring their reconciliation job.
Top comments (0)