# Subscriptions

> A customer's recurring commitment to one or more prices, billed at the end of each period.

Source: https://docs.borga.is/api/subscriptions

See the [subscriptions guide](/billing/subscriptions) for the billing model, trials and dunning.

**The subscription object**

- `id` (string): Prefixed `sub_`.
- `object` (string): `subscription`
- `customer` (string): <Param name="status" type="enum">`trialing`, `active`, `past_due`, `unpaid`, `canceled` or `paused`.
- `collection_method` (enum): `charge_automatically` (saved card) or `send_invoice` (bank invoice).
- `days_until_due` (integer | null): For `send_invoice`.
- `current_period_start` (timestamp): <Param name="current_period_end" type="timestamp">When the next invoice is issued.
- `cancel_at_period_end` (boolean): - `canceled_at` (timestamp | null) - `ended_at` (timestamp | null) - `trial_start` (timestamp | null) - `trial_end` (timestamp | null) - `pause_collection` (object | null) <Param name="discount" type="object | null">`amount_off` or `percent_off`, `duration`.
- `items` (array): [Subscription items](/api/subscription-items).
- `metadata` (object): - `created_at` (timestamp) - `updated_at` (timestamp) ## Create a subscription `POST /v1/subscriptions` The customer needs a default payment method for `charge_automatically`, or a kennitala for `send_invoice`. All items must share an interval and a currency, and at least one must be recurring. **Body** - `customer` (string) <Param name="items" type="array" required>One or more `{ price, quantity?, credit_rollover?, included_units?, metadata? }`.
- `collection_method` (enum, default charge_automatically): `charge_automatically` or `send_invoice`.
- `trial_period_days` (integer): Free days before the first paid period.
- `days_until_due` (integer): For `send_invoice`: days the customer has to pay each invoice.
- `discount` (object): `{ amount_off?, percent_off?, duration: "once" }`.
- `metadata` (object):  ```ts Node.js // The customer already has a saved card (payment_method.attached fired). const subscription = await borga.subscriptions.create({ customer: "cus_8Jk2Lm4Np6Qr8St0Uv2Wx4Yz", items: [{ price: "price_2Ab4Cd6Ef8Gh0Ij2Kl4Mn6Op", quantity: 3 }], collection_method: "charge_automatically", trial_period_days: 14, metadata: { plan: "pro" }, }); console.log(subscription.status); // "trialing" console.log(subscription.current_period_end); ``` ```bash curl curl https://api.borga.is/v1/subscriptions \ -H "Authorization: Bearer sk_test_…" \ -H "Content-Type: application/json" \ -d '{ "customer": "cus_8Jk2Lm4Np6Qr8St0Uv2Wx4Yz", "items": [{ "price": "price_2Ab4Cd6Ef8Gh0Ij2Kl4Mn6Op", "quantity": 3 }], "collection_method": "charge_automatically", "trial_period_days": 14 }' ```  ```json title="Response" { "id": "sub_9Qw1Er3Ty5Ui7Op9As1Df3Gh", "object": "subscription", "customer": "cus_8Jk2Lm4Np6Qr8St0Uv2Wx4Yz", "status": "trialing", "collection_method": "charge_automatically", "days_until_due": null, "current_period_start": "2026-09-07T12:00:00.000Z", "current_period_end": "2026-09-21T12:00:00.000Z", "cancel_at_period_end": false, "canceled_at": null, "ended_at": null, "trial_start": "2026-09-07T12:00:00.000Z", "trial_end": "2026-09-21T12:00:00.000Z", "pause_collection": null, "discount": null, "metadata": { "plan": "pro" }, "items": [ { "id": "si_5Zx7Cv9Bn1Mq3We5Rt7Yu9Io", "object": "subscription_item", "subscription": "sub_9Qw1Er3Ty5Ui7Op9As1Df3Gh", "price": "price_2Ab4Cd6Ef8Gh0Ij2Kl4Mn6Op", "quantity": 3, "credit_rollover": false, "included_units": null, "metadata": {}, "created_at": "2026-09-07T12:00:00.000Z", "updated_at": "2026-09-07T12:00:00.000Z" } ], "created_at": "2026-09-07T12:00:00.000Z", "updated_at": "2026-09-07T12:00:00.000Z" } ``` Errors: [`invalid_subscription`](/errors/invalid_subscription), [`invalid_price_type`](/errors/invalid_price_type), [`resource_not_found`](/errors/resource_not_found). ## Retrieve a subscription `GET /v1/subscriptions/:id` ## Update a subscription `POST /v1/subscriptions/:id` Change items through [subscription items](/api/subscription-items). **Body** - `cancel_at_period_end` (boolean) <Param name="discount" type="object | null">Set a discount or `null` to remove it.
- `collection_method` (enum): - `days_until_due` (integer) - `metadata` (object) ## Cancel a subscription `POST /v1/subscriptions/:id/cancel` **Body** <Param name="at_period_end" type="boolean" default="false">`true` keeps the subscription active until `current_period_end`, bills the final period, then cancels. `false` ends it immediately.

## Uncancel a subscription

`POST /v1/subscriptions/:id/uncancel`

Clears `cancel_at_period_end`. Fails with [`cannot_uncancel`](/errors/cannot_uncancel) if no cancellation is pending.

## Pause a subscription

`POST /v1/subscriptions/:id/pause`

Stops billing. Fails with [`cannot_pause`](/errors/cannot_pause) unless the subscription is `active` or `trialing`.

## Resume a subscription

`POST /v1/subscriptions/:id/resume`

Fails with [`not_paused`](/errors/not_paused) if the subscription is not paused.

## List subscriptions

`GET /v1/subscriptions`

**Query parameters**

- `customer` (string)
- `status` (enum)
- `limit` (integer)
- `starting_after` (string)

```ts Node.js
const id = "sub_9Qw1Er3Ty5Ui7Op9As1Df3Gh";

// Change seats; Borga prorates the difference on the next invoice.
const [item] = (await borga.subscriptions.retrieve(id)).items;
await borga.subscriptionItems.update(item.id, {
  quantity: 5,
  proration_behavior: "create_prorations",
});

// Add a one-off charge to the next invoice.
await borga.invoiceItems.create({
  customer: "cus_8Jk2Lm4Np6Qr8St0Uv2Wx4Yz",
  subscription: id,
  amount: 15000,
  description: "Onboarding workshop",
});

// Cancel when the period ends (reversible with uncancel).
await borga.subscriptions.cancel(id, { at_period_end: true });
await borga.subscriptions.uncancel(id);

// Pause and resume billing.
await borga.subscriptions.pause(id);
await borga.subscriptions.resume(id);
```
