Zero to a validated first bill

A workspace, a plan, a customer, a subscription, one usage event — and a rated invoice you can read line by line. Everything below runs in the test environment — no processor, no card, no money moves. The full endpoint reference is at /docs.

01

Create your workspace

Sign in and name your organization. That one step provisions everything: a merchant account plus separate test and live environments, fully isolated from each other. You land in test mode, where the rest of this page happens.

02

Follow the Launch guide

A new workspace lands on the Launch guide — a checklist whose progress is derived from your actual billing data, not ticked boxes. It walks you through billing identity, your first plan (one-click starters exist for AI/token, seat, and usage pricing), a test customer, and a subscription. Prefer to do those over the API instead? Step 4 below is the same chain in curl.

03

Mint a test API key

In the cockpit: Settings → API keys. Keys look like roi_sk_test_…, are shown once, and roi stores only a keyed hash. A test key can only ever reach test data — there is no header or flag that lets it touch live.

export ROI_API_KEY=roi_sk_test_...

04

Create a customer and subscription

Objects take your identifiers via external_id, so your product never stores roi UUIDs. Creating the same external_id twice returns a conflict rather than a duplicate — safe to retry.

curl https://api.billroi.com/v1/customers \
  -H "Authorization: Bearer $ROI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"external_id":"workspace_42","name":"Acme AI","email":"billing@acme.test"}'

A subscription needs a plan. Grab the id from the plan you created in the Launch guide — it is on the pricing page, or one GET /v1/plans away.

curl https://api.billroi.com/v1/subscriptions \
  -H "Authorization: Bearer $ROI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "external_id": "workspace_42_pro",
    "customer_external_id": "workspace_42",
    "plan_id": "PLAN_ID"
  }'

This starts a durable billing workflow: period close, rating, invoicing, and — once money is involved — retries all run inside it. No payment method is required in test; without one, invoices simply collect as invoices rather than auto-charges.

05

Send a usage event

Metered billing is one POST per product fact. The idempotency_key is yours — use your business event id, and retries become safe.

curl https://api.billroi.com/v1/usage \
  -H "Authorization: Bearer $ROI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "subscription_external_id": "workspace_42_pro",
    "event_name": "generation.completed",
    "properties": {"tokens": 1200, "model": "gpt-4.1", "token_type": "input"},
    "quantity": 1,
    "source": "quickstart",
    "idempotency_key": "event-0001"
  }'

The cockpit's API-keys page renders this exact snippet with your real key and subscription pre-filled, plus Node and Python variants — and an MCP config, if you want an AI agent reading your billing data.

06

Validate your first bill

Back in the Launch guide, Validate first bill runs the entire invoice waterfall — rated subtotal, minimum true-up, tax, amount due, per-line margin — as a read-only pass. No invoice, payment, credit, or ledger state is created. This is the proof that your pricing does what you think it does, before a processor is anywhere near it.

07

Go live when you are ready

Connect the processor you already have — Stripe connects over OAuth; others take their API credentials on the Connections page — then promote your certified test configuration to live from the Launch guide. roi only ever holds processor-minted references, never card data: your PSP keeps the vault, the merchant agreement, and the funds flow.

Start in test modeAPI reference