> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.runledger.co/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.runledger.co/_mcp/server.

# Going live

> **Note**
>
> This page is the plan to follow to go live. The runbook, which starts at [Make your integration production-ready](/going-live/production-ready), has the code and the full steps.

Going live means five things: your agents keep working when Runledger is slow or down, no event is lost or billed twice, someone decides every dispute, you've compared Runledger's invoices with your own before a customer sees one, and the live configuration and payment providers are connected and reviewed by a person. An account starts in the sandbox, and live keys and live configuration work from the start. Live takes no payments until every row of the checklist below passes and Runledger has reviewed the account. An Admin then connects and confirms the first live payment provider; connecting a live provider isn't open yet.

## Before you start

* An integration that works in the sandbox. The [quickstart](/quickstart) builds one.
* Someone who can approve live configuration: an Admin in the [dashboard](/dashboard#roles). A Collaborator proposes live changes, and an Admin approves them.

## Keep checks off the critical path

`check()` runs before the work starts, so your users wait for it. Runledger is hosted in Australia, so from North America or Europe every call makes a long network round trip. Three habits keep it out of the way:

* **Check once per run.** Call `check()` when a conversation or run starts, and hold its whole budget. One hold covers the run, and a long run can [extend it](/api-reference/holds/extend).
* **Start the work and the check together.** A voice agent can greet the caller while the check runs, then act only if it comes back denied.
* **Fail open when Runledger doesn't answer.** Give `check()` a short timeout and no retries. If it times out, let the work run and record it with `track()` afterwards. Recording finished work [never fails for lack of balance](/concepts/checks-and-holds#work-that-already-happened), so the cost of an outage is a prepaid balance that can go below zero until it ends.

## Send events through your queue

Put `track()` on the job queue you already run, and build each `idempotency_key` from your own IDs, such as `conv_4821-resolved`. Every retry of the job then lands on the same event, for up to 35 days, so nothing is billed twice. Set `timestamp` to when the event happened: events can be dated up to 35 days back, so a job that waits out an outage is still billed in the right period. Send the `warnings` that `track()` returns to someone who can act on them; `no_rate_for_event` and `reference_not_found` usually mean an event name or a reference doesn't match your setup.

## Decide who handles disputes

When nobody decides a dispute by its deadline, its `default_decision` applies, and that's `reverse` unless you change it. Before you go live, send `dispute.decision_due` (it fires 24 hours before each deadline) to the people who will decide, give them a list of open disputes with the evidence, and set the default to `uphold` if your contracts say a charge stands unless it's reversed. A [notification rule](/api-reference/how-configuration-works#notification-rules) on `dispute.decision_due` emails them without any code on your side. A dispute that is still open when a charge's reversal horizon passes holds the charge's lock until it's decided, so a dispute nobody sees also keeps revenue from locking.

## Plan the move from your current billing

Runledger runs your plans, subscriptions and invoices, and your payment providers still collect the money. Settlement runs on Runledger's own plans and invoices, so it doesn't sit on top of a billing system you already use.

Move customers at the start of a billing period. Your old system bills everything dated before that boundary, and Runledger bills everything from it. Unused prepaid credits move as paid credit grants, valued at what the customer paid, and each subscription is created at the boundary, since a subscription starts when it is created. Runledger can't use a card your provider already holds, so customers who pay by card save it again on a hosted checkout page before the boundary, at whichever of your connected [payment providers](/concepts/payment-providers) routing picks for them. A customer stays with that provider afterwards. Charges your old system made stay there: if a customer comes back about an earlier conversation, credit it the way you do today.

## Compare before you switch

1. **Backtest.** Replay a few months of your own history in the sandbox on a [test clock](/api-reference/test-in-the-sandbox#test-clocks), and compare the invoices with the ones you sent.
2. **Shadow run.** Send your live traffic to the sandbox for one billing period while your current billing keeps invoicing, with `check()` denials logged and not enforced.
3. **Cut over** at a period boundary. Keep your old billing set up, and switched off, until the first Runledger invoices are paid.

## Checklist

| Item                    | Done when                                                                                                                                                                                                                                                                                                                                                                                                                      |
| ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| Email                   | The Admin's email address is verified. Sandbox work doesn't need it, and live can't open without it                                                                                                                                                                                                                                                                                                                            |
| Keys                    | Restricted live keys (`rl_rk_live_...`) are in your secret store and used only from your servers                                                                                                                                                                                                                                                                                                                               |
| `check()`               | It runs once per run, alongside the work, with a short timeout, and fails open when Runledger doesn't answer                                                                                                                                                                                                                                                                                                                   |
| `track()`               | It runs from your queue, with idempotency keys built from your IDs and the real `timestamp`                                                                                                                                                                                                                                                                                                                                    |
| Warnings                | `track()` warnings reach someone who can fix the event names, references or plans behind them                                                                                                                                                                                                                                                                                                                                  |
| Webhooks                | A live endpoint verifies signatures, drops duplicates on `webhook-id` and fetches each object before acting                                                                                                                                                                                                                                                                                                                    |
| Disputes                | `dispute.decision_due` reaches the people who decide, and each outcome definition has the `default_decision` your contracts call for                                                                                                                                                                                                                                                                                           |
| Evidence                | Outcome events carry a transcript link and a factual description, with no personal data                                                                                                                                                                                                                                                                                                                                        |
| Payment providers       | A provider is connected in the sandbox and a test payment through it has succeeded, such as a checkout completed with a test card. After the review, each provider you'll use is connected in live by a person, with currencies and countries set, an Admin confirms the first one, and routing sends each new customer where you expect (`POST /v1/payment_providers/resolve` shows which); connecting in live isn't open yet |
| Reconciliation          | Someone is alerted on `reconciliation.breaks_found`, and a reconciliation runs for each provider                                                                                                                                                                                                                                                                                                                               |
| Top-up chargebacks      | If you take card top-ups, a notification rule on `topup_chargeback.threshold_exceeded` has a threshold you chose, and someone owns the response                                                                                                                                                                                                                                                                                |
| Notifications           | `dispute.decision_due`, `reconciliation.breaks_found` and `proposal.pending` reach the people who act on them                                                                                                                                                                                                                                                                                                                  |
| Agent access            | Agent keys carry only the scopes they need and an expiry, none holds `charges:write` or `disputes:resolve`, and a person reviews every proposed live change                                                                                                                                                                                                                                                                    |
| Repeated errors         | At most 5% of the sandbox's requests in the last seven days failed. Above that the row warns, and above 20% it fails, with the commonest error codes                                                                                                                                                                                                                                                                           |
| Backtest and shadow run | Runledger's invoices match yours, or every difference is explained                                                                                                                                                                                                                                                                                                                                                             |
| Cutover                 | Old subscriptions end at the boundary, and each event goes to the system its `timestamp` belongs to                                                                                                                                                                                                                                                                                                                            |
| Reviewed by Runledger   | Runledger has reviewed the account and approved live access. The row reads **In review by Runledger** until it does                                                                                                                                                                                                                                                                                                            |

`POST /v1/integration_checks` reviews your recent sandbox traffic for what a live integration needs and returns a pass, warn, fail or unknown result for each item, with the fix. The dashboard's Get started page and the [developer MCP server](/agents/mcp)'s `check_integration` tool show the same result. A row the data shows passes on its own, and a row you can't attest has to pass. Some rows read unknown until there is something to read: Agent access until an agent key exists, and Evidence until an outcome event has been sent. An Admin asks for Runledger's review from Get started once every other row is done.

## Next steps

* [The going-live runbook](/going-live/production-ready) has the code for each item.
* [Webhooks](/api-reference/handle-webhooks) and [Idempotency and errors](/reference/idempotency-and-errors) are the references behind the checklist.