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

# Testing

> Test an integration in a sandbox, without billing a real customer

A sandbox is a separate copy of your organisation for testing an integration. It has its own test API keys and webhook endpoints, and it invoices a Xero Demo Company instead of your real Xero organisation.

A sandbox sends no emails, is never billed, and doesn't count toward your plan's limits.

<Warning>
  Never test with a live key. A subscription created with a live key raises a real invoice for a real customer. Use a `saasybill_test_` key from a sandbox.
</Warning>

***

## How a sandbox differs from a live organisation

| | Live organisation | Sandbox |
| - | - | - |
| **API key prefix** | `saasybill_live_` | `saasybill_test_` |
| **Xero** | Your Xero organisation | A Xero Demo Company only |
| **Emails** | Sent as normal | None. Saasybill sends no emails, and Xero doesn't email invoices. |
| **Billing** | Counts toward your plan | Never billed |
| **Setup Mode** | Can be on | Always off, so invoices are always raised |
| **`livemode`** | `true` | `false` |
| **Time** | Real time | Real time, or a [test clock](#advance-the-test-clock) you control |

Each live organisation can have one sandbox. Only an owner or admin of the live organisation can open it.

***

## Set up a sandbox

<Steps>
  <Step title="Create a Xero Demo Company">
    In Xero, create a Demo Company, or reset your existing one. Saasybill can't do this for you. A sandbox accepts only a Demo Company, so it can never write to real books.
  </Step>

  <Step title="Create the sandbox">
    Go to **Organisation Settings**, then **Developer Settings**, then **Configuration**. In the **Sandbox** section, click <Badge>Create Sandbox</Badge> and choose what to copy from your live organisation. See [What you can copy](#what-you-can-copy).
  </Step>

  <Step title="Connect the Demo Company">
    Saasybill switches you into the sandbox. Go to **Integrations** and click <Badge>Connect Demo Company</Badge>, then complete the Xero sign-in.
  </Step>

  <Step title="Copy your accounts">
    If you copied plans, go to **Organisation Settings** in the sandbox and click <Badge>Copy accounts</Badge> under **Account Mappings**. Saasybill finds or creates your live revenue accounts in the Demo Company and maps the sandbox's plans to them.
  </Step>

  <Step title="Create a test key">
    Still in the sandbox, go to **Developer Settings**, then **API Keys**, and create a key. Keys created in a sandbox are test keys. Use it in your test environment.
  </Step>
</Steps>

A red bar across every page tells you when you are in the sandbox. Click **Back to** your organisation's name in the bar to return to your live organisation.

<Info>
  A sandbox with no Demo Company connected behaves like a live organisation with no Xero connection. Subscriptions work, but invoices fail to reach Xero and show on the Error tab.
</Info>

***

## What you can copy

When you create or reset a sandbox, choose which data to copy from your live organisation. Ticking an option also ticks the ones it needs.

| Option | Default | Notes |
| - | - | - |
| **Organisation settings** | <Badge color="green">On</Badge> | Currencies, defaults and invoicing settings. Not the Xero connection or account mappings. |
| **Product catalogue** | <Badge color="green">On</Badge> | Plans, add-ons, charges, categories and meters, with the meters each plan bills. Needs organisation settings. The API can't create plans, so without these there is nothing to subscribe to. |
| **Customers** | <Badge color="red">Off</Badge> | Names, emails and customer codes. Copying them puts customers' personal data where anyone with a test key can read it. Your Demo Company already has test contacts you can use instead. |
| **Subscriptions** | <Badge color="red">Off</Badge> | Pending and active subscriptions with their add-ons. Needs customers and the catalogue. Invoices, credit notes and history are not copied. The next renewal invoices into the Demo Company. |

<Warning>
  Copying customers copies their names and email addresses. Leave it off unless you need your real customer codes.
</Warning>

***

## Customers and contacts

Xero is the source of truth for contacts, and a Demo Company has its own.

* **Copied customers** get a Demo Company contact the first time they are invoiced. Saasybill reuses a contact that has the customer's code as its contact number, or creates one. The contact is created with the customer's name and code, not their email address.
* **Customers created through the API** follow the same rules as in a live organisation. An owner or admin must have allowed the API to create Xero contacts. See [Customers and Xero](/api-reference/guides/customers-and-xero).

***

## Advance the test clock

A sandbox's clock can stand still and move only when you advance it, so you can test a renewal without waiting a month.

<Steps>
  <Step title="Open the Test Clock">
    In the sandbox, go to **Developer Settings**, then **Configuration**, and click <Badge>Advance Clock</Badge> on the **Test Clock** row.
  </Step>

  <Step title="Choose a date">
    Pick the date to advance to. The clock moves to midday on that date in the sandbox's timezone, so every renewal due that day is included. You can advance by up to 366 days at a time.
  </Step>

  <Step title="Wait for it to finish">
    Saasybill steps through each renewal, start and end in order, and pushes the invoices to the Demo Company. Advancing a long way takes longer. You can't start another advance, or reset the sandbox, until it arrives.
  </Step>
</Steps>

Once the clock is set, everything in the sandbox happens at the clock's time. That includes subscriptions and unit changes you make through the API and in the app. The scheduled renewal run leaves a sandbox with a clock alone, so it renews only when you advance it.

To test [usage-based billing](/api-reference/guides/usage-based-billing), report events with a test key, then advance the clock past the end of the billing period. Saasybill closes the period and raises its usage invoice into the Demo Company, as it does in a live organisation. Reported usage is never copied from your live organisation.

<Note>
  You advance the clock in the app, not through the API. A sandbox that has never been advanced runs on real time.
</Note>

***

## Reset the sandbox

A reset empties the sandbox and lets you copy fresh data from your live organisation. Go to **Developer Settings**, then **Configuration**, in the sandbox, and click <Badge>Reset Sandbox</Badge>.

| Kept | Removed |
| - | - |
| Test API keys | Customers |
| Test webhook endpoints | Subscriptions |
| The Demo Company connection and its default accounts | Invoices and credit notes |
| The API settings on the Configuration page: Create Xero Customers and Changes After Invoicing | Idempotency records, reported usage, past webhook events and deliveries |

A reset also puts the test clock back to real time. To change what the sandbox holds, reset it. Saasybill never merges new copies into existing data.

### If your Demo Company is reset

Xero wipes a Demo Company every 28 days, and you can reset it at any time. Saasybill sees this as a new Xero tenant. It doesn't delete the sandbox.

Reset your Demo Company in Xero, then connect it again in the sandbox's **Integrations**. Saasybill clears every Xero id it holds, such as contacts, invoices and account mappings, so nothing points into the old Demo Company. Your records stay. Copy your accounts again to re-map the plans.

***

## Test webhooks

Add webhook endpoints inside the sandbox in the same way as in a live organisation. Events from a sandbox have `livemode` set to `false`.

***

## Not available in a sandbox

Billing, users and invitations, deleting the organisation, removing the Xero connection, Setup Mode and automated customer emails are not available in a sandbox.

***

## Setup Mode

While a live organisation is in [Setup Mode](/settings/account), the API still creates subscriptions but doesn't raise invoices in Xero. A sandbox is never in Setup Mode.

* `POST /v1/subscriptions` returns `invoice: null`.
* `POST /v1/subscriptions/{id}/units` is refused with `422 setup_mode_on`.
* `start_date` can't be in the future. It is the previous renewal date of a subscription that is already running.

Check `setup_mode` and `livemode` on [the organisation](/api-reference/organisation/retrieve-the-organisation). They let your integration tell a live organisation, one that is still mirroring existing billing, and a sandbox apart.

***

## Test checklist

<Check>Call `GET /v1/organisation` with your test key. `livemode` is `false`.</Check>

<Check>Use a test key against a live organisation, or a live key against the sandbox. You get `403 api_key_mode_mismatch`.</Check>

<Check>Create a subscription, then send the same request again with the same `Idempotency-Key`. You get the same response and `Idempotent-Replayed: true`.</Check>

<Check>Send an unknown field. You get `422` and `param` names it.</Check>

<Check>Use a key without a scope and call an endpoint that needs it. You get `403 insufficient_scope`.</Check>

<Check>Increase units with proration, then decrease them. Confirm each `change` object matches what you expected.</Check>

<Check>Advance the test clock past a renewal. Confirm your integration sees the renewal invoice and the `subscription.updated` event.</Check>

<Check>Register a webhook endpoint, use <Badge>Send Test Event</Badge>, and confirm your signature check passes.</Check>

<Check>Let your webhook handler fail once. Confirm it copes with the retry, and with the same event arriving twice.</Check>

<Tip>
  Before you go live, swap in your live key and confirm `GET /v1/organisation` returns `livemode: true`.
</Tip>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.