> ## Documentation Index
> Fetch the complete documentation index at: https://recurr.dev/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Test mode

> Develop against isolated test data with a test API key — no real charges, no real emails, same endpoints.

<Warning>
  **🚧 Under development.** Test mode is part of the committed contract; it ships
  with the API. This page documents the model you'll integrate against.
</Warning>

Recurr follows the model you already know from Stripe: **one API, two
environments, separated by the key.** A `rk_test_` key operates on **isolated
test data** — you can build and exercise the full integration without touching a
real subscriber, moving real money, or sending a real email.

## How it works

* **Same base URL, same endpoints.** You don't change hostnames — you change the
  key. `rk_test_…` → test environment; `rk_live_…` → live.
* **Isolated data.** Test subscribers, subscriptions, charges, and events live in
  a separate `livemode = false` space. Test objects are never returned to live
  calls and vice-versa.
* **No real side effects.** Test-mode charges use Stripe **test cards** (e.g.
  `4242 4242 4242 4242`); no money moves. Test-mode emails are not delivered to
  real inboxes.
* **Real webhooks, flagged.** Test actions emit the same webhook events to your
  test endpoints, with `livemode: false` on the envelope, so you can verify your
  receiver end-to-end.

<Note>
  Everything in test mode is clearly marked **TEST** in the dashboard, and every
  object carries a `livemode` flag. If you're unsure which environment you're in,
  check the key prefix and the `livemode` field.
</Note>

## A typical test loop

1. Create a `rk_test_` key (**Settings → API keys**).
2. Point your dev/staging config at it (`RECURR_API_KEY=rk_test_…`).
3. Create a test subscriber + subscription via the API.
4. Trigger a charge with a Stripe test card; confirm the `payment.succeeded`
   webhook arrives at your test endpoint with `livemode: false`.
5. Exercise pause / resume / cancel / refund and confirm the resulting events.

## Going live

When your integration is verified in test, swap the key for a `rk_live_` one in
your production config. **No code changes** — the only difference is the key.
Re-run your smoke checks against live with a small, controlled cohort first.

<Warning>
  Test and live data never mix. Migrating test objects to live is not supported —
  recreate the handful you need in live, or let the real flow populate them.
</Warning>
