$0.00, inbound
calls are rejected and outbound calls return 402 Payment Required.
These endpoints let you query balance state, top up via Stripe, and
configure automatic reloads.
Endpoints
| Method | Path | Description |
|---|---|---|
GET | /v1/billing | Get billing account state |
PATCH | /v1/billing | Update auto-reload settings |
POST | /v1/billing/top-up | Create a top-up payment intent (one-time charge) |
POST | /v1/billing/setup-intent | Create a Stripe SetupIntent for saving a card |
POST | /v1/billing/default-payment-method | Set the default payment method |
GET | /v1/billing/transactions | List balance transactions |
Billing account object
| Field | Type | Description |
|---|---|---|
balance_cents | integer | Current balance in USD cents |
balance_usd | string | Formatted, e.g. "1250.00" |
currency | string | Always usd |
auto_reload_enabled | boolean | Whether automatic top-ups are on |
auto_reload_minimum_cents | integer | Balance threshold that triggers a reload |
auto_reload_amount_cents | integer | Amount to charge on reload |
auto_reload_monthly_limit_cents | integer | null | Cap on auto-reload spend per calendar month. null = no cap |
has_payment_method | boolean | Derived — true iff a default Stripe payment method is set |
Get billing account
200 OK with a Billing account object.
Update auto-reload
Enable, disable, or reconfigure automatic balance reloads. A payment method must be on file (has_payment_method: true) before
auto_reload_enabled can be set to true — otherwise the server
returns 422 Unprocessable Entity with code: "payment_method_required".
| Field | Type | Required when enabling |
|---|---|---|
auto_reload_enabled | boolean | |
auto_reload_minimum_cents | integer ≥ 0 | yes — triggers a reload once balance drops below |
auto_reload_amount_cents | integer > 0 | yes — amount charged on reload |
auto_reload_monthly_limit_cents | integer ≥ 0, or null | no — null means unlimited |
200 OK with the updated Billing account object.
Top up balance
Create a one-time charge to increase your balance. Uses the default payment method unlesspayment_method_id is supplied.
| Field | Type | Required | Description |
|---|---|---|---|
amount_cents | integer ≥ 1 | yes | USD cents. Minimum typically $5 |
payment_method_id | string | no | Stripe PM id. Defaults to the org’s default |
201 Created:
| Field | Type | Description |
|---|---|---|
payment_intent_id | string | Stripe PaymentIntent id |
status | string | Mirrors Stripe’s own PaymentIntent.status — typically succeeded, requires_action, or requires_payment_method |
client_secret | string | Pass to Stripe.js / stripe-react on the client side if status === "requires_action" (3DS) |
status === "succeeded" the balance is credited synchronously
from the request. When status === "requires_action", complete the
3DS flow client-side and wait for the payment_intent.succeeded
webhook — then poll GET /v1/billing to
observe the credit.
Errors:
| Status | code | Condition |
|---|---|---|
400 | invalid_amount | amount_cents below minimum or above maximum |
402 | card_declined | Bank declined the card |
402 | authentication_required | 3DS required — response carries next_action: "confirm_payment" and a client_secret your front-end passes to Stripe.js |
502 | provider_unavailable | Stripe upstream failure; safe to retry |
Add / save a payment method
Two-step flow: create a SetupIntent, confirm it client-side, then set the resulting payment-method id as the org’s default.1. Create a SetupIntent
Response
2. Confirm client-side with Stripe.js
See the Stripe documentation forstripe.confirmCardSetup(). On success you receive a
payment_method id.
3. Mark the payment method as default
200 OK with the updated Billing account object;
has_payment_method is now true.
List transactions
Returns credits (top-ups), debits (per-call billing), and adjustments.Query parameters
| Param | Type | Default | Description |
|---|---|---|---|
limit | integer | 50 | 1–200 |
offset | integer | 0 | |
kind | string | credit, debit, adjustment, refund | |
start_date | ISO 8601 | Filter on created_at | |
end_date | ISO 8601 |
Transaction object
amount_cents is negative for debits and positive for credits.
Stripe webhook
ThunderPhone receives Stripe webhooks at/v1/stripe/webhook internally — you don’t interact with this endpoint
directly. It processes payment_intent.succeeded,
payment_intent.payment_failed, and setup_intent.succeeded events to
update balances and mark payment methods ready.
Related
Outbound Calls
Outbound calls require positive balance.
Pricing
Per-minute pricing by product tier.