Skip to main content
Some Recoup endpoints are billed in credits — primarily endpoints that hit external data providers, run AI inference, or generate content. The rest of the API is free at the API layer.

What’s billed

Failed calls (4xx / 5xx) do not deduct credits. Deduction happens only after the upstream call succeeds.

What a credit is worth

Balances and prices are US dollars. The ledger stores amounts as integer micro-dollars, the same 6-decimal unit as USDC: 1,000,000 = $1.00, so it can carry sub-cent charges (a $0.002/s provider rate prices exactly). Every credit field the API returns is that integer; divide by 1,000,000 to display it as currency. Example: GET /api/accounts/{id}/credits.

Check your balance

Response shape:
plan, task_limit, and min_cadence_minutes describe the plan the balance belongs to. total_credits is your plan-derived monthly allotment. remaining_credits can exceed total_credits after a top-up or an admin grant, and used_credits clamps to 0 in that case. Full schema at Get Account Credits. To see what consumed the balance, list the charges line by line with GET /api/accounts/{id}/usage: one item per deduction, newest first, each with the amount in micro-dollars and as a dollar string, plus the total for the period. API charges name the endpoint that billed them in model_id (for example POST /api/artist/socials/scrape), so a list of charges reads as a list of calls.

Subscription

Recoup has three plans. All three refill credits on a monthly cycle, and the plan also sets how many scheduled tasks an account can run and how often they can fire.

Task limits

POST /api/tasks and PATCH /api/tasks check the plan before writing. Creating a task past task_limit, re-enabling a disabled task past it, or saving a cron whose consecutive runs are closer together than min_cadence_minutes returns HTTP 402 with error: "plan_limit":
limit is task_count or min_cadence; current_task_count excludes the task being created or updated. Edits that only touch title, prompt, or model never hit the gate.

Monthly refill

The refill is a floor, not an assignment. It raises remaining_credits up to your plan’s monthly total and never lowers it. A balance already above the plan total, whether from a top-up or an admin grant, is left exactly as it is, so credits you bought or were granted are never taken away by the calendar. The refill is lazy rather than scheduled: it applies on the next read of GET /api/accounts/{id}/credits once your credits row is more than a month old. The balance you read is always the refilled one.

Upgrade to Starter or Pro

  1. Sign in at app.recoupable.dev/plan
  2. Pick a plan, or call POST /api/subscriptions/sessions with plan set to starter or pro and open the returned checkout url
  3. Stripe checkout creates a subscription tied to the account your API key authenticates against. Pro subscriptions include a 30-day trial; Starter is charged at checkout

Check your tier

Get $ACCOUNT_ID from GET /api/accounts/id if you don’t already have it. Response includes isPro (boolean), status, plan, and source (whether the subscription comes from the account itself or an organization the account belongs to). Full schema at Get Subscription.

One-time top-ups

You can purchase credits any time via POST /api/credits/sessions. The endpoint adapts to what’s on the account:
  • Card on file → silent auto-charge. Recoup charges your saved Stripe card off-session and returns paymentIntentId, creditsPurchased, and totalCents. Credits land within seconds.
  • No card, or Stripe declines the saved card → Stripe Checkout fallback. The response contains a Checkout url you open in the browser. When Stripe specifically declined a saved card, the response also includes a declineReason (e.g. insufficient_funds, expired_card) so you can explain why before sending the customer to update billing.
Full request/response schema at Create Credits Top-Up Session.

Check which card will be charged

Before triggering a silent off-session charge, inspect the default payment method on file:
Response shape:
card is null when no payment method has been saved yet — the next top-up call will route through a checkout session to collect one. Expired cards are still returned (with their original exp_month / exp_year); callers should compare against the current date and warn the customer, since an off-session charge against an expired card will decline. Full schema at Get Default Payment Method.

Running out of credits

Every billed API request runs a credit gate before it executes. If remaining_credits doesn’t cover the request’s cost, the request stops there and returns HTTP 402. Nothing is charged and no Stripe object is created. The decision tree:
  1. Enough credits? → Request proceeds, credits deducted on success.
  2. Short? → Request returns HTTP 402 with the balance, the cost, and a link to billing.
A card on the account is never charged on its own. Charging happens only when the account asks to buy credits, through POST /api/credits/sessions, or when the account has turned on auto top-up. Saving a card ahead of time via POST /api/accounts/{id}/payment-method makes a one-time purchase a single call instead of a browser round-trip; it does not authorize a charge by itself. Your plan, card, and every payment are on /api/accounts/{id}/subscription, /api/accounts/{id}/payment-method, and /api/accounts/{id}/payments; pass an organization id as {id} to read the organization’s billing.

Auto top-up (opt-in)

Auto top-up is off for every account until it is turned on with PUT /api/accounts/{id}/auto-top-up, which needs three things chosen by the account: enabled, the amountCents to buy each time (5.00 to 1,000.00 USD), and the thresholdCents balance that triggers it. Both are USD cents; the remaining_credits balance above is in credit micro-dollars, so divide it by 10,000 to compare. Turning it on requires a card on file. Once on, the first credit deduction that leaves the balance below the threshold charges the card for the amount, grants the credits, records a usage event, and emails a receipt. Guardrails: at most one top-up per account per 10 minutes; a card decline turns auto top-up off, records the decline message as lastError (returned by GET /api/accounts/{id}/auto-top-up), and emails the account instead of retrying; removing the card turns it off. Auto top-up never creates a checkout session and never touches an invoiced (enterprise) plan. Saving a card does not turn auto top-up on by itself.

402 Payment Required

When the gate comes up short, billed endpoints return HTTP 402 with a unified body:
billingUrl is a constant, not a freshly minted Stripe Checkout Session. Retrying a credit-gated endpoint returns the same URL every time and creates nothing, so an unattended client that keeps hitting the gate is safe to leave running. How to react:
  • Browser-driven UI (e.g., the Recoup chat app): send the customer to billingUrl, or call POST /api/credits/sessions inline and open the url it returns.
  • Programmatic / LLM-driven client: report remaining_credits and required_credits, and surface billingUrl as the link a human needs to visit. Do not treat a 402 as retryable; the balance will not change on its own until someone buys credits or the monthly refill lands.

Cost per endpoint

Current as of this revision of the page. The authoritative source is the per-endpoint reference docs and the required_credits field on any 402 response.