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

# Quickstart

> Create an API key, check your connection, and bill your first subscription

This walkthrough takes you from no key to a subscription with an invoice in Xero. Each step is one request.

<Info>
  You need a Saasybill organisation connected to Xero, with at least one plan and one customer. If you are testing, read [Testing](/api-reference/testing) first and use a Xero Demo Company.
</Info>

***

## Before you start

<Steps>
  <Step title="Create an API key">
    Only an owner or admin can create keys.

    1. Open **Organisation Settings** and go to **Developer Settings**, then **API Keys**.
    2. Click <Badge>Create API Key</Badge>.
    3. Enter a **Name**, such as `Signup integration`.
    4. Choose the **Permissions** the key needs. For this walkthrough, select all of them.
    5. Choose when the key **Expires**, or choose **Never**.
    6. Click <Badge>Create Key</Badge>.

    Copy the key from the **Your New API Key** dialog. It is shown once and cannot be retrieved later.
  </Step>

  <Step title="Store it as an environment variable">
    Keep the key out of your code and your repository.

    ```bash theme={null}
    export SAASYBILL_API_KEY="saasybill_live_…"
    ```
  </Step>
</Steps>

***

## Make your first subscription

<Steps>
  <Step title="Check the connection">
    Retrieve the organisation. A `200` response confirms the key works.

    ```bash theme={null}
    curl https://app.saasybill.com/api/v1/organisation \
      -H "Authorization: Bearer $SAASYBILL_API_KEY"
    ```

    Note `setup_mode`. While it is `true`, Saasybill creates subscriptions but does not raise invoices in Xero.
  </Step>

  <Step title="Find the plan">
    Look up the plan by the code you gave it in the app.

    ```bash theme={null}
    curl "https://app.saasybill.com/api/v1/plans?code=TEAM-MONTHLY" \
      -H "Authorization: Bearer $SAASYBILL_API_KEY"
    ```

    ```json Response theme={null}
    {
      "data": [
        {
          "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"
        }
      ],
      "has_more": false
    }
    ```
  </Step>

  <Step title="Find the customer">
    Customers come from Xero. Look one up by the code you use for them.

    ```bash theme={null}
    curl "https://app.saasybill.com/api/v1/customers?code=ACME-001" \
      -H "Authorization: Bearer $SAASYBILL_API_KEY"
    ```

    If the customer doesn't exist yet, see [Customers and Xero](/api-reference/guides/customers-and-xero).
  </Step>

  <Step title="Create the subscription">
    Send the customer, the plan and the units. The `Idempotency-Key` is required. Use an id from your own system, such as the signup id, so a retry can never bill twice.

    ```bash theme={null}
    curl https://app.saasybill.com/api/v1/subscriptions \
      -H "Authorization: Bearer $SAASYBILL_API_KEY" \
      -H "Content-Type: application/json" \
      -H "Idempotency-Key: signup_8f3a2c1d" \
      -d '{
        "customer_code": "ACME-001",
        "plan_code": "TEAM-MONTHLY",
        "units": 10,
        "discount_percent": "10",
        "invoice_reference": "PO-4471"
      }'
    ```

    ```json Response (trimmed) theme={null}
    {
      "id": "9d4e2b7a-13c5-4f8e-b6a0-2e1d7c9f5b33",
      "object": "subscription",
      "status": "active",
      "units": 10,
      "renewal_date": "2026-10-30",
      "renewal_value": "108.0000",
      "invoice": {
        "id": "5f8a3c9d-7e21-4b04-9c6d-0a2b4e8f1d55",
        "object": "invoice",
        "number": "INV-0042",
        "status": "awaiting_approval",
        "xero": { "sync_status": "synced", "invoice_id": "f0e9d8c7-b6a5-4f43-9210-fedcba987654", "sync_error": null }
      }
    }
    ```
  </Step>

  <Step title="Check the invoice reached Xero">
    Read `invoice.xero.sync_status`. `synced` means the invoice is in Xero. `failed` means Xero refused it, but the subscription still exists. See [Create a subscription](/api-reference/guides/create-a-subscription#check-the-invoice).
  </Step>

  <Step title="Change the units">
    When the customer adds seats, send the new total, not the difference.

    ```bash theme={null}
    curl https://app.saasybill.com/api/v1/subscriptions/9d4e2b7a-13c5-4f8e-b6a0-2e1d7c9f5b33/units \
      -H "Authorization: Bearer $SAASYBILL_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{
        "units": 15,
        "prorate": true,
        "proration_behaviour": "charge_immediately",
        "effective_date": "2026-10-08"
      }'
    ```

    The response's `change` object says what Saasybill did. See [Change units](/api-reference/guides/change-units).
  </Step>
</Steps>

***

## Next steps

<CardGroup cols={2}>
  <Card title="Create a subscription" icon="plus" href="/api-reference/guides/create-a-subscription">
    Every option, with request bodies for common cases.
  </Card>

  <Card title="Set up webhooks" icon="bell" href="/api-reference/webhooks/overview">
    Hear about paid invoices without polling.
  </Card>

  <Card title="Handle errors" icon="triangle-exclamation" href="/api-reference/errors">
    Branch on error codes, not messages.
  </Card>

  <Card title="Retry safely" icon="rotate" href="/api-reference/idempotency">
    How idempotency keys protect against double billing.
  </Card>
</CardGroup>
