# Create a new subscription

Creates a new subscription for a customer with specified billing plan and schedule. The subscription will be created in 'created' status and will be activated when the customer completes the first payment.
On an `as_presented` subscription, pass `split_ids` to declare your share of a dynamic pricing rule's fee. See [Dynamic Fee Split](#tag/pricing_split). The declaration applies to the first payment and to every subsequent auto debit that does not pass `split_ids` of its own. `split_ids` is rejected on a fixed-frequency subscription, because a fixed-frequency plan auto debits without you and so has no point at which to pass a split or replace one that goes stale.
If the subscription's declaration later stops resolving — Glomo deleted the underlying rule, or the rule is no longer dynamic — the next auto debit is rejected with a `400 Bad Request` until you pass a valid `split_ids` on [Create a payment](#tag/Payment).

Endpoint: POST /subscriptions
Version: 1.0.0
Security: JWT

## Security:

  - `JWT` (unknown)
    http bearer JWT

## Request fields (application/json):

  - `customer_id` (string, required)
    Unique identifier of the customer associated with this subscription.
    Example: cust_5JU9yv0lGSUP

  - `product_name` (string, required)
    Name of the product being subscribed to. Up to 128 characters, using only letters `A`–`Z` and `a`–`z`, digits, whitespace, hyphens, underscores, periods, commas, parentheses and ampersands. Accented letters and any other symbol are rejected. A value that breaks either rule returns `400` with a message such as `Product name contains invalid characters…` or `Product name is too long (maximum is 128 characters)`.
    Example: ShieldGuard Insurance

  - `product_description` (string, required)
    Description of the product. Up to 512 characters. Allows the same characters as `product_name`, plus exclamation marks, colons, single quotes and asterisks; accented letters and any other symbol are rejected. A value that breaks either rule returns `400`.
    Example: Flexible monthly insurance for belongings travel and digital assets easy to manage

  - `plan_name` (string)
    Name of the subscription plan. Optional. A non-blank value follows the same rules as `product_name`: up to 128 characters, and the same allowed characters.
    Example: ShieldGuard Lite

  - `plan_description` (string)
    Description of the subscription plan. Optional. A non-blank value follows the same rules as `product_description`: up to 512 characters, and the same allowed characters.
    Example: Simple, monthly insurance plan that covers your basic belongings and key digital assets

  - `amount` (number, required)
    The amount in the smallest currency unit. For example, if the amount is $299.00, then 29900 is passed in  this field. In the case of three decimal currencies, such as KWD, BHD and OMR, to represent an amount of 295.991, pass the value as 295990. And in the case of zero decimal currencies such as JPY, for amount ￥295, pass the value as 295.
    Example: 1000

  - `currency` (string, required)
    The currency code in [ISO 4217](https://en.wikipedia.org/wiki/ISO_4217) format.
    Example: USD

  - `interval_type` (string, required)
    Used in combination with interval_count to define the billing cycle frequency.
    Enum: "month", "year", "as_presented"

  - `interval_count` (integer | null)
    Number of intervals between a billing cycle, used in combination with interval_type.
Valid combinations:
- Monthly: interval_type='month', interval_count=1
- Quarterly: interval_type='month', interval_count=3
- Half-yearly: interval_type='month', interval_count=6
- Yearly: interval_type='year', interval_count=1
- As Presented: interval_type='as_presented', interval_count=null
    Enum: "1", "3", "6", "null"

  - `billing_cycles` (integer)
    Total number of billing cycles for the subscription. Required for regular subscriptions, must not be provided for 'as_presented' subscriptions.
A subscription can have a lifetime of 30 years.
Maximum billing cycles therefore depend on interval:
- Monthly (interval_type='month', interval_count=1): max 360 cycles
- Quarterly (interval_type='month', interval_count=3): max 120 cycles
- Half-yearly (interval_type='month', interval_count=6): max 60 cycles
- Yearly (interval_type='year', interval_count=1): max 30 cycles

Send an integer of at least `2` as a JSON number; a string such as `"12"` is rejected. A value below
`2` or above the interval's maximum returns `400`.
    Example: 12

  - `max_amount` (integer)
    Maximum allowed amount per payment for `as_presented` subscriptions, in the smallest unit of `currency` (cents for USD). `5000` is $50.00 when `currency` is USD. A positive integer. Required when `interval_type` is `as_presented`, and must not be provided for regular subscriptions.
Subsequent payments on the subscription cannot exceed this amount.
    Example: 5000

  - `start_date` (string)
    Start date of the subscription in UTC timezone and ISO 8601 format (YYYY-MM-DD). Must be today or in the future.
Required for regular subscriptions, must not be provided for 'as_presented' subscriptions.
    Example: 2025-01-01

  - `expires_at` (string, required)
    Expiration date for the subscription payment link in UTC timezone and ISO 8601 format (YYYY-MM-DD). Must be today (UTC) or later, and at most 1 calendar month after today (UTC). An earlier date returns `400` with the message `Validation failed: Expires at must be today or in the future`, and a later one returns `400` with `Validation failed: Expires at cannot be more than 1 months from today`. It is not compared with `start_date`.
    Example: 2026-10-15

  - `notify_customer` (boolean, required)
    Whether to send notification e-mails to customers for subscription lifecycle changes.
    Example: true

  - `notes` (object | null)
    Optional key-value pairs for attaching custom metadata (e.g. invoice references, project codes). Keys must be strings and cannot collide with reserved field names. Your account may require some `notes` fields: Glomo configures custom field rules per account, and for beneficiaries they are checked when the beneficiary is created. Some fields are also validated by the beneficiary's country (for example, a PAN format for Indian beneficiaries). A missing required field returns `422` with `Validation failed: Notes <field> is required`, and type and validation errors (such as enum constraints) are returned the same way. The rule is set on your account, not by currency or rail. No API lists the fields, but the `422` names each missing one: add that key to `notes` with the value your account expects, and ask your Glomo account manager if you don't know what the field should hold. See [Custom fields](/payin/custom-fields). Each key appears as a separate column in CSV report exports, with corresponding values populating the rows.
    Example: {"invoice_ref":"INV-2026-001","project":"Alpha"}

  - `reference_number` (string)
    optional identifier to be sent for reconciliations
    Example: R0001

  - `starts_with_first_payment` (boolean, required)
    Whether the subscription payment schedule should get synchronized with the first payment.
    Example: true

  - `split_ids` (array)
    Supported only when `interval_type` is `as_presented`. Sending `split_ids` on a fixed-frequency subscription returns a `400 Bad Request`, because a fixed-frequency plan auto debits without you and so has no point at which to pass a split or replace one that goes stale.
The declaration applies to the first payment, and to every subsequent auto debit that does not pass `split_ids` of its own. See [Create a payment](#tag/Payment) for the auto debit override.
    Example: ["psplit_7Kq2mXbTdLp9"]

## Request examples:

  - `Standard monthly subscription` (unknown)

  - `Subscription with as_presented interval (flexible billing, merchant-initiated subsequent payments)` (unknown)

  - `as_presented subscription priced from a declared dynamic fee split` (unknown)

## Response 201:

  - `201` (unknown)
    Subscription created successfully

## Response 201 fields (application/json):

  - `id` (string, required)
    Unique identifier for the subscription.
    Example: sub_5JU9yv0lGSUP

  - `customer_id` (string, required)
    Unique identifier of the customer associated with this subscription.
    Example: cust_5JU9yv0lGSUP

  - `product_name` (string, required)
    Name of the product being subscribed to.
    Example: ShieldGuard Insurance

  - `product_description` (string, required)
    Description of the product.
    Example: Flexible, monthly insurance for belongings, travel, and digital assets, easy to manage

  - `plan_name` (string)
    Name of the subscription plan.
    Example: ShieldGuard Lite

  - `plan_description` (string)
    Description of the subscription plan.
    Example: Simple, monthly insurance plan that covers your basic belongings and key digital assets

  - `reference_number` (string)
    optional identifier to be sent for reconciliations
    Example: R0001

  - `status` (string, required)
    Current status of the subscription.
- `created` — the subscription exists and is waiting for the customer to authorise it.
- `authorized` — the customer has authorised the subscription and it has not become `active` yet.
- `active` — the subscription is charging on its schedule.
- `paused` — you paused the subscription. Resume it to continue charging.
- `halted` — charging stopped automatically; `halt_reason` says why. It returns to `active` after
its next successful payment, for example once the customer updates the card. The resume endpoint
applies only to `paused` subscriptions.
- `action_required` — Glomo needs more information before the subscription can proceed. Respond to
the open RFI to continue.
- `under_review` — the information you submitted is being reviewed. The subscription becomes
`active` if the review passes and `failed` if it does not.
- `completed` — every billing cycle has been charged. Terminal.
- `cancelled` — the subscription was cancelled. Terminal.
- `expired` — the customer did not authorise the subscription in time. Terminal.
- `failed` — the subscription could not be set up, or did not pass review. Terminal.
    Enum: "created", "authorized", "active", "paused", "halted", "action_required", "under_review", "completed", "cancelled", "expired", "failed"

  - `amount` (number, required)
    The amount in the smallest currency unit. For example, if the amount is $299.00, then 29900 is passed in  this field. In the case of three decimal currencies, such as KWD, BHD and OMR, to represent an amount of 295.991, pass the value as 295990. And in the case of zero decimal currencies such as JPY, for amount ￥295, pass the value as 295.
    Example: 1000

  - `currency` (string, required)
    The currency code in [ISO 4217](https://en.wikipedia.org/wiki/ISO_4217) format.
    Example: USD

  - `interval_type` (string, required)
    Used in combination with interval_count to define the billing cycle frequency.
    Enum: "month", "year", "as_presented"

  - `interval_count` (integer | null)
    Number of intervals between a billing cycle, used in combination with interval_type.
Valid combinations:
- Monthly: interval_type='month', interval_count=1
- Quarterly: interval_type='month', interval_count=3
- Half-yearly: interval_type='month', interval_count=6
- Yearly: interval_type='year', interval_count=1
- As Presented: interval_type='as_presented', interval_count=null
    Enum: "1", "3", "6", "null"

  - `billing_cycles` (integer | null)
    Total number of billing cycles for the subscription. Each cycle lasts `interval_count` units of `interval_type`, so 12 cycles with `interval_count` 1 and `interval_type` `month` span 12 months. `null` for `as_presented` subscriptions.
    Example: 12

  - `max_amount` (integer | null)
    Maximum allowed amount per payment, in the smallest unit of `currency` (cents for USD). `5000` is $50.00 when `currency` is USD. Present only for `as_presented` subscriptions, `null` for regular subscriptions.
    Example: 5000

  - `start_date` (string, required)
    Start date of the subscription in UTC timezone and ISO 8601 format (YYYY-MM-DD).
    Example: 2025-01-01

  - `end_date` (string | null)
    The date on which the subscription ends in UTC timezone and ISO 8601 format (YYYY-MM-DD).
    Example: 2025-12-01

  - `expires_at` (string, required)
    Expiration date for the subscription payment link in UTC timezone and ISO 8601 format (YYYY-MM-DD).
    Example: 2025-01-07

  - `next_payment_date` (string | null)
    Date of the next scheduled payment in UTC timezone and ISO 8601 format (YYYY-MM-DD).
    Example: 2025-02-01

  - `subscription_link_url` (string, required)
    URL for the subscription payment page. Your customer can use this URL to make the first payment and activate the subscription. The path is `/subscription-links/{id}`; in sandbox the URL ends with `?sandbox=true`. The host depends on your account, so share the URL exactly as returned rather than building it yourself.
    Example: https://your-dashboard-host.example/subscription-links/sub_5JU9yv0lGSUP

  - `cancelled_at` (string | null)
    Date when the subscription was cancelled in UTC timezone and ISO 8601 format (YYYY-MM-DD). This field is null unless the subscription status is 'cancelled'.
    Example: 2025-01-15

  - `notes` (object | null)
    Optional key-value pairs for attaching custom metadata (e.g. invoice references, project codes). Keys must be strings and cannot collide with reserved field names. Your account may require some `notes` fields: Glomo configures custom field rules per account, and for beneficiaries they are checked when the beneficiary is created. Some fields are also validated by the beneficiary's country (for example, a PAN format for Indian beneficiaries). A missing required field returns `422` with `Validation failed: Notes <field> is required`, and type and validation errors (such as enum constraints) are returned the same way. The rule is set on your account, not by currency or rail. No API lists the fields, but the `422` names each missing one: add that key to `notes` with the value your account expects, and ask your Glomo account manager if you don't know what the field should hold. See [Custom fields](/payin/custom-fields). Each key appears as a separate column in CSV report exports, with corresponding values populating the rows.
    Example: {"invoice_ref":"INV-2026-001","project":"Alpha"}

## Response 400:

  - `400` (unknown)
    Bad Request - validation error or invalid parameters

## Response 400 fields (application/json):

  - `error` (string)
    Enum: "Bad Request"

  - `message` (string)
    Error message describing the validation failure
    Example: Customer not found

## Response 400 examples:

  - `Customer not found` (unknown)

  - `split_ids sent on a fixed-frequency subscription` (unknown)

  - `A split id does not resolve to a live dynamic rule` (unknown)

  - `Another dynamic rule on the same dimension is not declared` (unknown)

