---
title: "Create a subscription"
description: "Bills active subs in advance."
canonical_url: "https://twominutebilling.com/help/developers/api-reference/subscriptions/create-a-subscription"
---
# Create a subscription

> Bills active subs in advance.

<api-operation method="POST" path="/v1/businesses/{biz}/customers/{cus}/subscriptions">
<template v-slot:docs="">

When the new subscription auto-collects and bills a period NOW (no trial, starts immediately, `invoice_immediately` is not false), the customer must already have a USABLE payment method — not `expired`, not `invalid` — or the create is refused with 400 `payment_error` / `no_chargeable_payment_method`. Add a card first, or pass `auto_collection: "off"`. This refusal is newer than the endpoint: it was added with the mandate-expiry work so a subscription cannot be created already uncollectable. A declined first charge refuses the create (402, nothing is created) unless `on_charge_failure` is `dun`: then the subscription is created and dunning collects the open invoice.

## Path parameters

<table>
<thead>
  <tr>
    <th>
      Parameter
    </th>
    
    <th>
      Type
    </th>
    
    <th>
      Required
    </th>
    
    <th>
      Description
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      <code>
        biz
      </code>
    </td>
    
    <td>
      <code>
        string
      </code>
    </td>
    
    <td>
      <strong>
        yes
      </strong>
    </td>
    
    <td>
      Business id (biz_…)
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        cus
      </code>
    </td>
    
    <td>
      <code>
        string
      </code>
    </td>
    
    <td>
      <strong>
        yes
      </strong>
    </td>
    
    <td>
      Customer id (cus_…)
    </td>
  </tr>
</tbody>
</table>

## Headers

<table>
<thead>
  <tr>
    <th>
      Parameter
    </th>
    
    <th>
      Type
    </th>
    
    <th>
      Required
    </th>
    
    <th>
      Description
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      <code>
        Idempotency-Key
      </code>
    </td>
    
    <td>
      <code>
        string
      </code>
    </td>
    
    <td>
      no
    </td>
    
    <td>
      Safely retry writes — repeats return the original response. If a write FAILED after it had already taken effect, that failure is what repeats: the key is spent, and a new attempt needs a new key.
    </td>
  </tr>
</tbody>
</table>

## Body

The request body is **required**.

<table>
<thead>
  <tr>
    <th>
      Field
    </th>
    
    <th>
      Type
    </th>
    
    <th>
      Required
    </th>
    
    <th>
      Description
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      <code>
        shipping_address_id
      </code>
    </td>
    
    <td>
      <code>
        string
      </code>
    </td>
    
    <td>
      no
    </td>
    
    <td>
      Where this subscription ships: one of the customer's shipping addresses. Must not be archived. Omitted: the customer's default shipping address.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        payment_method
      </code>
    </td>
    
    <td>
      <code>
        string
      </code>
    </td>
    
    <td>
      no
    </td>
    
    <td>
      One of the customer's saved payment methods (<code>
        pm_…
      </code>
      
      ) to pin to the subscription. Collection charges it first, then the customer's backups. Must belong to this customer and not be <code>
        expired
      </code>
      
      /<code>
        invalid
      </code>
      
       (400). Omitted: the customer's primary.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        id
      </code>
    </td>
    
    <td>
      <code>
        string
      </code>
    </td>
    
    <td>
      no
    </td>
    
    <td>
      Your own subscription id (letters, digits, _ and -). Auto-generated as sub_<nano> when omitted. Unique per business; a duplicate returns 400. Mainly for keeping ids when migrating from another billing system.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        items
      </code>
    </td>
    
    <td>
      <code>
        array of object
      </code>
    </td>
    
    <td>
      <strong>
        yes
      </strong>
    </td>
    
    <td>
      The items on the subscription.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        items.price
      </code>
    </td>
    
    <td>
      <code>
        string
      </code>
    </td>
    
    <td>
      <strong>
        yes
      </strong>
    </td>
    
    <td>
      The price's id (a slug id, e.g. <code>
        pro-monthly-usd
      </code>
      
      ).
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        items.quantity
      </code>
    </td>
    
    <td>
      <code>
        integer
      </code>
    </td>
    
    <td>
      no
    </td>
    
    <td>
      The quantity. Defaults to <code>
        1
      </code>
      
      .
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        items.unit_price_minor
      </code>
    </td>
    
    <td>
      <code>
        integer
      </code>
    </td>
    
    <td>
      no
    </td>
    
    <td>
      Custom price override (flat/per-unit only), minor units; falls back to the catalog price when omitted
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        trial_days
      </code>
    </td>
    
    <td>
      <code>
        integer
      </code>
    </td>
    
    <td>
      no
    </td>
    
    <td>
      0 disables the plan's trial; omitted applies the plan price's trial_period.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        trial_end
      </code>
    </td>
    
    <td>
      <code>
        string · ISO-8601
      </code>
    </td>
    
    <td>
      no
    </td>
    
    <td>
      An exact trial end, in place of trial_days. Must be after the start; on a day-anchored business it names the day the trial ends on.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        start_date
      </code>
    </td>
    
    <td>
      <code>
        string · ISO-8601
      </code>
    </td>
    
    <td>
      no
    </td>
    
    <td>
      Backdate/future-date the period start
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        billing_anchor
      </code>
    </td>
    
    <td>
      <code>
        string · ISO-8601
      </code>
    </td>
    
    <td>
      no
    </td>
    
    <td>
      Calendar billing anchor for the first period end
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        coupon_ids
      </code>
    </td>
    
    <td>
      <code>
        array of string
      </code>
    </td>
    
    <td>
      no
    </td>
    
    <td>
      Coupon codes applied at signup — discount the first invoice
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        discount
      </code>
    </td>
    
    <td>
      <code>
        object
      </code>
    </td>
    
    <td>
      no
    </td>
    
    <td>
      A manual discount applied at signup — a %/amount reduction with no catalog coupon behind it, discounting the FIRST invoice (a discount passed at signup lands on the first invoice, not the next renewal). Singular, because the engine allows one discount per subscription and refuses a second.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        discount.type
      </code>
    </td>
    
    <td>
      <code>
        string
      </code>
    </td>
    
    <td>
      <strong>
        yes
      </strong>
    </td>
    
    <td>
      The discount type. One of <code>
        percent
      </code>
      
      , <code>
        amount
      </code>
      
      .
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        discount.value
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <strong>
        yes
      </strong>
    </td>
    
    <td>
      A whole percent 1-100 for <code>
        percent
      </code>
      
      ; integer MINOR units for <code>
        amount
      </code>
      
      .
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        discount.duration
      </code>
    </td>
    
    <td>
      <code>
        string
      </code>
    </td>
    
    <td>
      <strong>
        yes
      </strong>
    </td>
    
    <td>
      How long the discount lasts. One of <code>
        one_time
      </code>
      
      , <code>
        forever
      </code>
      
      .
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        discount.note
      </code>
    </td>
    
    <td>
      <code>
        string
      </code>
    </td>
    
    <td>
      no
    </td>
    
    <td>
      A note shown with the discount.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        invoice_immediately
      </code>
    </td>
    
    <td>
      <code>
        boolean
      </code>
    </td>
    
    <td>
      no
    </td>
    
    <td>
      Signup invoicing. true (default) raises — and with auto-collection on, collects — the first invoice now. false queues the first period as a pending unbilled charge instead, so it rides on the next invoice and nothing is collected at signup (the response then carries <code>
        deferred_charge
      </code>
      
       instead of <code>
        latest_invoice
      </code>
      
      ). Ignored for a trial or a future-dated start, neither of which invoices now. Distinct from create_pending_invoices, which governs RENEWAL invoicing. Defaults to <code>
        true
      </code>
      
      .
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        create_pending_invoices
      </code>
    </td>
    
    <td>
      <code>
        boolean
      </code>
    </td>
    
    <td>
      no
    </td>
    
    <td>
      RENEWAL invoicing for this subscription: false posts an invoice each renewal, true opens a pending invoice that charges accumulate on until it is closed. Overrides the business default when supplied.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        bill_usage_monthly
      </code>
    </td>
    
    <td>
      <code>
        boolean
      </code>
    </td>
    
    <td>
      no
    </td>
    
    <td>
      Invoice metered usage every month while the plan fee stays on the billing period. Needs a billing period of 2 months or more, in months or years, and no pending invoices. Default: the plan price's.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        commitment_amount_minor
      </code>
    </td>
    
    <td>
      <code>
        integer
      </code>
    </td>
    
    <td>
      no
    </td>
    
    <td>
      Minimum commitment for one full billing period; null for none. Default: the plan price's. Not with pending invoices.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        custom_fields
      </code>
    </td>
    
    <td>
      <code>
        object
      </code>
    </td>
    
    <td>
      no
    </td>
    
    <td>
      Custom-field values; or pass top-level cf_<name> params
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        payment_intent
      </code>
    </td>
    
    <td>
      <code>
        string
      </code>
    </td>
    
    <td>
      no
    </td>
    
    <td>
      An intent (<code>
        pi_…
      </code>
      
      ) the buyer authorized after this request answered 402 <code>
        requires_action
      </code>
      
      . The first invoice is settled by consuming it. Must belong to this customer, be <code>
        authorized
      </code>
      
       and match the first invoice's amount and currency.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        client_result
      </code>
    </td>
    
    <td>
      <code>
        object
      </code>
    </td>
    
    <td>
      no
    </td>
    
    <td>
      What the gateway's browser SDK returned for a <code>
        next_action.mode: sdk
      </code>
      
       challenge, as string key/values. We send it to the gateway, which decides the outcome. A refusal answers 400 (402 on subscription create) with the gateway's reason, and the intent stays open for a retry. Rejected with <code>
        client_result_unsupported
      </code>
      
       on a gateway that takes no browser result.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        on_charge_failure
      </code>
    </td>
    
    <td>
      <code>
        string
      </code>
    </td>
    
    <td>
      no
    </td>
    
    <td>
      What a declined first charge does, when the create charges now (auto-collection on, no trial, starts now, invoiced now). <code>
        refuse
      </code>
      
       (default): nothing is created and the call returns 402. <code>
        dun
      </code>
      
      : the subscription is created <code>
        active
      </code>
      
      , the first invoice stays open and dunning collects it, as after a failed renewal; the 201 response carries <code>
        payment_error
      </code>
      
       with the decline. <code>
        dun
      </code>
      
       with <code>
        on_session: true
      </code>
      
       or <code>
        payment_intent
      </code>
      
       is refused (400 <code>
        on_charge_failure_conflict
      </code>
      
      ), because the buyer pays before the subscription exists. One of <code>
        refuse
      </code>
      
      , <code>
        dun
      </code>
      
      .
    </td>
  </tr>
</tbody>
</table>

## Response

<table>
<thead>
  <tr>
    <th>
      Field
    </th>
    
    <th>
      Type
    </th>
    
    <th>
      Description
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      <code>
        object
      </code>
    </td>
    
    <td>
      <code>
        string
      </code>
    </td>
    
    <td>
      The object type.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        id
      </code>
    </td>
    
    <td>
      <code>
        string
      </code>
    </td>
    
    <td>
      The subscription's id (sub_…).
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        status
      </code>
    </td>
    
    <td>
      <code>
        string
      </code>
    </td>
    
    <td>
      The subscription's status. One of <code>
        future
      </code>
      
      , <code>
        in_trial
      </code>
      
      , <code>
        active
      </code>
      
      , <code>
        non_renewing
      </code>
      
      , <code>
        paused
      </code>
      
      , <code>
        cancelled
      </code>
      
      .
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        currency
      </code>
    </td>
    
    <td>
      <code>
        string
      </code>
    </td>
    
    <td>
      The subscription's currency (ISO-4217 code).
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        current_period_end
      </code>
    </td>
    
    <td>
      <code>
        string · ISO-8601
      </code>
    </td>
    
    <td>
      The current billing term end. NULL while <code>
        in_trial
      </code>
      
       — a trial is not a term, so a trialling subscription reports <code>
        trial_end
      </code>
      
       instead and this is null (one or the other is reported, never both). Use <code>
        next_billing_at
      </code>
      
       for "when is this customer charged again?", which answers across every status.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        next_billing_at
      </code>
    </td>
    
    <td>
      <code>
        string · ISO-8601
      </code>
    </td>
    
    <td>
      When the next invoice will be raised: trial end while in_trial, the scheduled start while future, the first renewal not skipped while active (or the next monthly usage invoice, when it is earlier); null once non_renewing/paused/cancelled, where no further invoice is due
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        bill_usage_monthly
      </code>
    </td>
    
    <td>
      <code>
        boolean
      </code>
    </td>
    
    <td>
      Metered usage is invoiced every month inside the billing period.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        current_sub_period_start
      </code>
    </td>
    
    <td>
      <code>
        string · ISO-8601
      </code>
    </td>
    
    <td>
      Monthly usage billing: usage before this instant is billed. Null when monthly usage billing is off.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        current_sub_period_end
      </code>
    </td>
    
    <td>
      <code>
        string · ISO-8601
      </code>
    </td>
    
    <td>
      Monthly usage billing: when the next monthly usage invoice is raised. Null when off.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        commitment
      </code>
    </td>
    
    <td>
      <code>
        object
      </code>
    </td>
    
    <td>
      Minimum commitment for one full billing period, or null. See GET /subscriptions/{id}/commitment for the counted fees.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        skipped_renewals
      </code>
    </td>
    
    <td>
      <code>
        array of string · ISO-8601
      </code>
    </td>
    
    <td>
      Upcoming renewals scheduled to be skipped, as the instants the clock renews at. See <code>
        skip_renewal
      </code>
      
      .
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        recurring_amount_minor
      </code>
    </td>
    
    <td>
      <code>
        integer
      </code>
    </td>
    
    <td>
      What one billing period charges for the recurring items, in minor units, net of discounts that last more than one period and before tax; null when cancelled or when an item recurs on a different cadence than the subscription
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        revenue_to_date_minor
      </code>
    </td>
    
    <td>
      <code>
        integer
      </code>
    </td>
    
    <td>
      DERIVED, read-only: cash collected on this subscription's invoices, in its currency — succeeded payments minus succeeded refunds. Credits applied to invoices are excluded. Emitted by GET (detail) only.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        revenue_paid_invoices_count
      </code>
    </td>
    
    <td>
      <code>
        integer
      </code>
    </td>
    
    <td>
      How many of this subscription's invoices received a succeeded payment.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        revenue_since
      </code>
    </td>
    
    <td>
      <code>
        string · ISO-8601
      </code>
    </td>
    
    <td>
      The first succeeded payment on this subscription; null when nothing was collected.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        custom_fields
      </code>
    </td>
    
    <td>
      <code>
        object
      </code>
    </td>
    
    <td>
      Stored custom-field values; also flattened onto the object as cf_<name>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        shipping_address_id
      </code>
    </td>
    
    <td>
      <code>
        string
      </code>
    </td>
    
    <td>
      The shipping address this subscription is set to ship to; null when it ships to the customer's default. Emitted by GET (detail), create, and an update that sends it.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        shipping_address
      </code>
    </td>
    
    <td>
      <code>
        object
      </code>
    </td>
    
    <td>
      Where this subscription ships now: its own address, else the customer's default, else null. Invoices record a copy when they are issued.
    </td>
  </tr>
</tbody>
</table>

## Status codes

<table>
<thead>
  <tr>
    <th>
      Status
    </th>
    
    <th>
      Meaning
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      <code>
        201
      </code>
    </td>
    
    <td>
      Created
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        400
      </code>
    </td>
    
    <td>
      Invalid body
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        404
      </code>
    </td>
    
    <td>
      No such customer/price
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        409
      </code>
    </td>
    
    <td>
      Idempotency-Key conflict — the key is already in flight, or was reused with a different request payload.
    </td>
  </tr>
</tbody>
</table>
</template>

<template v-slot:request="">

```bash [Request]
curl -X POST "$TMBILLING_URL/v1/businesses/biz_XXXXXXXXXXXX01/customers/cus_XXXXXXXXXXXX01/subscriptions" \
  -H "Authorization: Bearer $TMBILLING_API_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{
    "items": [
      {
        "price": "pro-monthly-usd",
        "quantity": 1
      }
    ]
  }'
```

</template>

<template v-slot:response="">
<code-group>

```json [201 Created]
{
  "object": "subscription",
  "id": "sub_XXXXXXXXXXXX01",
  "status": "active",
  "currency": "USD",
  "current_period_end": "2026-04-14T09:30:00Z",
  "next_billing_at": "2026-04-14T09:30:00Z",
  "bill_usage_monthly": false,
  "current_sub_period_start": "2026-03-14T09:30:00Z",
  "current_sub_period_end": "2026-04-14T09:30:00Z",
  "commitment": {
    "amount_minor": 2900
  },
  "skipped_renewals": [
    "2026-04-14T09:30:00Z"
  ],
  "recurring_amount_minor": 2900,
  "revenue_to_date_minor": 2900,
  "revenue_paid_invoices_count": 1,
  "revenue_since": "2026-03-14T09:30:00Z",
  "custom_fields": {
    "cf_region": "West"
  },
  "shipping_address_id": "Shipping address id",
  "shipping_address": {
    "object": "shipping_address",
    "id": "addr_XXXXXXXXXXXX01",
    "customer_id": "cus_XXXXXXXXXXXX01",
    "label": "Maya Castillo",
    "first_name": "Maya",
    "last_name": "Castillo",
    "company": "Brightwater Analytics",
    "phone": "+1 415 555 0100",
    "line1": "500 Market Street",
    "line2": "Suite 400",
    "line3": "Line3",
    "city": "San Francisco",
    "state": "CA",
    "state_code": "CA",
    "postal_code": "94105",
    "country": "US",
    "is_default": false,
    "archived": false,
    "archived_at": null,
    "created_at": "2026-03-14T09:30:00Z",
    "updated_at": "2026-03-14T09:30:00Z"
  }
}
```

```json [400 Bad Request]
{
  "error": {
    "type": "invalid_request_error",
    "message": "Invalid body"
  }
}
```

```json [404 Not Found]
{
  "error": {
    "type": "invalid_request_error",
    "message": "No such customer/price"
  }
}
```

```json [409 Conflict]
{
  "error": {
    "type": "idempotency_error",
    "message": "Idempotency-Key conflict — the key is already in flight, or was reused with a different request payload."
  }
}
```

</code-group>
</template>
</api-operation>


## Sitemap

See the full [sitemap](https://twominutebilling.com/sitemap.md) for all pages.
