Skip to main content
There is no sandbox yet. Every API key works against a real organisation, and a subscription you create raises a real invoice in that organisation’s Xero. The supported way to test is a second Saasybill organisation connected to a Xero Demo Company. It works today and bills nobody.
Never test with your production key. A test subscription creates a real invoice for a real customer.

Set up a test organisation

1

Create a second organisation

Create a new organisation in Saasybill, separate from your live one. It gets its own customers, plans and keys.
2

Connect it to a Xero Demo Company

Connect the new organisation to a Xero Demo Company and not to your real Xero organisation. Follow the same steps as in the Quickstart.
3

Add a plan and a customer

Create a plan, and import or create a customer, so your requests have something to bill.
4

Create a key in the test organisation

Open Developer Settings in the test organisation and create an API key. Use that key in your test environment.
Keep the test key and the live key in separate environment variables, so a deployment can’t mix them up.

Setup Mode

While an organisation is in Setup Mode, the API still creates subscriptions but doesn’t raise invoices in Xero.
  • 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 on the organisation. It lets your integration tell the difference between a live organisation and one that is still mirroring existing billing.

Test checklist

Create a subscription, then send the same request again with the same Idempotency-Key. You get the same response and Idempotent-Replayed: true.
Send an unknown field. You get 422 and param names it.
Use a key without a scope and call an endpoint that needs it. You get 403 insufficient_scope.
Increase units with proration, then decrease them. Confirm each change object matches what you expected.
Register a webhook endpoint, use Send Test Event, and confirm your signature check passes.
Let your webhook handler fail once. Confirm it copes with the retry, and with the same event arriving twice.