# Create a subscription

> The subscriptions.create operation: POST /api/v1/subscriptions in the REST API and the subscriptions_create tool in the MCP server.

Starts a subscription of a customer to one or more recurring prices (spec §16.2). The prices must share a
currency, and their intervals must be whole multiples of each other (monthly with yearly). A customer has at
most one live item per metered price's meter.

- **Trial:** `trialEnd`, else `trialDays` (0 = none), else the prices' shortest trial. The subscription is
  `trialing` and nothing is invoiced until the trial ends; free plans have no trial.
- **Free plans** (only zero-amount licensed prices) are `active` at once, with no invoice and no payment method.
- **First invoice:** licensed items for the first period, with the coupon or promotion code applied, taxed now
  with the customer's stored location evidence (a new sale: a blocked location is refused). A later
  `billingCycleAnchor` bills a prorated first period (`prorationBehavior: none` bills nothing until then). A
  zero total isn't issued.
- **Collection:** `charge_automatically` charges the invoice to the customer's saved payment method
  (`paymentMethodId`, else their default): the subscription is `incomplete` until the payment succeeds (23
  hours at most). Without a saved payment method the answer carries `paymentSetup.url`, a hosted checkout in
  setup mode where the customer saves one; the first invoice is charged right after. `send_invoice` emails the
  invoice with the bank transfer details and is `active` at once.

Emits `subscription.created` (and `invoice.issued`/`invoice.finalized` for the first invoice); the customer's
entitlements are recomputed. Dry-run it to see the first invoice before charging anyone.

## At a glance

- **REST:** `POST /api/v1/subscriptions`
- **MCP tool:** `subscriptions_create`
- **Operation ID:** `subscriptions.create`
- **Scope:** Brand
- **Permission:** `subscriptions:write`
- **Risk tier:** `financial`
- **Dry run:** Supported (send `Ownrecord-Dry-Run: true`)
- **Idempotency:** `Idempotency-Key` required
- **Modes:** Test and live
- **Plan feature:** `subscriptions.enabled`
- **Authentication:** API key with the `subscriptions:write` scope
- **Since:** M5

## Request

### Body

A JSON object (`Content-Type: application/json`):

| Field                     | Type                                                                          | Required | Description                                                                                                                                                                                 |
| ------------------------- | ----------------------------------------------------------------------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `customerId`              | `cus_…` ID                                                                    | Yes      | The customer (`cus_…`).                                                                                                                                                                     |
| `items`                   | array of object                                                               | Yes      | The recurring prices: one currency; intervals that are whole multiples of each other.                                                                                                       |
| `items[].priceId`         | `price_…` ID                                                                  | Yes      | A recurring price (`price_…`).                                                                                                                                                              |
| `items[].quantity`        | integer (1 to 1000000)                                                        | No       | Seats or units of a licensed price (1 to 1,000,000). Metered prices take no quantity.                                                                                                       |
| `collectionMethod`        | one of `charge_automatically`, `send_invoice`                                 | No       | `charge_automatically` (the default payment method is charged) or `send_invoice` (the invoice is emailed with bank transfer details and paid by the due date).                              |
| `daysUntilDue`            | integer (0 to 365)                                                            | No       | `send_invoice`: days from an invoice's issue date to its due date (default 14).                                                                                                             |
| `trialDays`               | integer (0 to 730)                                                            | No       | Trial days (0 = no trial). Default: the shortest trial of the prices.                                                                                                                       |
| `trialEnd`                | date-time                                                                     | No       | When the trial ends (instead of `trialDays`).                                                                                                                                               |
| `trialEndBehavior`        | one of `convert`, `cancel_if_no_payment_method`, `pause_if_no_payment_method` | No       | What happens at the trial's end without a payment method: `convert` (bill anyway), `cancel_if_no_payment_method` or `pause_if_no_payment_method`.                                           |
| `couponId`                | `cpn_…` ID                                                                    | No       | A coupon to apply (`cpn_…`).                                                                                                                                                                |
| `promotionCode`           | string                                                                        | No       | A promotion code as the customer typed it (case doesn't matter).                                                                                                                            |
| `billingCycleAnchor`      | date-time                                                                     | No       | When the first full period starts (default: now, or the trial's end). A later anchor bills a prorated first period.                                                                         |
| `prorationBehavior`       | one of `create_prorations`, `always_invoice`, `none`                          | No       | With a later `billingCycleAnchor`: `create_prorations` and `always_invoice` charge the partial first period now; `none` bills nothing until the anchor.                                     |
| `paymentMethodId`         | `pm_…` ID                                                                     | No       | A saved payment method of the customer (`pm_…`); default: the customer's default method.                                                                                                    |
| `setupSuccessUrl`         | string                                                                        | No       | Without a payment method (`charge_automatically`): where the setup checkout sends the customer after saving one.                                                                            |
| `usageThreshold`          | object                                                                        | No       | Invoice metered usage as soon as what it would charge reaches this amount (spec §16.7): limits the credit risk of usage-heavy customers. In the subscription's currency, whole minor units. |
| `usageThreshold.amount`   | string                                                                        | Yes      | Integer micros as a string (12500000 = 12.50).                                                                                                                                              |
| `usageThreshold.currency` | string                                                                        | Yes      | ISO 4217 currency code: the price's currency.                                                                                                                                               |
| `metadata`                | object                                                                        | No       | Your own key-value pairs (at most 50 keys). On updates the whole set is replaced.                                                                                                           |

## Response

`201 Created` with a JSON object:

| Field                    | Type                                                                                                        | Description                                                                                                                                                    |
| ------------------------ | ----------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `id`                     | `sub_…` ID                                                                                                  |                                                                                                                                                                |
| `object`                 | `"subscription"`                                                                                            |                                                                                                                                                                |
| `livemode`               | boolean                                                                                                     |                                                                                                                                                                |
| `entityId`               | `ent_…` ID                                                                                                  |                                                                                                                                                                |
| `brandId`                | `brd_…` ID                                                                                                  |                                                                                                                                                                |
| `customerId`             | `cus_…` ID                                                                                                  |                                                                                                                                                                |
| `status`                 | one of `incomplete`, `incomplete_expired`, `trialing`, `active`, `past_due`, `unpaid`, `paused`, `canceled` | `incomplete` (waiting for the first payment, 23 hours), `trialing`, `active`, `past_due`, `unpaid`, `paused`, `canceled` or `incomplete_expired` (spec §16.1). |
| `items`                  | array of object                                                                                             |                                                                                                                                                                |
| `items[].id`             | `si_…` ID                                                                                                   |                                                                                                                                                                |
| `items[].priceId`        | `price_…` ID                                                                                                |                                                                                                                                                                |
| `items[].productId`      | `prod_…` ID                                                                                                 |                                                                                                                                                                |
| `items[].quantity`       | integer                                                                                                     |                                                                                                                                                                |
| `items[].createdAt`      | date-time                                                                                                   |                                                                                                                                                                |
| `currency`               | string                                                                                                      |                                                                                                                                                                |
| `mrr`                    | money or null                                                                                               | The items' monthly recurring amount (licensed items, before discounts and tax).                                                                                |
| `collectionMethod`       | one of `charge_automatically`, `send_invoice`                                                               |                                                                                                                                                                |
| `daysUntilDue`           | integer or null                                                                                             |                                                                                                                                                                |
| `defaultPaymentMethodId` | `pm_…` ID or null                                                                                           |                                                                                                                                                                |
| `billingCycleAnchor`     | date-time                                                                                                   |                                                                                                                                                                |
| `currentPeriodStart`     | date-time                                                                                                   |                                                                                                                                                                |
| `currentPeriodEnd`       | date-time                                                                                                   |                                                                                                                                                                |
| `trialStart`             | date-time or null                                                                                           |                                                                                                                                                                |
| `trialEnd`               | date-time or null                                                                                           |                                                                                                                                                                |
| `trialEndBehavior`       | one of `convert`, `cancel_if_no_payment_method`, `pause_if_no_payment_method`                               |                                                                                                                                                                |
| `cancelAtPeriodEnd`      | boolean                                                                                                     |                                                                                                                                                                |
| `cancelAt`               | date-time or null                                                                                           |                                                                                                                                                                |
| `canceledAt`             | date-time or null                                                                                           |                                                                                                                                                                |
| `endedAt`                | date-time or null                                                                                           |                                                                                                                                                                |
| `cancellation`           | object or null                                                                                              |                                                                                                                                                                |
| `pause`                  | object or null                                                                                              |                                                                                                                                                                |
| `discountIds`            | array of `disc_…` ID                                                                                        |                                                                                                                                                                |
| `pendingUpdate`          | object or null                                                                                              |                                                                                                                                                                |
| `latestInvoiceId`        | `inv_…` ID or null                                                                                          |                                                                                                                                                                |
| `incompleteExpiresAt`    | date-time or null                                                                                           |                                                                                                                                                                |
| `testClockId`            | `clk_…` ID or null                                                                                          |                                                                                                                                                                |
| `dunning`                | object or null                                                                                              | Dunning (§16.10) while past due or unpaid; null otherwise.                                                                                                     |
| `usageThreshold`         | money or null                                                                                               | Unbilled metered usage worth this much is invoiced at once (spec §16.7).                                                                                       |
| `entitlementGraceUntil`  | date-time or null                                                                                           |                                                                                                                                                                |
| `metadata`               | object                                                                                                      |                                                                                                                                                                |
| `version`                | integer                                                                                                     |                                                                                                                                                                |
| `createdAt`              | date-time                                                                                                   |                                                                                                                                                                |
| `updatedAt`              | date-time                                                                                                   |                                                                                                                                                                |
| `paymentSetup`           | object or null                                                                                              | `charge_automatically` without a saved payment method: the checkout URL in setup mode (spec §16.2).                                                            |

## Examples

### Three seats and metered API calls, charged to the saved card

```http
POST /api/v1/subscriptions
Authorization: Bearer or_test_…
Idempotency-Key: 3f1c9a52-7d0e-4b8f-9a61-0c2d5e8b7f14
Content-Type: application/json

{
  "customerId": "cus_01m4tx5nj8emwbyf7y9vcf47z4",
  "items": [
    {
      "priceId": "price_01m4tx5nj8emwbyf7y9vcf47y2",
      "quantity": 3
    },
    {
      "priceId": "price_01m4tx5nj8emwbyf7y9vcf47y9"
    }
  ],
  "metadata": {
    "crm_account": "A-1042"
  }
}
```

Response (`201`):

```json
{
  "id": "sub_01m4tx5nj8emwbyf7y9vcf47z5",
  "object": "subscription",
  "livemode": false,
  "entityId": "ent_01m4tx5nj8emwbyf7y9vcf47zm",
  "brandId": "brd_01m4tx5nj8emwbyf7y9vcf47x4",
  "customerId": "cus_01m4tx5nj8emwbyf7y9vcf47z4",
  "status": "incomplete",
  "items": [
    {
      "id": "si_01m4tx5nj8emwbyf7y9vcf47za",
      "priceId": "price_01m4tx5nj8emwbyf7y9vcf47y2",
      "productId": "prod_01m4tx5nj8emwbyf7y9vcf47y0",
      "quantity": 3,
      "createdAt": "2026-10-13T12:00:00.000Z"
    },
    {
      "id": "si_01m4tx5nj8emwbyf7y9vcf47zb",
      "priceId": "price_01m4tx5nj8emwbyf7y9vcf47y9",
      "productId": "prod_01m4tx5nj8emwbyf7y9vcf47y1",
      "quantity": 1,
      "createdAt": "2026-10-13T12:00:00.000Z"
    }
  ],
  "currency": "EUR",
  "mrr": {
    "amount": "87000000",
    "currency": "EUR"
  },
  "collectionMethod": "charge_automatically",
  "daysUntilDue": null,
  "defaultPaymentMethodId": "pm_01m4tx5nj8emwbyf7y9vcf47zd",
  "billingCycleAnchor": "2026-10-13T12:00:00.000Z",
  "currentPeriodStart": "2026-10-13T12:00:00.000Z",
  "currentPeriodEnd": "2026-11-13T12:00:00.000Z",
  "trialStart": null,
  "trialEnd": null,
  "trialEndBehavior": "convert",
  "cancelAtPeriodEnd": false,
  "cancelAt": null,
  "canceledAt": null,
  "endedAt": null,
  "cancellation": null,
  "pause": null,
  "discountIds": [],
  "pendingUpdate": null,
  "latestInvoiceId": "inv_01m4tx5nj8emwbyf7y9vcf47zn",
  "incompleteExpiresAt": "2026-10-14T11:00:00.000Z",
  "testClockId": null,
  "dunning": null,
  "usageThreshold": null,
  "entitlementGraceUntil": null,
  "metadata": {
    "crm_account": "A-1042"
  },
  "version": 2,
  "createdAt": "2026-10-13T12:00:00.000Z",
  "updatedAt": "2026-10-13T12:00:00.000Z",
  "paymentSetup": null
}
```

### A 14-day trial without a saved card

The trial starts at once; `paymentSetup.url` lets the customer add a card before it ends.

```http
POST /api/v1/subscriptions
Authorization: Bearer or_test_…
Idempotency-Key: 3f1c9a52-7d0e-4b8f-9a61-0c2d5e8b7f14
Content-Type: application/json

{
  "customerId": "cus_01m4tx5nj8emwbyf7y9vcf47z4",
  "items": [
    {
      "priceId": "price_01m4tx5nj8emwbyf7y9vcf47y2",
      "quantity": 3
    }
  ],
  "trialDays": 14
}
```

Response (`201`):

```json
{
  "id": "sub_01m4tx5nj8emwbyf7y9vcf47z5",
  "object": "subscription",
  "livemode": false,
  "entityId": "ent_01m4tx5nj8emwbyf7y9vcf47zm",
  "brandId": "brd_01m4tx5nj8emwbyf7y9vcf47x4",
  "customerId": "cus_01m4tx5nj8emwbyf7y9vcf47z4",
  "status": "trialing",
  "items": [
    {
      "id": "si_01m4tx5nj8emwbyf7y9vcf47za",
      "priceId": "price_01m4tx5nj8emwbyf7y9vcf47y2",
      "productId": "prod_01m4tx5nj8emwbyf7y9vcf47y0",
      "quantity": 3,
      "createdAt": "2026-10-13T12:00:00.000Z"
    },
    {
      "id": "si_01m4tx5nj8emwbyf7y9vcf47zb",
      "priceId": "price_01m4tx5nj8emwbyf7y9vcf47y9",
      "productId": "prod_01m4tx5nj8emwbyf7y9vcf47y1",
      "quantity": 1,
      "createdAt": "2026-10-13T12:00:00.000Z"
    }
  ],
  "currency": "EUR",
  "mrr": {
    "amount": "87000000",
    "currency": "EUR"
  },
  "collectionMethod": "charge_automatically",
  "daysUntilDue": null,
  "defaultPaymentMethodId": null,
  "billingCycleAnchor": "2026-10-27T12:00:00.000Z",
  "currentPeriodStart": "2026-10-13T12:00:00.000Z",
  "currentPeriodEnd": "2026-10-27T12:00:00.000Z",
  "trialStart": "2026-10-13T12:00:00.000Z",
  "trialEnd": "2026-10-27T12:00:00.000Z",
  "trialEndBehavior": "convert",
  "cancelAtPeriodEnd": false,
  "cancelAt": null,
  "canceledAt": null,
  "endedAt": null,
  "cancellation": null,
  "pause": null,
  "discountIds": [],
  "pendingUpdate": null,
  "latestInvoiceId": null,
  "incompleteExpiresAt": null,
  "testClockId": null,
  "dunning": null,
  "usageThreshold": null,
  "entitlementGraceUntil": null,
  "metadata": {
    "crm_account": "A-1042"
  },
  "version": 1,
  "createdAt": "2026-10-13T12:00:00.000Z",
  "updatedAt": "2026-10-13T12:00:00.000Z",
  "paymentSetup": {
    "checkoutSessionId": "cs_01m4tx5nj8emwbyf7y9vcf47zj",
    "url": "https://ownrecord.io/c/genno/cs_01m4tx5nj8emwbyf7y9vcf47zj?key=example",
    "expiresAt": "2026-10-14T12:00:00.000Z",
    "required": false
  }
}
```

## Errors

| Code                                                                                                                       | HTTP status | When                                                                                                           | What to do                                                                                                                                                                                                |
| -------------------------------------------------------------------------------------------------------------------------- | ----------- | -------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| [`validation_failed`](https://ownrecord.io/docs/reference/errors.md#validation_failed)                                     | 400         | A field is malformed or out of range.                                                                          | Fix the fields listed in `details.issues` and send the request again.                                                                                                                                     |
| [`resource_not_found`](https://ownrecord.io/docs/reference/errors.md#resource_not_found)                                   | 404         | No subscription (or customer, price, coupon) with this ID is visible to the request.                           | Check the ID and that your credentials are scoped to the right organization, entity, brand and mode.                                                                                                      |
| [`customer_deleted`](https://ownrecord.io/docs/reference/errors.md#customer_deleted)                                       | 400         | The customer was deleted.                                                                                      | Create a new customer for this buyer. Deleted customers stay readable for the records they belong to, but can't be changed.                                                                               |
| [`subscription_price_invalid`](https://ownrecord.io/docs/reference/errors.md#subscription_price_invalid)                   | 400         | A price isn't recurring, is archived, is in another currency, or its interval doesn't combine with the others. | Use active recurring prices of one currency whose intervals are whole multiples of each other (monthly with yearly, weekly with 2-weekly). `details.reason` says what's wrong and `param` names the item. |
| [`subscription_meter_conflict`](https://ownrecord.io/docs/reference/errors.md#subscription_meter_conflict)                 | 409         | The customer already has a live subscription item for a metered price's meter.                                 | Change the existing subscription's metered item instead, or cancel it first. A customer has at most one active metered item per meter.                                                                    |
| [`subscription_payment_method_invalid`](https://ownrecord.io/docs/reference/errors.md#subscription_payment_method_invalid) | 400         | `paymentMethodId` isn't a saved, attached payment method of the customer.                                      | Use a saved payment method (`pm_…`) of the subscription's customer that isn't detached, or leave it out to use the customer's default.                                                                    |
| [`subscription_anchor_invalid`](https://ownrecord.io/docs/reference/errors.md#subscription_anchor_invalid)                 | 400         | `billingCycleAnchor` is before the start or too far ahead.                                                     | Set `billingCycleAnchor` after the subscription starts (after the trial, if any) and at most one of its longest interval later, or leave it out to bill from the start.                                   |
| [`coupon_not_redeemable`](https://ownrecord.io/docs/reference/errors.md#coupon_not_redeemable)                             | 409         | The coupon is archived, expired or used up.                                                                    | Check `details.reason`: reactivate an archived coupon, or create a new coupon when it expired or reached its redemption limit.                                                                            |
| [`promotion_code_not_redeemable`](https://ownrecord.io/docs/reference/errors.md#promotion_code_not_redeemable)             | 409         | The promotion code can't be used for this customer or amount (`details.reason`).                               | Check `details.reason` and tell the customer: the code may have expired, be used up, belong to another customer, need a larger purchase or be for first-time customers only.                              |
| [`registration_required`](https://ownrecord.io/docs/reference/errors.md#registration_required)                             | 422         | An invoice issued now can't be taxed: the seller isn't registered where the customer is (a new sale).          | Register the entity for the regime named in `details.regime` (see its prerequisites and deadline), or arm the jurisdiction once the prerequisites are done. The customer can join the waitlist meanwhile. |
| [`jurisdiction_blocked`](https://ownrecord.io/docs/reference/errors.md#jurisdiction_blocked)                               | 422         | The customer's location is blocked for new sales.                                                              | This jurisdiction isn't covered by usable tax knowledge for this seller. Contact support if you need to sell there.                                                                                       |
| [`evidence_conflict`](https://ownrecord.io/docs/reference/errors.md#evidence_conflict)                                     | 422         | The customer's stored location evidence isn't enough to tax an invoice issued now (§13.3).                     | Collect another piece of location evidence (billing address, card country, or the customer's confirmation of their country) and quote again.                                                              |
| [`invoice_bank_transfer_missing`](https://ownrecord.io/docs/reference/errors.md#invoice_bank_transfer_missing)             | 409         | `send_invoice`: the entity has no bank transfer details to put on the first invoice.                           | Add the IBAN, BIC, bank name and account holder in the entity's invoice settings, then send the invoice again. A send_invoice invoice tells the customer where to pay.                                    |
| [`permission_denied`](https://ownrecord.io/docs/reference/errors.md#permission_denied)                                     | 403         | The credentials can't change this brand's subscriptions (`subscriptions:write`).                               | Ask an organization owner or admin for a role or scope that allows this action.                                                                                                                           |
| [`entitlement_required`](https://ownrecord.io/docs/reference/errors.md#entitlement_required)                               | 403         | The organization's plan doesn't include subscriptions (`subscriptions.enabled`).                               | Upgrade the organization's plan, or remove something to get back under the limit.                                                                                                                         |
| [`org_suspended`](https://ownrecord.io/docs/reference/errors.md#org_suspended)                                             | 403         | Live mode, while the organization is suspended (§37.5).                                                        | If this is your organization, pay the open Ownrecord invoice in Organization → Billing; it is active again as soon as it is paid. Renewals, refunds, the customer portal and filings keep working.        |

It can also return these [common errors](https://ownrecord.io/docs/reference.md#common-errors): [`api_version_unsupported`](https://ownrecord.io/docs/reference/errors.md#api_version_unsupported), [`invalid_json`](https://ownrecord.io/docs/reference/errors.md#invalid_json), [`unsupported_media_type`](https://ownrecord.io/docs/reference/errors.md#unsupported_media_type), [`authentication_required`](https://ownrecord.io/docs/reference/errors.md#authentication_required), [`api_key_invalid`](https://ownrecord.io/docs/reference/errors.md#api_key_invalid), [`scope_required`](https://ownrecord.io/docs/reference/errors.md#scope_required), [`idempotency_key_required`](https://ownrecord.io/docs/reference/errors.md#idempotency_key_required), [`idempotency_key_reused`](https://ownrecord.io/docs/reference/errors.md#idempotency_key_reused), [`idempotency_in_progress`](https://ownrecord.io/docs/reference/errors.md#idempotency_in_progress), [`approval_required`](https://ownrecord.io/docs/reference/errors.md#approval_required), [`approval_rejected`](https://ownrecord.io/docs/reference/errors.md#approval_rejected), [`approval_expired`](https://ownrecord.io/docs/reference/errors.md#approval_expired), [`stale_approval`](https://ownrecord.io/docs/reference/errors.md#stale_approval), [`approval_policy_denied`](https://ownrecord.io/docs/reference/errors.md#approval_policy_denied), [`rate_limited`](https://ownrecord.io/docs/reference/errors.md#rate_limited), [`internal_error`](https://ownrecord.io/docs/reference/errors.md#internal_error).
