Skip to main content
For how customers work in the app, see Customers.
Xero is the source of truth for contacts. Saasybill syncs them as customers, and by default never creates one. The API can create a Xero contact, but only when the organisation has allowed it and your request asks for it.

The default: look up by code

Give each customer a code, which is their contact number in Xero. Your platform then finds them without storing Saasybill ids.
If a subscription request names a customer_code that doesn’t exist, the API answers 404 customer_not_found. It never creates a contact by accident, so a mistyped code can’t add a stray customer to your Xero.

Let the API create customers

Two things must both be true before the API creates a Xero contact.
1

The organisation allows it

An owner or admin turns on Create Xero Customers under Developer Settings, then API Keys. It is off by default. While it’s off, a request that asks to create a contact is refused with 403 xero_contact_creation_disabled. The setting shows as can_create_xero_contacts on the organisation.
2

The request asks for it

Nothing creates a contact implicitly. Two requests can ask.

Create a customer directly

POST /v1/customers needs the customers:write scope.

Create a customer while creating a subscription

Send create_customer next to customer_code. It is used only if no customer has that code.
create_customer needs customer_code. It is the code the new customer is created with.

What the API does, in order

POST /v1/customers follows these steps. Each is safe to repeat, so a retry never creates a second contact.
1

Look for a customer with that code

Found: return it with 200. Nothing is created.
2

Look in Xero for a contact whose contact number is the code

Found: adopt it as the customer and return it with 201. Nothing new is created in Xero.
3

Create the contact in Xero

Otherwise create a contact with the name, the email if you sent one, and the code as its contact number. Adopt it and return the customer with 201.
The status tells you which happened: 200 means the customer already existed, and 201 means it is new to Saasybill.

When it doesn’t work

Use your own stable account id as the customer code. Then a retry, or a second signup event for the same account, finds the customer that already exists.