Repository navigation
feat(pricing): Convert usage into each ServicePricing's pricing unit - #29
Merged
Merged
Conversation
Offers price memory per GiB-second and egress per GB, but meters count bytes, and the plan sent the per-GiB rate unchanged, so OpenMeter charged it per byte (Datum's staging bill for the period is $1.97B). A ServicePricing's unitConversion (billing v0.4.2) becomes the rate card's unit_config: OpenMeter divides the usage by the factor before pricing, so rates and tier bounds stay as the Offer states them and invoices read "50 x $0.01" per GiB-second. OpenMeter's v1 API cannot carry unit_config (it hides such plans from listings and refuses to read, change or migrate to them), so plans are written and read through v3, and a subscription moving onto a converting plan changes through v3. v3 never returns plan labels, so the spec hash lives in the plan description. UsageQuery spend reads the plan's rate cards from v3 and rates with the conversion. Dev OpenMeter enables unitConfig; the invoice e2e bills a byte-seconds meter per GiB-second. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
mattdjenkinson
approved these changes
Oct 19, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
Offers price memory per GiB-second and egress per GB, but the meters count bytes. The provider sent the per-GiB rate unchanged, so OpenMeter charged it per byte: Datum's staging bill for the current period is about $1.97B. Invoices go to Stripe on Nov 10.
How
unitConversion(feat(pricing): Convert usage into the pricing unit billing#124, billing v0.4.2) becomes the rate card'sunit_config. OpenMeter divides the usage by the factor before pricing, so rates and tier limits stay as the Offer states them, and invoices read50 x $0.01per GiB-second instead of byte counts times a per-byte price.unit_config: it hides such plans from listings and refuses to read, change or migrate to them. A subscription moving onto a converting plan uses v3 change. Everything else stays on v1. There's no v3 Go client, sointernal/openmeter/v3.gois a small HTTP helper using OpenMeter's generated v3 types.unitConfig. Staging gets the same setting from this bundle, so no infra change is needed.Rollout notes
payg-3on staging) gets one new version, because v3 can't read the old hash. Subscriptions migrate once and the current period splits, with the same rates and nothing billed twice./). It's tracing only; nothing reads it.unitConversionand they move to a new Offer (migrateFromOffer).Tests
invoice(green): adds a byte-seconds meter priced per GiB-second. 53,687,091,200 byte-seconds must bill 50 at $0.01. Every line's billed quantity, unit price and Stripe line are checked against the Offer. Total $3.40.offer(green): its checks now read the rate card description and the plan's hash.🤖 Generated with Claude Code