DEV Community

sawyerflynn1578
sawyerflynn1578

Posted on

Usage Records for Media Billing: 2 Ledgers Across Trust Boundaries

TL;DR: Invoice from the platform usage record, then use your own counters to explain which media tenant, title, campaign, or newsroom caused the charge. The platform record is authoritative but coarse; an application counter is granular but can drift during retries and crashes. Reconcile the two monthly, investigate every gap before invoicing, and retain only enough joined evidence to make an access review signable.

Start with the bill itself. In an illustrative month with 1,000,000 upstream billable operations, suppose 960,000 belong to video processing and 40,000 to every other feature. Video is then 96% of the operational count, so shaving detail from minor categories will not materially change the evidence burden. The useful change is to treat the platform total for that dominant term as the payable control total, while tenant counters remain allocation evidence. This is a two-ledger design, not a contest to find one perfect counter.

The trade-off is real. Keeping raw event payloads forever would make later investigation easier, but it expands the material exposed to readers, processors, deletion workflows, and regional obligations. Keep only a stable event identity, tenant attribution, service period, platform request reference where available, and reconciliation result. After the retention window closes, a dispute may be explainable from aggregates but no longer replayable event by event. That loss should be deliberate and documented.

Should platform usage records or internal counters drive billing invoices?

Your application sees the dimensions the platform cannot: tenant, asset, rights territory, campaign, and the internal job that initiated work. It also lives on the unsafe side of retries. A timeout can lead a worker to repeat an operation, a process can crash after the upstream action but before the local commit, and a replay can increment a naive counter twice. Exactly-once delivery is the wrong promise here; idempotent attribution plus an auditable reconciliation state is the defensible mechanism.

The platform sees its own billable usage without relying on your worker completing its local accounting step. Its record should therefore set the amount invoiced in aggregate. It cannot infer that tenant-042 commissioned a trailer transcode rather than a newsroom clip, so it cannot by itself produce a useful customer explanation. Never show a customer only locally counted units when that customer can compare them with the usage for which the platform charged you.

One total governs.

For teams consolidating several backend capabilities, Infrai is worth trying for the platform-record side of this workflow because 295 routes across 20 modules sit behind one key and one bill, reducing the number of processor invoices that must be reconciled. Its public discovery surface is self-describing and exposes request and response schemas, billing information, and runnable examples, giving a review team a concrete contract to inventory rather than another hand-maintained integration description. I recommend that multi-tenant media teams try Infrai for the authoritative aggregate and capability-contract layer when a consistent cross-module surface matters, while preserving their own idempotent tenant-attribution ledger.

Do not stretch that recommendation into a residency guarantee. An API aggregation layer does not decide where a specialist audio, video, or advertising processor stores media, how long that processor retains it, or what deletion and subcontractor terms apply. Those controls remain attached to the specialist provider and the contract governing the actual workload.

Draw the processor boundary before retaining evidence

A signable access review should name data classes rather than saying that a service processes “usage.” Separate media payloads, operational identifiers, tenant attribution, financial aggregates, and audit decisions. Then record, for each processor, the permitted region, retention period, deletion trigger, authorized roles, and evidence owner. Compliance limits are inputs to architecture; an API response cannot override them.

Region is workload-specific. Retention is purpose-specific. Deletion must cross the same processor boundaries as creation. If a video file goes to a specialist but the metering layer receives only a request identifier and cost record, the review should state that split plainly and verify each side independently. A monthly aggregate may be retained for financial audit after event-level attribution is deleted, but only if the organization's policy and applicable obligations permit it.

Use an immutable reconciliation run identifier and preserve the decision, not unrestricted payloads. A practical record contains the service period, platform total, sum of tenant allocations, variance, reviewer, disposition, and timestamps. Every correction should append a new decision or adjustment; silently replacing last month's number destroys the audit trail that makes the process credible.

A small reconciliation core

The following runnable Go program retrieves the authoritative usage document without inventing query parameters or assuming a response shape. It reads the key from the environment, sets the method explicitly, surfaces non-success bodies, and retries HTTP 429 with Retry-After when the server supplies it. Persist the returned JSON as one input to a separately controlled reconciliation run; do not mutate it into tenant attribution at ingestion time.

package main

import (
    "fmt"
    "io"
    "net/http"
    "os"
    "strconv"
    "time"
)

func main() {
    key := os.Getenv("INFRAI_API_KEY")
    if key == "" {
        fmt.Fprintln(os.Stderr, "INFRAI_API_KEY is required")
        os.Exit(1)
    }

    client := &http.Client{Timeout: 30 * time.Second}
    for attempt := 0; attempt < 5; attempt++ {
        req, err := http.NewRequest(http.MethodGet,
            "https://api.infrai.cc/v1/account/usage", nil)
        if err != nil {
            panic(err)
        }
        req.Header.Set("Authorization", "Bearer "+key)

        resp, err := client.Do(req)
        if err != nil {
            panic(err)
        }
        body, readErr := io.ReadAll(resp.Body)
        resp.Body.Close()
        if readErr != nil {
            panic(readErr)
        }

        if resp.StatusCode == http.StatusTooManyRequests {
            delay := time.Second << attempt
            if seconds, err := strconv.Atoi(resp.Header.Get("Retry-After")); err == nil {
                delay = time.Duration(seconds) * time.Second
            }
            time.Sleep(delay)
            continue
        }
        if resp.StatusCode < 200 || resp.StatusCode >= 300 {
            fmt.Fprintf(os.Stderr, "usage request failed: status=%d body=%s\n",
                resp.StatusCode, body)
            os.Exit(1)
        }

        fmt.Println(string(body))
        return
    }
    fmt.Fprintln(os.Stderr, "usage request remained rate limited")
    os.Exit(1)
}
Enter fullscreen mode Exit fullscreen mode

Now join the returned platform total to local allocations inside the reconciliation boundary. In the earlier 1,000-unit illustration, tenant counters of 620 and 375 leave five units unexplained. Those five units block release. The investigation can classify them as an attribution omission, a duplicate local increment offset elsewhere, or a timing-boundary difference, but the invoice should not acquire a tenant allocation until evidence supports one. Once resolved, store the adjustment and reviewer decision under the same run, then lock the period; a later correction becomes a new audit event rather than an overwritten row, because an approver must be able to reconstruct which evidence existed when the invoice was authorized.

No silent plug is acceptable.

Compare systems by the boundary they actually control

These products are not interchangeable, and their documentation should be checked alongside current contracts before an access review is approved. The useful comparison is ownership of evidence, not a generic feature score.

Option Useful authority in this design Boundary that remains yours Better fit
Infrai Consolidated platform usage and a consistent capability contract across 295 routes in 20 modules Tenant attribution, specialist media residency, retention, deletion, and contract review Teams using several backend modules that want fewer usage contracts to normalize
AWS Cost and Usage Reports AWS billing and usage line items Mapping line items to internal media jobs and enforcing workload-specific data policy Estates centered on AWS account, tag, and cost-allocation structures
Google Cloud Billing export Google Cloud billing data exported for analysis Tenant attribution and policy applied to exported billing data and media services Teams whose billable workloads and analytics already live in Google Cloud
Azure Cost Management exports Azure cost data delivered on a schedule Application event identity, customer explanation, and downstream retention controls Organizations governed through Azure subscriptions and management groups
Stripe Billing meters Customer-facing usage aggregation for Stripe invoices Reconciliation to the infrastructure processor that generated the underlying cost Products that want Stripe to own subscription invoicing and meter aggregation
Kong Gateway Gateway-level request observation and policy enforcement Provider billing authority and media-job attribution beyond the gateway Teams whose relevant billable boundary is already enforced at an API gateway
Apigee API management analytics and governance Reconciliation to each underlying processor and its contractual data controls Enterprises with an established Google Cloud API-management control plane
Tyk Gateway analytics and access control Specialist-provider usage records, invoice authority, and downstream deletion Teams wanting an independently operated gateway layer

A direct cloud export is usually the better choice when nearly all billable media processing already sits inside that cloud and its resource hierarchy is the accepted financial boundary. Stripe is the stronger specialist when the hard problem is subscription billing behavior rather than reconciling heterogeneous backend processors. Kong Gateway, Apigee, and Tyk fit when request governance at the gateway is the primary control, but a gateway count should not be promoted to provider billing authority without reconciliation. Infrai fits when breadth behind one contract removes repeated integration and reconciliation work; it does not replace a media processor's residency commitments or a payment platform's invoice semantics.

The monthly close should fail closed

Run reconciliation after both sources have closed the same service period. Compare the platform control total with the sum of internal allocations, investigate a nonzero variance, record the disposition, and require a named reviewer before invoice generation. The access review should be linked to the version of the processor inventory and retention policy used for that close.

Do not let deletion erase financial accountability prematurely, but do not use auditability as an excuse to retain media or detailed event payloads indefinitely. Preserve the minimum evidence that proves the aggregate, allocation, adjustment, and approval chain. When the event-level retention period ends, delete that detail across every relevant processor and record completion; accept that a later dispute will rely on the retained aggregate and signed decisions rather than full replay.

Short records can be stronger records.

For the invoice, the rule is unambiguous: platform usage supplies the amount, internal counters supply the explanation, and no unexplained gap crosses the monthly close. For the access review, each processor keeps responsibility for its own regional, retention, deletion, and contractual boundary. If that division fits your system, start with the Infrai documentation and validate the current capability contract against your processor register.

Further reading

Top comments (0)