---
title: "Create a subscription"
method: POST
path: "/subscriptions"
tags: ["Subscriptions"]
---

# Create a subscription

`POST /subscriptions`

Subscribe a customer to a plan. Returns a short_url that the customer MUST open to authorize the payment mandate (UPI Autopay, NACH, or card-on-file). The subscription will not charge until the mandate is authorized. Set notify_info to send the auth link via SMS/email automatically. Requires Subscriptions feature enabled on your Razorpay account.

## Request body

- object
  - `plan_id` string, required — Plan ID (plan_*) to subscribe the customer to.
  - `total_count` integer, required — Total number of billing cycles. Use 0 for indefinite (no fixed end).
  - `quantity` integer — Number of plan units billed per cycle.
  - `customer_notify` 0 | 1 — 1 to have Razorpay notify customer via SMS/email on each charge event.
  - `start_at` integer — Unix timestamp for the first charge. Defaults to subscription creation time.
  - `expire_by` integer — Unix timestamp deadline for the customer to authorize the mandate.
  - `addons` object[] — One-time charges added to the first billing cycle only.
    - `item` object
      - `name` string
      - `amount` integer — Addon amount in paise.
      - `currency` string
  - `offer_id` string — Offer/coupon ID to apply to the subscription.
  - `notify_info` object — If provided, Razorpay sends the mandate auth link directly to the customer.
    - `notify_phone` string — Customer phone number to send SMS.
    - `notify_email` string — Customer email address to send the link.
  - `notes` Notes — Key-value pairs for storing custom metadata. Maximum 15 pairs. Each key and value must not exceed 256 characters.

## Response `200`

Subscription created. Send short_url to the customer for mandate authorization.

- Subscription — A recurring billing subscription linking a customer to a plan. Requires customer mandate authorization via short_url before charges can be collected.
  - `id` string — Subscription ID. Prefix: sub_
  - `entity` 'subscription'
  - `plan_id` string — Associated plan ID (plan_*).
  - `status` 'created' | 'authenticated' | 'active' | 'pending' | 'halted' | 'cancelled' | 'completed' | 'expired' | 'paused' — Subscription lifecycle status. created→authenticated (mandate authorized)→active→completed/cancelled/expired. pending=charge retry scheduled; halted=multiple failures; paused=temporarily stopped.
  - `current_start` integer — Unix timestamp of current billing cycle start.
  - `current_end` integer — Unix timestamp of current billing cycle end.
  - `ended_at` integer — Unix timestamp when subscription ended (cancelled/completed/expired).
  - `quantity` integer — Number of plan units billed per cycle.
  - `notes` Notes — Key-value pairs for storing custom metadata. Maximum 15 pairs. Each key and value must not exceed 256 characters.
  - `charge_at` integer — Unix timestamp of next scheduled charge attempt.
  - `start_at` integer — Unix timestamp of first charge. Defaults to subscription creation time.
  - `end_at` integer — Unix timestamp after which no more charges will be attempted.
  - `auth_attempts` integer — Number of mandate authorization attempts.
  - `total_count` integer — Total billing cycles. 0 = indefinite.
  - `paid_count` integer — Number of billing cycles successfully charged.
  - `remaining_count` integer — Remaining billing cycles.
  - `customer_notify` 0 | 1 — 1 = Razorpay sends SMS/email notifications to customer on each charge.
  - `short_url` string — Mandate authorization URL. Must be sent to the customer to activate the subscription.
  - `has_scheduled_changes` boolean — True if a plan/quantity change is scheduled for the next cycle.
  - `change_scheduled_at` 'now' | 'cycle_end' — When scheduled changes take effect.
  - `source` string — Source that created the subscription (e.g., api, dashboard).
  - `offer_id` string — Offer/coupon applied to the subscription.
  - `expire_by` integer — Unix timestamp by which the customer must authorize the mandate.
  - `created_at` integer

## Other responses

- `400` — Bad request. Invalid parameters or missing required fields.
- `401` — Authentication failed. Invalid or missing API key credentials.
- `429` — Rate limit exceeded. Implement exponential backoff with jitter before retrying.

---

[API](https://skmtc.net/razorpay/apis/razorpay-api.md) · [All operations](https://skmtc.net/razorpay/apis/razorpay-api/llms.txt) · [OpenAPI document](https://skmtc-service-staging.skmtc.workers.dev/v1/apis/razorpay/razorpay-api/versions/824ca9e6faef/schema)
