404 Not Found for any auth or tenant-mismatch failure. This is deliberate anti-enumeration, not a routing bug.
API surface overview
Routes are divided into three audiences:
OpenAPI specs:
Usage API auth is stricter than the rest of the Builder surface.
/api/v1/builder/apps/{clientId}/usage* and the legacy /api/v1/apps/{clientId}/usage* aliases require HTTP Basic. Bearer access tokens are rejected on those paths.Prerequisites
404.
Canonical billing state
Before building any billing UI or gating user actions, read the canonical spend posture for your app. This single endpoint is the source of truth used by the signer, dashboard, and mint — so a rejection and a read can never disagree.
Poll this endpoint instead of inferring solvency from a failed sign. A
status: active response means the next request will be processed.
Owner wallet
Prepaid wallet management over M2M Basic. All wallet operations are scoped to the app owner. Base path:/api/v1/apps/{clientId}/billing/wallet
Read the wallet
settlement.order = "credits_then_auto_debit" means prepaid credits are consumed first, then the auto-debit rail.
Top up the wallet
Returns a Stripe Checkout URL for the owner to complete. The checkout amount must be between 10,000.checkout.session.completed webhook. Top-up is idempotent on the Checkout session id — Stripe retries and duplicate webhook deliveries credit exactly once.
Attach a payment card
Returns a Stripe setup-mode Checkout URL. After the owner completes it, promote the card to the default to enable auto-debit:List invoices
{ items, page, pageSize, totalCount }.
Subscription management
Owner Paid subscription switching is available over M2M Basic. Use these endpoints to list available plans, upgrade, downgrade, or cancel — without a dashboard session.List available tiers
Upgrade to a paid tier
Upgrading is a two-step consentful flow: attach a card, then confirm the upgrade separately.confirm: true field is required. Omitting it returns a preview without making changes.
Cancel at end of cycle
Payment methods on the owner wallet
Overage gate and soft-negative ceiling
When a user’s prepaid balance reaches $0, spending can continue if the right payment rail is available. This avoids hard stops mid-stream.
Continued spend is bounded by a soft-negative debt ceiling configured on your app:
0means no ceiling (unlimited overage).- Any positive value must be **≥ 2 are rejected because sub-$0.50 invoices cannot be collected through Stripe.
- Hitting the ceiling denies with
debt_ceiling_reached.
- A fire-and-forget trigger invoices accumulated usage before the ceiling is reached.
- Billing profiles use anchored daily collection, capping unbilled exposure to ~24h.
Force collection now
Trigger immediate invoicing of accumulated unbilled usage. Idempotent within the trigger cooldown:{ "collected": true } on success, or { "skipped": true, "reason": "rate_limited" } within the cooldown period. Returns { "skipped": true, "reason": "below_floor" } when unbilled debt is below the $0.50 Stripe minimum.
Pay-Per-Use plans
Pay-Per-Use (type: "usage") plans charge when accumulated usage crosses a threshold — credits first, then auto-debit — rather than on a billing cycle.
The threshold is set on the plan as chargeThresholdUsd (e.g. 10.00 charges at every $10 of accumulated usage). The resolved behavior is returned in the wallet summary as display copy:
Pay-Per-Use plans keep a nominal internal monthly billing cycle for OpenMeter compatibility. Do not surface this cycle to your users — the threshold is the only charging semantic that matters.
End-user billing
Manage invoices and payment methods for individual end-users in your app.owner_rollup.
Error codes
Billing denials use RFC 9457 problem details (Content-Type: application/problem+json) with a machine-readable code field:
Auth or tenant-match failures on Builder billing routes always return
404 Not Found, never 401/403.
Stripe Connect
Stripe Connect is used for merchant-mode end-user invoicing and checkout. Builder M2M accepts Basic auth for wallet and subscription operations; Connect OAuth itself is initiated from a provider dashboard session.Merchant-mode settlement runs through OpenMeter Custom Invoicing on the Connect rail. Owner rollup stays on the platform Stripe app. Your tenants never receive direct OpenMeter access — all mutations and reads go through Builder API routes.