Skip to content

Usage and billing

Saram bills the steps your personas take. Everything else a run does is included: the browsers, the judge, and every reproduction replay. Model calls are on your own provider and are billed by them, not by Saram (Providers and your own keys).

You manage billing on the dashboard under Settings > Billing, and see what you used under Settings > Usage. Billing is for your organisation’s owners and admins; over the API, a billing route needs a key with the keys:admin scope.

A step is one action a persona takes: a click, a keystroke, a scroll, a look at the page. Only the personas’ steps are billed. A reproduction replay’s steps, and a retest’s, never are.

On the Free and Pro plans, each step is weighed by how long it took, and the result is a unit called Usage:

Usage of one step = 0.5 + 0.1 x (the step's seconds, counted up to 30)

A typical 5-second step is 1 Usage, and no step is more than 3.5, however long it stalls. A run’s bill is its Usage times your plan’s price per Usage.

A session that fails on Saram’s side is refunded in full. The usage report says whose failure ended each session: none, saram, provider or target.

Free Pro
Monthly fee $0 $20, before tax
Credit included each month $1 $10
Price per Usage $0.02 $0.016
Sessions of one run at the same time 2 8
Evidence kept (videos, screenshots, step traces) 14 days 90 days
People in the organisation 2 10
Automation: GitHub issues and pull request comments, the run-finished webhook, the CI action No Yes

The figures are Saram’s plan list on 2026-10-23. billing_overview (GET /api/v1/billing) answers your own: monthly_fee_usd, included_credit_usd, usage_price_usd and limits.

  • Retention. Evidence is kept for its days counted from the run’s creation. A run keeps the longer of what your plan kept when it ran and what it keeps now, and says the date as evidence_expires_at. The run’s findings are kept after its evidence is gone.
  • Automation. On Free, a spec naming connectors.github or connectors.webhook is refused when it is validated or started, never run without it. The API and the MCP server are open on every plan.
  • Upgrading and cancelling. Upgrade on the dashboard. You are on Pro once the first invoice is paid. Cancelling ends Pro when the month already paid for ends, and the organisation then moves to Free; that month’s included credit stays until it expires.

Some organisations are on an older plan that bills each persona step at a fixed price, invoiced after the month. See Reading your usage for how those read.

On Free and Pro you pay for Usage before you use it. The balance has two parts:

  • Included credit comes with your plan each month and expires at the end of the month.
  • Purchased credit comes from top-ups and does not expire.

When a run starts, it holds the most it can cost: its ceiling, worked out from the spec’s budgets. Each session that finishes is then charged what it actually used, and what is left of the hold goes back. So GET /api/v1/billing reads:

Field
included_usd, purchased_usd The two parts of the balance
balance_usd Both together
held_usd What runs in flight have reserved
available_usd What a new run can hold against: the balance less the holds

A run starts only if available_usd covers its ceiling. If it does not, POST /api/v1/runs is a 402 naming the ceiling and the balance, and no run starts. A run that has started has its ceiling held, so it finishes. Validate tells you before you try: its usage_ceiling answers the run’s most Usage, its price, available_usd, whether it is covered, and steps_per_session_that_fit, the largest budget.steps_per_session your balance would cover. enforced: false there means the balance is not yet being enforced for your organisation.

The ceiling is counted with every step at its most, 3.5 Usage, so a normal run bills well under it. To lower a ceiling, lower budget.steps_per_session or set budget.wall_clock_s_per_session.

A top-up buys purchased credit: whole dollars, from $10 to $500, as a one-off invoice for “Saram usage credit, N x $1.00”, with tax on top where it applies. Top up on the dashboard: it needs a card on file, and the payment is made in your browser on Stripe’s form. Saram never sees the card.

Credit lands once Stripe says the invoice is paid, never on the browser’s word. An invoice left unpaid for a day is voided. The last twenty top-ups are in top_ups on GET /api/v1/billing.

Invoices and receipts are in Stripe’s customer portal, linked from the dashboard (billing_portal).

With auto-refill on, whenever available_usd falls below your threshold, Saram charges your card your chosen amount ($10 to $500) and adds it as purchased credit. Turning it on needs a threshold, an amount and a card on file. If the balance is already under the threshold, the first refill starts at once. A declined charge, or one your bank wants you to authenticate, turns auto-refill off.

The monthly budget is the most Saram may charge your card in one calendar month, top-ups made by hand and by auto-refill together. No budget means no limit. When the month’s charges reach it:

  • A top-up that would pass it is refused with a 409.
  • A refill that is due is skipped, not charged. auto_refill.last_skipped says so, so the dashboard can show that auto-refill is on but the month’s budget is spent. The next month’s budget has room again.
  • Runs go on while the balance covers them, and stop starting, with a 402, once it does not.

Set both on the dashboard, or with billing_auto_refill. budget_used_usd on GET /api/v1/billing is what this month’s top-ups have used of the budget.

get_usage answers one calendar month for your organisation alone:

Terminal window
curl -s "https://api.saram.sh/api/v1/usage?period=2026-10" -H "Authorization: Bearer $API_KEY"

period is YYYY-MM in UTC, and left out it is this month. A month you ran nothing in answers zeros, not a 404. The answer has:

Field
usage Free and Pro: what Saram charged. The month’s Usage and its cost (usage, usage_usd, net of refunds), refunded_usd, and the same by run, by persona and per refund
provider Your model provider’s estimated bill for the month, from your own keys. Shown apart and never added to Saram’s charge
totals, meters What was measured: steps, sessions, browser_seconds, and model spend on Saram’s credential (model_usd_hosted) and on yours (model_usd_byo). These are reports, not charges
runs Each run metered in the month, oldest first
billable_usd, billed_steps, step_price_usd, monthly_cap_usd Older plans that bill steps only. On those, billable_usd is the month’s bill, and a new run is refused with a 402 once it reaches monthly_cap_usd

get_usage_csv is the same month as a file, the one an invoice is written from:

Terminal window
curl -s "https://api.saram.sh/api/v1/usage.csv?period=2026-10" \
-H "Authorization: Bearer $API_KEY" -o usage-2026-10.csv
period,tenant,run_id,session_id,persona_id,persona_label,caller,occurred_at,steps,sessions,browser_seconds,model_usd_hosted,model_usd_byo,persona_steps,persona_seconds,usage,fault,usage_usd,refunded_usd,billable_usd

Each run has a row, followed by one row per session of that run, then a TOTAL row. A run’s row carries the run’s meters, steps to model_usd_byo, and billable_usd. A session’s row carries its persona_steps, its persona_seconds (the time its steps took, without the session’s setup and teardown), its usage, fault, usage_usd and refunded_usd. Each leaves the other’s columns empty, so every column sums to its total. A session that failed on Saram’s side reads fault saram, usage_usd 0.0000, and its whole charge in refunded_usd. usage_usd and refunded_usd are empty, not zero, where the balance was not charged for the session: on an older plan, or while the session is not yet settled.

Below the TOTAL row, after one empty line, is a second table: the credit that came into your balance or lapsed from it that month, oldest first. Its header is there in a month with no credit too, so a script that splits the file at the empty line always finds it:

period,tenant,kind,bucket,amount_usd,created_at,stripe_ref
Column
kind grant (the month’s included credit), top_up, expiry (included credit left at the end of the month, in the month whose credit lapsed) or adjustment (a correction Saram made)
bucket included or purchased, the part of the balance it moved (The prepaid balance)
amount_usd Signed, to four places: a grant and a top-up are positive, an expiry is negative
stripe_ref The Stripe invoice behind a top-up or a Pro grant, empty on a row nobody paid Stripe for

The credit rows less the month’s usage_usd are how far the month moved your balance. What runs charged and refunded is in the session rows above, not here.

Each run also says what it used. GET /api/v1/runs/{run_id} carries its usage, usage_usd (what it was charged, refunds taken off) and refunded_usd. They rise while the run is open and are final once usage_state is settled or refunded. cost_usd beside them is model spend, not Saram’s charge.

Block Checked
The fees, included credit, session, retention, member and automation limits The descriptions of BillingOverview and PlanLimits in platform-api 0.9.0 (/openapi.json), and Saram’s plan list
The price per Usage and the Usage formula Saram’s plan list (0.5, 0.1 a second, 30 seconds at most); the reference’s CostCeiling (“a typical 5-second step is about 1 Usage, against the 3.5 a step can reach”)
GET /api/v1/billing, /usage 2026-10-23 against api.saram.sh, on an organisation on an older plan that bills steps: the fields shown; its figures are left out
GET /api/v1/usage.csv 2026-10-25 against api.saram.sh (platform-api 0.14.0), for 2026-09 and 2026-10, on an organisation on an older plan that bills steps: both headers shown, the run, session and TOTAL rows, the empty line, and the credit table’s header with no credit rows under it; its figures are left out. The credit columns’ values are from the reference’s get_usage_csv
The 402, the 409 and the top-up and auto-refill bounds The reference’s create_run, billing_top_up, TopUpWrite and AutoRefill; not run, as each is a charge or a refused run