# CustomerSubscription

A recurring agreement with one customer: what it covers, the interval it is billed at, when it started and when it is next invoiced. Its lines live on the items sub-resource, and the renewal run turns a due subscription into a sales invoice. A subscription with no next invoice date is never invoiced automatically.

## Used by
- GET /api/v2/customer-subscriptions: List customer subscriptions (CustomerSubscriptionList)
- POST /api/v2/customer-subscriptions: Create a customer subscription (CustomerSubscription)
- GET /api/v2/customer-subscriptions/{customer_subscription}: Read a customer subscription (CustomerSubscription)
- PATCH /api/v2/customer-subscriptions/{customer_subscription}: Update a customer subscription (CustomerSubscription)
- POST /api/v2/customer-subscriptions/{customer_subscription}/actions/restore: Restore a deleted customer subscription (CustomerSubscription)

## CustomerSubscription fields
- id (integer, required): Unique identifier.
- customer_id (integer, required): Customer this subscription belongs to.
- customer (Ref or CustomerSummary, required): The customer this subscription belongs to. Expanding it with `?include=customer` additionally requires the `customers::read` permission and a token scope covering the customers prefix.
- subscription_type_id (integer, required): Subscription type this subscription is an instance of.
- subscription_type (Ref or SubscriptionTypeSummary, required): The subscription type this subscription is an instance of, which is also where its displayed name comes from. Expanding it with `?include=subscription_type` additionally requires the `subscription_types::read` permission and a token scope covering the `subscription_types` prefix.
- description (string or null, required, multiline): What this subscription covers, as free text. This is the field `?q=` searches, and it is also what a generated invoice line falls back to.
- status (string, required): Lifecycle status. Only an active subscription is picked up by the renewal run; the other three are inert.
- billing_interval (string, required): How often the subscription is invoiced. one-time forces `auto_renew` to `false`, because a one-off has no next period to move on to.
- starts_at (date (YYYY-MM-DD), required): First day the subscription runs from, as a zone-free calendar date. Newest first is the default sort.
- next_invoice_date (date (YYYY-MM-DD) or null, required): First day of the period to be invoiced next. Omit it on create and the server fills it with `starts_at`, so the first period is billable; the renewal run advances it by one interval each time it invoices. Null makes the subscription invisible to that run (it is skipped, silently), so a subscription that should never auto-invoice is expressed this way.
- cancelled_at (date (YYYY-MM-DD) or null, required): Day the subscription was cancelled, `null` while it has not been. It is a record of the cancellation date only: nothing derives status from it.
- expires_at (date (YYYY-MM-DD) or null, required): Day the subscription runs out, `null` when it is open-ended.
- auto_renew (boolean, required): Whether the renewal run may invoice this subscription again. A one-time subscription is always `false`: it is forced on every save, so sending `true` together with `billing_interval=one-time` succeeds and comes back as `false` rather than failing.
- exact_subscription_id (string or null ≤ 255, required, server-assigned): Exact Online subscription this one maps to, by Exact's own external identifier, not by a local id. Written by the sync; `null` when the subscription has never been synced.
- last_invoiced_at (date (YYYY-MM-DD) or null, required, server-assigned): Day the subscription was last invoiced, `null` until it has been. Maintained by the renewal run.
- created_at (timestamp (YYYY-MM-DDThh:mm:ssZ), required): Creation timestamp.
- updated_at (timestamp (YYYY-MM-DDThh:mm:ssZ), required): Last-write timestamp; use for incremental sync. It also feeds the `ETag` revision, because a customer subscription has no `version` field.
- deleted_at (timestamp (YYYY-MM-DDThh:mm:ssZ) or null, required): Soft-delete timestamp, `null` while live.
- items_count (integer ≥ 0, required): Number of lines on this subscription.
- links (CustomerSubscriptionLinks, required)
  - self (url, required): The canonical URI of this record.
  - items (url, required): Lines on this subscription.

## Variants

### CustomerSubscriptionList

What a collection returns, and what `?view=summary` returns on a single record.

20 fields.
Identical to the detail object above.

### CustomerSubscriptionSummary

The embedded form: what you get when another resource carries this one and you did not `include` it.

3 fields.
Omits: customer, subscription_type_id, subscription_type, description, status, billing_interval, next_invoice_date, cancelled_at, expires_at, auto_renew, exact_subscription_id, last_invoiced_at, created_at, updated_at, deleted_at, items_count, links

### CustomerSubscriptionLinks

The `links` object on this resource.

Keys: self, items

## Example
```json
{
  "id": 1,
  "customer_id": 1,
  "customer": {
    "id": 1
  },
  "subscription_type_id": 1,
  "subscription_type": {
    "id": 1
  },
  "description": "Managed hosting and maintenance.",
  "status": "pending",
  "billing_interval": "yearly",
  "starts_at": "2026-07-01",
  "next_invoice_date": "2026-03-04",
  "cancelled_at": "2026-03-04",
  "expires_at": "2026-03-04",
  "auto_renew": true,
  "exact_subscription_id": "…",
  "last_invoiced_at": "2026-03-04",
  "created_at": "2026-03-04T09:15:00Z",
  "updated_at": "2026-03-04T09:15:00Z",
  "deleted_at": "2026-03-04T09:15:00Z",
  "items_count": 1,
  "links": {
    "self": "https://<your-url>/api/v2/work-items/1",
    "items": "https://<your-url>/api/v2/work-items/1"
  }
}
```
