Skip to main content
The Builder M2M Payments API gives your backend full programmatic control over billing — the same operations available in the PymtHouse dashboard, accessible via M2M HTTP Basic auth. Use it to embed prepaid top-up flows, subscription upgrades, and billing dashboards directly in your product. All billing and usage Builder routes return 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

The M2M credential must be the app’s configured M2M OIDC client. Anything else returns 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.
Response:
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

Response includes:
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 1and1 and 10,000.
Credits land in the wallet when Stripe fires the 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:
Attaching a card is not the same as enabling auto-debit. After a setup Checkout completes, you must explicitly set the card as default with PATCH { ensureDefault: true } before it will be used for overage collection or subscription charges.

List invoices

Returns { 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.
The confirm: true field is required. Omitting it returns a preview without making changes.

Cancel at end of cycle

Schedules a downgrade to Sandbox Starter at the end of the current billing cycle. To revert before the cycle ends:

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:
  • 0 means no ceiling (unlimited overage).
  • Any positive value must be **≥ 2.Valuesbelow2**. Values below 2 are rejected because sub-$0.50 invoices cannot be collected through Stripe.
  • Hitting the ceiling denies with debt_ceiling_reached.
Collection is invoice-based (never a PaymentIntent from PymtHouse):
  • 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:
Returns { "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.
See Plans for creating and configuring Pay-Per-Use plans.

End-user billing

Manage invoices and payment methods for individual end-users in your app.
Free, Starter, and draft plan targets are never revenue-gated. Migrating users off a phased-out paid plan continues working after switching to 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.

Full example: embed a billing dashboard

For the aggregate billing summary (cycle totals, timeline, overage), see Billing summary.