> ## 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.

# Objects

> Every object the API returns, field by field

Every object has an `id` and an `object` field naming its type. Formats are described in [Requests and responses](/api-reference/requests-and-responses#data-formats).

<Info>
  Money fields are decimal strings with four decimal places. Timestamps are ISO 8601 in UTC. Calendar dates are `YYYY-MM-DD` in the subscription's timezone.
</Info>

***

## Organisation

The organisation the API key belongs to. [Retrieve it](/api-reference/organisation/retrieve-the-organisation).

```json theme={null}
{
  "id": "7c3e9a1b-5d20-4f68-a4b7-8e6d2c0f9a99",
  "object": "organisation",
  "name": "Northwind Software",
  "timezone": "Australia/Sydney",
  "default_currency": "AUD",
  "setup_mode": false,
  "can_create_xero_contacts": true
}
```

| Field | Type | Description |
| - | - | - |
| `id` | string | The organisation's id. |
| `name` | string | The organisation's name. |
| `timezone` | string | The organisation's timezone. Dates you send are read in this timezone. |
| `default_currency` | string or null | The default currency code, such as `AUD`. |
| `setup_mode` | boolean | `true` while [Setup Mode](/settings/account) is on. No invoices are raised in Xero. |
| `can_create_xero_contacts` | boolean | Whether an owner or admin has allowed the API to create Xero contacts. |

***

## Customer

A customer, synced from a Xero contact. [Endpoints](/api-reference/customers/list-customers).

```json theme={null}
{
  "id": "3b9f1c1e-6a52-4c0e-9d7e-1f6f2f0b7a11",
  "object": "customer",
  "code": "ACME-001",
  "name": "Acme Pty Ltd",
  "company_name": "Acme Pty Ltd",
  "first_name": null,
  "last_name": null,
  "email": "accounts@acme.example",
  "status": "active",
  "xero_contact_id": "d5f2a8c1-6b73-4e09-8a1d-4c7e9b3f0a12",
  "created": "2026-08-14T02:31:08.000Z"
}
```

| Field | Type | Description |
| - | - | - |
| `id` | string | The Saasybill customer id. |
| `code` | string or null | Your own reference for the customer. Unique in the organisation. It is the contact number in Xero. |
| `name` | string | The display name: the company name, or the person's name. |
| `company_name` | string or null | The company name. |
| `first_name` | string or null | The contact's first name. |
| `last_name` | string or null | The contact's last name. |
| `email` | string or null | The customer's email address. |
| `status` | string | <Badge color="green">active</Badge> or <Badge color="red">inactive</Badge>. |
| `xero_contact_id` | string or null | The id of the contact in Xero. |
| `created` | timestamp | When the customer was added to Saasybill. |

<Note>
  A customer with no code can't be found by `customer_code`. Give the customer a code before your integration needs to look them up.
</Note>

***

## Plan

A pricing plan. [Endpoints](/api-reference/plans/list-plans). For how each type prices, see [Plans explained](/core/plans).

```json theme={null}
{
  "id": "b6c1e0a4-2f7d-4a61-8f0c-5d3e9a7b2c44",
  "object": "plan",
  "code": "TEAM-MONTHLY",
  "name": "Team",
  "type": "per_unit",
  "interval": { "unit": "month", "count": 1 },
  "currency": "AUD",
  "price": "12.0000",
  "minimum_units": 5,
  "free_units": 0,
  "unit_labels": { "singular": "seat", "plural": "seats" },
  "allows_price_override": false,
  "status": "active",
  "tiers": [],
  "created": "2026-06-02T23:10:44.000Z"
}
```

| Field | Type | Description |
| - | - | - |
| `id` | string | The plan id. |
| `code` | string | The plan's code. Unique in the organisation. |
| `name` | string | The plan's name. |
| `type` | string | `flat_fee`, `per_unit`, `tiered`, `volume` or `stairstep`. |
| `interval` | object | The billing period: `unit` is `day`, `week`, `month` or `year`, and `count` is how many of them. |
| `currency` | string | The plan's currency code. |
| `price` | string | The flat fee, or the per-unit price. On tiered, volume and stairstep plans, read the prices in `tiers`. |
| `minimum_units` | integer | The fewest units a subscription can have. |
| `free_units` | integer | Units included at no charge. |
| `unit_labels` | object | The `singular` and `plural` names of a unit, such as `seat` and `seats`. Either can be `null`. |
| `allows_price_override` | boolean | `true` when a flat fee subscription can set its own `flat_fee_price`. |
| `status` | string | `draft`, `active`, `inactive` or `legacy`. Only `active` and `draft` plans can be sold. |
| `tiers` | array | The price bands, ordered by `from_units`. Empty on flat fee and per unit plans. |
| `created` | timestamp | When the plan was created. |

### Plan types

| Type | How it prices |
| - | - |
| `flat_fee` | One price per period, whatever the units. Takes no `units`. |
| `per_unit` | A price multiplied by the units, less any free units. |
| `tiered` | Each band of units is priced at its own rate, and the bands add up. |
| `volume` | The band the total falls in sets one rate for every unit. |
| `stairstep` | The band the total falls in sets one price for the whole quantity. |

### Tier

| Field | Type | Description |
| - | - | - |
| `from_units` | integer | The first unit in the band. |
| `to_units` | integer or null | The last unit in the band. `null` for the top band, which has no limit. |
| `price` | string | The band's price. |

***

## Charge

A one-off fee that can be added to a new subscription. It bills once and doesn't recur. [Endpoints](/api-reference/charges/list-charges).

```json theme={null}
{
  "id": "e2a7d5c8-91b3-4d16-a0f4-7c8b6e5d3a22",
  "object": "charge",
  "code": "ONBOARDING",
  "name": "Onboarding",
  "description": "One-off setup and training",
  "currency": "AUD",
  "price": "450.0000",
  "allows_price_override": false,
  "status": "active",
  "created": "2026-06-02T23:14:09.000Z"
}
```

| Field | Type | Description |
| - | - | - |
| `id` | string | The charge id. Charges are sent on a subscription by id. |
| `code` | string | The charge's code. |
| `name` | string | The charge's name. |
| `description` | string or null | A description shown on the invoice line. |
| `currency` | string | The charge's currency. It must match the plan's. |
| `price` | string | The charge's price. |
| `allows_price_override` | boolean | `true` when a subscription can set its own `price` for this charge. |
| `status` | string | `draft`, `active`, `inactive` or `legacy`. |
| `created` | timestamp | When the charge was created. |

***

## Subscription

A customer's subscription to a plan. [Endpoints](/api-reference/subscriptions/list-subscriptions). For the lifecycle, see [Subscriptions explained](/core/subscriptions).

```json theme={null}
{
  "id": "9d4e2b7a-13c5-4f8e-b6a0-2e1d7c9f5b33",
  "object": "subscription",
  "customer": "3b9f1c1e-6a52-4c0e-9d7e-1f6f2f0b7a11",
  "customer_code": "ACME-001",
  "plan": "b6c1e0a4-2f7d-4a61-8f0c-5d3e9a7b2c44",
  "status": "active",
  "currency": "AUD",
  "interval": { "unit": "month", "count": 1 },
  "timezone": "Australia/Sydney",
  "start_date": "2026-09-30",
  "renewal_date": "2026-10-30",
  "end_date": null,
  "units": 10,
  "minimum_units": 5,
  "discount_percent": "10.00",
  "cancel_at_period_end": false,
  "end_after_cycles": null,
  "label": "Acme – Team plan",
  "invoice_reference": "PO-4471",
  "renewal_value": "108.0000",
  "created": "2026-09-30T04:12:00.000Z"
}
```

| Field | Type | Description |
| - | - | - |
| `id` | string | The subscription id. |
| `customer` | string | The customer's id. |
| `customer_code` | string or null | The customer's code. |
| `plan` | string | The plan's id. |
| `status` | string | `pending`, `active`, `complete` or `ended`. See below. |
| `currency` | string | The subscription's currency. |
| `interval` | object | The billing period, copied from the plan. |
| `timezone` | string | The subscription's timezone. Its dates are in this timezone. |
| `start_date` | date | When the subscription starts. |
| `renewal_date` | date or null | When it next renews. |
| `end_date` | date or null | When it ends, if it is set to end. |
| `units` | integer | The current number of units. `0` on flat fee plans. |
| `minimum_units` | integer | The minimum set on this subscription. `0` means the plan's minimum applies. A subscription can raise its plan's minimum, never lower it. |
| `discount_percent` | string | The discount, from `"0.00"` to `"100.00"`. |
| `cancel_at_period_end` | boolean | `true` when the subscription is set to end at its renewal date. |
| `end_after_cycles` | integer or null | The number of billing cycles before it ends. `null` for an ongoing subscription. |
| `label` | string or null | A label for you. |
| `invoice_reference` | string or null | The reference printed on each invoice, such as a purchase order number. |
| `renewal_value` | string | What the next renewal will bill, after discount. |
| `created` | timestamp | When the subscription was created. |

### Subscription status

| Status | Meaning |
| - | - |
| <Badge color="blue">pending</Badge> | Created with a future start date. The first invoice has been created. |
| <Badge color="green">active</Badge> | Live and billing. Renews automatically. |
| <Badge>complete</Badge> | Reached its scheduled end. |
| <Badge color="red">ended</Badge> | Stopped by request. Can be [restored](/api-reference/guides/end-and-restore) before its renewal date. |

<Note>
  A subscription set to end at period end stays `active` with `cancel_at_period_end: true` until its end date.
</Note>

***

## Invoice

An invoice raised in Xero. [Endpoints](/api-reference/invoices/list-invoices). Invoices are read-only in the API.

```json theme={null}
{
  "id": "5f8a3c9d-7e21-4b04-9c6d-0a2b4e8f1d55",
  "object": "invoice",
  "customer": "3b9f1c1e-6a52-4c0e-9d7e-1f6f2f0b7a11",
  "subscription": "9d4e2b7a-13c5-4f8e-b6a0-2e1d7c9f5b33",
  "number": "INV-0042",
  "reference": "PO-4471",
  "status": "awaiting_approval",
  "currency": "AUD",
  "invoice_date": "2026-09-29T14:00:00.000Z",
  "due_date": "2026-10-29T13:00:00.000Z",
  "subtotal": "558.0000",
  "total": "613.8000",
  "credit_note_amount": "0.0000",
  "amount_paid": null,
  "sent": false,
  "xero": {
    "sync_status": "synced",
    "invoice_id": "f0e9d8c7-b6a5-4f43-9210-fedcba987654",
    "sync_error": null
  },
  "lines": [
    {
      "id": "0a1b2c3d-4e5f-4a6b-8c7d-9e0f1a2b3c77",
      "type": "subscription",
      "name": "Team",
      "description": "Team – 10 seats",
      "units": 10,
      "amount": "120.0000",
      "discount_amount": "12.0000",
      "charge_amount": "108.0000",
      "effective_date": "2026-09-29T14:00:00.000Z"
    }
  ],
  "created": "2026-09-30T04:12:01.000Z"
}
```

| Field | Type | Description |
| - | - | - |
| `id` | string | The Saasybill invoice id. |
| `customer` | string | The customer's id. |
| `subscription` | string or null | The subscription that raised it. |
| `number` | string or null | Xero's invoice number, once the invoice is in Xero. |
| `reference` | string or null | The invoice reference. |
| `status` | string | The invoice's status. See below. |
| `currency` | string | The invoice's currency. |
| `invoice_date` | timestamp | The invoice date. |
| `due_date` | timestamp or null | The due date. |
| `subtotal` | string | The total excluding tax. |
| `total` | string | The total including tax, as Xero returns it. |
| `credit_note_amount` | string | Credit applied to the invoice. |
| `amount_paid` | string or null | The amount paid so far. |
| `sent` | boolean | Whether the invoice has been sent to the customer. |
| `xero` | object | Whether the invoice is in Xero. See below. |
| `lines` | array | The invoice's line items. |
| `created` | timestamp | When the invoice was created in Saasybill. |

### Invoice status

| Status | Meaning |
| - | - |
| `draft` | Created, not yet approved in Xero. |
| `awaiting_approval` | Ready to be approved in Xero. |
| `approved` | Approved and awaiting payment. |
| `paid` | Fully paid. |
| `voided` | Voided in Xero. |
| `deleted` | Deleted in Xero. |
| `scheduled` | Held for a later date. |
| `not_in_external` | Not in Xero. Check `xero.sync_status`. |

### Xero sync

| Field | Description |
| - | - |
| `xero.sync_status` | <Badge color="green">synced</Badge> the invoice is in Xero. <Badge color="yellow">pending</Badge> it hasn't reached Xero yet. <Badge color="red">failed</Badge> Xero refused it. |
| `xero.invoice_id` | The invoice's id in Xero. `null` until it is there. |
| `xero.sync_error` | Why Xero refused it. `null` unless `sync_status` is `failed`. |

### Invoice line

| Field | Type | Description |
| - | - | - |
| `id` | string | The line's id. |
| `type` | string or null | `subscription`, `addon` or `charge`. |
| `name` | string or null | The item's name. |
| `description` | string or null | The line's description. |
| `units` | integer or null | The units billed. `null` where the line has none, such as a charge. |
| `amount` | string | The amount before discount. |
| `discount_amount` | string | The discount taken off. |
| `charge_amount` | string | What is billed: `amount` less `discount_amount`. |
| `effective_date` | timestamp or null | When the line takes effect. |

<Info>
  On a subscription created through the API, a charge takes the subscription's discount only when you set `apply_discount` to `true` on that charge.
</Info>
