Skip to content

Create a subscription

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

POST/api/v1/subscriptions

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):

FieldTypeRequiredDescription
customerIdcus_… IDYesThe customer (cus_…).
itemsarray of objectYesThe recurring prices: one currency; intervals that are whole multiples of each other.
items[].priceIdprice_… IDYesA recurring price (price_…).
items[].quantityinteger (1 to 1000000)NoSeats or units of a licensed price (1 to 1,000,000). Metered prices take no quantity.
collectionMethodone of charge_automatically, send_invoiceNocharge_automatically (the default payment method is charged) or send_invoice (the invoice is emailed with bank transfer details and paid by the due date).
daysUntilDueinteger (0 to 365)Nosend_invoice: days from an invoice's issue date to its due date (default 14).
trialDaysinteger (0 to 730)NoTrial days (0 = no trial). Default: the shortest trial of the prices.
trialEnddate-timeNoWhen the trial ends (instead of trialDays).
trialEndBehaviorone of convert, cancel_if_no_payment_method, pause_if_no_payment_methodNoWhat happens at the trial's end without a payment method: convert (bill anyway), cancel_if_no_payment_method or pause_if_no_payment_method.
couponIdcpn_… IDNoA coupon to apply (cpn_…).
promotionCodestringNoA promotion code as the customer typed it (case doesn't matter).
billingCycleAnchordate-timeNoWhen the first full period starts (default: now, or the trial's end). A later anchor bills a prorated first period.
prorationBehaviorone of create_prorations, always_invoice, noneNoWith a later billingCycleAnchor: create_prorations and always_invoice charge the partial first period now; none bills nothing until the anchor.
paymentMethodIdpm_… IDNoA saved payment method of the customer (pm_…); default: the customer's default method.
setupSuccessUrlstringNoWithout a payment method (charge_automatically): where the setup checkout sends the customer after saving one.
usageThresholdobjectNoInvoice 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.amountstringYesInteger micros as a string (12500000 = 12.50).
usageThreshold.currencystringYesISO 4217 currency code: the price's currency.
metadataobjectNoYour own key-value pairs (at most 50 keys). On updates the whole set is replaced.

Response

201 Created with a JSON object:

FieldTypeDescription
idsub_… ID
object"subscription"
livemodeboolean
entityIdent_… ID
brandIdbrd_… ID
customerIdcus_… ID
statusone of incomplete, incomplete_expired, trialing, active, past_due, unpaid, paused, canceledincomplete (waiting for the first payment, 23 hours), trialing, active, past_due, unpaid, paused, canceled or incomplete_expired (spec §16.1).
itemsarray of object
items[].idsi_… ID
items[].priceIdprice_… ID
items[].productIdprod_… ID
items[].quantityinteger
items[].createdAtdate-time
currencystring
mrrmoney or nullThe items' monthly recurring amount (licensed items, before discounts and tax).
collectionMethodone of charge_automatically, send_invoice
daysUntilDueinteger or null
defaultPaymentMethodIdpm_… ID or null
billingCycleAnchordate-time
currentPeriodStartdate-time
currentPeriodEnddate-time
trialStartdate-time or null
trialEnddate-time or null
trialEndBehaviorone of convert, cancel_if_no_payment_method, pause_if_no_payment_method
cancelAtPeriodEndboolean
cancelAtdate-time or null
canceledAtdate-time or null
endedAtdate-time or null
cancellationobject or null
pauseobject or null
discountIdsarray of disc_… ID
pendingUpdateobject or null
latestInvoiceIdinv_… ID or null
incompleteExpiresAtdate-time or null
testClockIdclk_… ID or null
dunningobject or nullDunning (§16.10) while past due or unpaid; null otherwise.
usageThresholdmoney or nullUnbilled metered usage worth this much is invoiced at once (spec §16.7).
entitlementGraceUntildate-time or null
metadataobject
versioninteger
createdAtdate-time
updatedAtdate-time
paymentSetupobject or nullcharge_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

CodeHTTP statusWhenWhat to do
validation_failed400A field is malformed or out of range.Fix the fields listed in details.issues and send the request again.
resource_not_found404No 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_deleted400The 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_invalid400A 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_conflict409The 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_invalid400paymentMethodId 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_invalid400billingCycleAnchor 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_redeemable409The 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_redeemable409The 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_required422An 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_blocked422The 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_conflict422The 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_missing409send_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_denied403The 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_required403The organization's plan doesn't include subscriptions (subscriptions.enabled).Upgrade the organization's plan, or remove something to get back under the limit.
org_suspended403Live 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: api_version_unsupported, invalid_json, unsupported_media_type, authentication_required, api_key_invalid, scope_required, idempotency_key_required, idempotency_key_reused, idempotency_in_progress, approval_required, approval_rejected, approval_expired, stale_approval, approval_policy_denied, rate_limited, internal_error.