BatchRouter Docs

Auto top-up

Configure automatic credit top-ups so long-running BatchRouter pipelines never stall on insufficient credits, and review the charge-attempt history.

Auto top-up charges a saved card off-session to refill your credit balance whenever it drops below a threshold you set. Enable it so a long-running or unattended pipeline keeps dispatching instead of failing with 402 insufficient_credits partway through.

This page covers the three endpoints that manage it: read the config with GET /v1/billing/auto-topup, change it with PUT /v1/billing/auto-topup, and review the off-session charge history with GET /v1/billing/auto-topup/attempts.

Auto top-up is the automatic counterpart to buying credits by hand in the dashboard. There is no public billing-checkout endpoint — manual purchases happen in the dashboard, and auto top-up is the only programmatic way to add credits. See Credits and billing for how the balance works.

When to enable it

A batch is rejected with 402 at submit time if your balance can't fund it. For a single ad-hoc batch that's easy to handle by topping up manually. Auto top-up matters when you can't be in the loop:

  • Long-running or chained pipelines that submit many batches over hours or days and would otherwise stall mid-run.
  • Unattended / scheduled jobs (cron, agents, CI) where no human is watching the balance.
  • Bursty workloads where spend is hard to predict ahead of time.

When enabled, the balance is refilled back up to a target you choose as soon as it falls below your threshold, so submits keep succeeding.

Configuration fields

The configuration object (auto_topup) uses these fields. Money values are returned as objects ({ "currency": "usd", "amount": "25.00" }); when you write them via PUT, you send plain USD-dollar numbers.

FieldTypeDescription
enabledbooleanWhether auto top-up is active.
thresholdmoneyBalance that triggers a refill.
targetmoneyBalance to refill up to. Must exceed threshold.
payment_method_idstringThe saved card charged off-session. Must belong to your org.
max_per_dayinteger | nullMaximum auto top-ups per day; null means no cap.
monthly_ceilingmoney | nullMaximum total auto top-up spend per month; null means no cap.
oncredit_exhaustedblock | pauseWhat happens when credits still run out: hard-block new batches, or pause the org gracefully.
configuredbooleanRead-only. Whether a config row exists yet.
consecutive_failuresintegerRead-only, system-managed. Resets on a successful charge.
paused_reasonstring | nullRead-only, system-managed. Set when repeated failures auto-pause top-up.

consecutive_failures and paused_reason are system-managed — you can read them but not set them. Repeated off-session charge failures will auto-pause top-up and populate paused_reason. Always confirm the exact set of writable fields against the API reference.

Read the current config

GET /v1/billing/auto-topup returns the org's auto top-up configuration under an auto_topup key. Reading is authorized with either a customer API key or a signed-in dashboard session.

curl https://api.batchrouter.com/v1/billing/auto-topup \
  -H "Authorization: Bearer $BATCHROUTER_API_KEY"

A representative response:

{
  "auto_topup": {
    "org_id": "org_...",
    "configured": true,
    "enabled": true,
    "threshold": { "currency": "usd", "amount": "10.00" },
    "target": { "currency": "usd", "amount": "50.00" },
    "payment_method_id": "pm_...",
    "max_per_day": 3,
    "monthly_ceiling": { "currency": "usd", "amount": "500.00" },
    "consecutive_failures": 0,
    "paused_reason": null,
    "oncredit_exhausted": "block"
  }
}

Update the config

PUT /v1/billing/auto-topup performs a partial merge: only the fields you send are changed; everything else is left as-is. Money fields are sent as plain USD-dollar numbers (e.g. 50 for $50.00).

Mutating the config requires a signed-in, email-based user session — an API key with no associated user is rejected with 403 user_session_required. In practice, configure auto top-up from the dashboard or a session-backed call, not from a bare br_live_… key.

Enabling auto top-up has hard prerequisites. The PUT will reject the change unless all of these hold:

  1. Your account email is verified.

  2. A threshold is set, and a target greater than the threshold is set.

  3. A saved payment_method_id that belongs to your org is set.

  4. The environment supports off-session charging. If it doesn't, you'll get 503 auto_topup_unavailable.

curl -X PUT https://api.batchrouter.com/v1/billing/auto-topup \
  -H "Authorization: Bearer $BATCHROUTER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "enabled": true,
    "threshold": 10,
    "target": 50,
    "payment_method_id": "pm_...",
    "max_per_day": 3,
    "monthly_ceiling": 500
  }'

A successful PUT returns the merged config in the same { "auto_topup": { … } } shape as the GET. To turn auto top-up off, send { "enabled": false } — the rest of the config is retained.

Pair auto top-up with spending controls to bound how much it can spend. max_per_day and monthly_ceiling cap the refill activity itself, while spending controls cap your overall usage — together they give you an automatic safety net and a hard ceiling.

Review charge attempts

GET /v1/billing/auto-topup/attempts returns recent off-session charge attempts, newest first, under a data array. Use it to confirm a refill went through or to diagnose a failed charge. Pass an optional limit query parameter (1–200, default 50).

curl "https://api.batchrouter.com/v1/billing/auto-topup/attempts?limit=20" \
  -H "Authorization: Bearer $BATCHROUTER_API_KEY"

Each attempt records the trigger_balance (what the balance was when the refill fired), the amount charged, the payment_method_id, the Stripe payment intent, a status (pending, succeeded, requires_action, or failed), and a failure_code when the charge didn't go through. A successful attempt also carries a credited_transaction_id linking to the credit that landed on your balance. See the API reference for the full field list.

A failed attempt — or a card that needs authentication (requires_action) — leaves your balance unchanged, and repeated failures will auto-pause top-up (paused_reason is set). Watch this endpoint, or your delivery webhook, so a silently declining card doesn't surface as a surprise 402 on a later submit.

Next steps

On this page