Going live
Switching modes is a one-line change. Everything hard about going live happens before it: an approval by a person, a deposit that has to actually clear before you can spend it, and a handful of cases your integration must already handle because production will find them.
The sequence
- Build against sandbox. Every route, every shape and every price calculation is identical. Rehearse the four failure cases before anything else — they are what production will hand you.
- Ask for approval. Email [email protected] with what you sell, where your customers are, and roughly what volume you expect. A person reads it. There is no form and no automated approval, and we would rather say so than build a form in front of a queue.
- Deposit.
POST /partner/v1/depositsmints a cryptocurrency invoice for a whole number of dollars between $100 and $10,000, and answers a link to pay it. Bank transfer is the rail for anything larger. It is a live-mode operation — a sandbox key is refused with403— so approval comes first, and the invoice is not the credit: the float moves when the payment settles. An owner can open the same invoice from the cabinet without writing any code. The three behaviours that surprise people. - Mint a live key. An owner on the account does it in the partner cabinet, once the account is approved. It begins
simway_sk_live_rather thansimway_sk_test_and the secret is shown once and never again — there is no endpoint and no screen that can produce it a second time. Store it where you store secrets, not in your repository. - Change the key. That is the migration. Same base URL, same routes, same payloads.
The checklist worth passing first
Each line is a case that production will produce and sandbox can rehearse. An integration that handles all of them is not going to be surprised by this API.
| Case | What good looks like |
|---|---|
| Idempotency keys are persisted before sending | The key is written next to your order record first, so a process that crashes mid-request can resume with the same key rather than mint a second one. |
| Keys are namespaced per mode | A key used in sandbox is a 409 in live. A prefix, or a fresh UUID per order. |
| A timeout resends the same key | You get a 200 replay rather than a second order. Prove it against the slow fixture. |
| A 402 mints a new key | Topping up does not release the old one; it is bound to that refusal permanently. |
| You never retry a 202 | The order is durable. Poll it. |
| Your poller follows poll_after_ms | And stops when it is null, rather than enumerating terminal statuses itself. |
| Partial delivery is a real branch | Some profiles arrive, some money returns. Neither success nor failure, and it needs its own path through your fulfilment code. |
| You read your_price_cents | Rather than multiplying the list price by your tier rate. |
| Your catalogue mirror runs a full pass sometimes | updated_since never reports a deletion, so an incremental-only sync will keep selling delisted plans. |
| You pace on the rate-limit headers | They are on every response, not only on 429s. |
| A 429 without Retry-After alerts an operator | That is a rejected credential, not congestion. Backing off will not fix it. |
| Balance is monitored | A 402 in a live checkout is a customer who cannot buy. Watch balance_cents and low_balance_threshold_cents. |
What to expect on day one
- You start on Bronze at 8% off list. The rung is recomputed nightly from trailing 30-day live spend, so it moves on its own once you are selling — the next rung is $1,000 in a rolling 30 days.
- Statement rows begin appearing immediately, and this is the first time you will see them — sandbox writes none. Reconciliation is worth testing here, carefully.
- A supplier failure now takes up to 8 minutes to be reported as
failed, rather than settling on the first pass the way the sandbox fixture does. Your own customer-facing timeout should be longer than that, or you will tell a customer it failed while it is still trying. - Usage counters are up to 30 minutes old. Show a timestamp beside them.
Operating it
Monitor these four
Keep in mind
- Keys are per workload. Rate-limit buckets are per key, so a nightly catalogue import on its own key cannot starve live checkout. Ask for a second key rather than sharing one.
- Rotation costs no downtime. The replacement is issued when rotation begins and both keys work until the old one expires.
- An IP allowlist is worth having and is not a second factor. The honest version.
- Quote the request id. Every response carries
X-Request-Id, including 401s, and every error body repeats it. It is the fastest route to an answer from us.
Do not plan around these
Absent rather than pending. If your roadmap needs one of them, tell us before you build rather than after.
| Not built | What to do instead |
|---|---|
| Webhooks of any kind | Poll. The order tells you the interval and when to stop. |
| Order cancellation | An order runs to a terminal state. Undelivered units refund themselves. |
| A refunds API | Money returns only through automatic settlement of undelivered units. |
| Card deposits | Cryptocurrency or bank transfer. A card chargeback lands months after the float has been spent on profiles bought at wholesale. |
| Key management endpoints | Email us to create, label, revoke or rotate a key. |
| A live usage read, or batch usage | Counters are up to 30 minutes old. |
| Suspend, unsuspend or top up a profile | A profile runs its course. More data is a new order. |
| A hosted QR image URL | Use qr_code_data_url, and store it on your side. |
| A statement CSV export | GET /ledger is JSON, and pages. |
| A minimum resale price | There is none. min_resale_price_cents is null on every plan. |
Machine-readable copies
- /partners/openapi.json — an OpenAPI 3.1 document generated from the same typed reference these pages render.
- /partners/llms-full.txt — the whole reference as one flat Markdown file, for a coding assistant.
- /partners/llms.txt — a short curated index of the same.