Subscriptions API
Complete guide to managing customer subscriptions via the API
Subscriptions API
The Subscriptions API allows you to create, manage, and track customer subscriptions for your application. Subscriptions link customers to specific plans and handle billing, feature access, and lifecycle management.
Overview
Subscriptions represent the relationship between customers and plans. Each subscription includes:
- Customer Association: Links to a specific customer
- Plan & Pricing: Associated plan and effective pricing
- Features: Access to plan features with optional overrides
- Lifecycle Management: Start/end dates, versioning, and cancellation
- Billing Integration: Automatic recurring billing and MRR calculation
Authentication
All API requests require authentication via merchant credentials.
Endpoints
Get All Subscriptions
Get all subscriptions for the authenticated merchant.
GET /api/subscriptions
Query Parameters
Parameter | Type | Description |
---|---|---|
includeFeatures | string | Set to "true" to include subscription features |
Response
{
"subscriptions": [
{
"id": "sub_stable_123",
"customerId": "cust_123",
"planId": "plan_456",
"effectivePriceId": "price_789",
"startTimestamp": "2024-01-01T00:00:00Z",
"endTimestamp": null,
"versionNumber": 1,
"createdAt": "2024-01-01T00:00:00Z",
"customer": {
"id": "cust_123",
"email": "customer@example.com",
"name": "John Doe"
},
"plan": {
"id": "plan_456",
"planName": "Professional Plan",
"planDescription": "For growing businesses"
},
"price": {
"id": "price_789",
"pricingData": {
"components": [
{
"type": "fixed",
"amount_cents": 2900,
"recurrence_rule": "FREQ=MONTHLY"
}
]
}
},
"subscriptionFeatures": [
{
"id": "subfeature_123",
"featureId": "feature_456",
"featureValue": "10000",
"source": "plan",
"feature": {
"id": "feature_456",
"slug": "api_calls",
"displayName": "API Calls",
"featureType": "number"
}
}
]
}
]
}
Get Subscriptions by Customer
Get all subscriptions for a specific customer.
GET /api/subscriptions/customer/{customerId}
Parameters
Parameter | Type | Description |
---|---|---|
customerId | string | Customer ID |
Query Parameters
Parameter | Type | Description |
---|---|---|
includeFeatures | string | Set to "true" to include subscription features |
Response
Same structure as get all subscriptions, but filtered for the specific customer.
Calculate MRR (Monthly Recurring Revenue)
Calculate the total Monthly Recurring Revenue for the merchant.
GET /api/subscriptions/mrr
Response
{
"mrr": {
"amount_cents": 145000,
"amount": 1450.0,
"active_subscriptions_count": 25,
"calculated_at": "2024-01-15T10:30:00Z"
}
}
Get Subscription by ID
Get a specific subscription by its stable ID.
GET /api/subscriptions/{id}
Parameters
Parameter | Type | Description |
---|---|---|
id | string | Subscription stable ID |
Query Parameters
Parameter | Type | Description |
---|---|---|
includeFeatures | string | Set to "true" to include subscription features |
Response
Same structure as the subscription object in the get all response.
Create Subscription
Create a new subscription for a customer.
POST /api/subscriptions
Request Body
{
"customerId": "cust_123",
"planId": "plan_456",
"effectivePriceId": "price_789",
"startTimestamp": "2024-01-01T00:00:00Z"
}
Request Fields
Field | Type | Required | Description |
---|---|---|---|
customerId | string | ✓ | Customer ID |
planId | string | ✓ | Plan ID |
effectivePriceId | string | ✓ | Price ID to use for billing |
startTimestamp | string | ISO datetime for subscription start |
Response
{
"subscription": {
"id": "sub_stable_456",
"customerId": "cust_123",
"planId": "plan_456",
"effectivePriceId": "price_789",
"startTimestamp": "2024-01-01T00:00:00Z",
"endTimestamp": null,
"versionNumber": 1,
"createdAt": "2024-01-01T00:00:00Z",
"subscriptionFeatures": [
{
"id": "subfeature_456",
"featureId": "feature_789",
"featureValue": "10000",
"source": "plan"
}
]
}
}
Add Feature Overrides
Add feature overrides to an existing subscription (creates a new version).
POST /api/subscriptions/feature-overrides/{id}
Parameters
Parameter | Type | Description |
---|---|---|
id | string | Subscription stable ID |
Request Body
{
"featureIds": ["feature_123", "feature_456", "feature_789"]
}
Request Fields
Field | Type | Required | Description |
---|---|---|---|
featureIds | string[] | ✓ | Complete list of feature IDs |
Response
Returns the updated subscription with the new version number and feature overrides applied.
Add Price Override
Add a price override to an existing subscription (creates a new version).
POST /api/subscriptions/price-override/{id}
Parameters
Parameter | Type | Description |
---|---|---|
id | string | Subscription stable ID |
Request Body
{
"priceId": "price_new_123"
}
Request Fields
Field | Type | Required | Description |
---|---|---|---|
priceId | string | ✓ | New price ID to apply |
Response
Returns the updated subscription with the new version number and price override applied.
Cancel Subscription
Cancel an active subscription.
DELETE /api/subscriptions/{id}
Parameters
Parameter | Type | Description |
---|---|---|
id | string | Subscription stable ID |
Response
{
"success": true,
"message": "Subscription, associated features, and details canceled successfully"
}
Create Free Subscription
Create a free subscription for a customer with automatic plan selection.
POST /api/subscriptions/create-free-subscription
Request Body
{
"customerEmail": "customer@example.com",
"customerName": "John Doe",
"userId": "user_ext_123",
"billingAddressLine1": "123 Main St",
"billingAddressLine2": "Apt 4B",
"billingCity": "New York",
"billingPostalCode": "10001",
"billingCountry": "US",
"taxId": "12-3456789"
}
Request Fields
Field | Type | Required | Description |
---|---|---|---|
customerEmail | string | ✓ | Customer email address |
customerName | string | ✓ | Customer full name |
userId | string | ✓ | External user ID |
billingAddressLine1 | string | Primary billing address | |
billingAddressLine2 | string | Secondary billing address | |
billingCity | string | Billing city | |
billingPostalCode | string | Billing postal code | |
billingCountry | string | Billing country code | |
taxId | string | Tax identification number |
Response
{
"message": "Free subscription created successfully",
"subscription": {
"id": "sub_stable_789",
"customerId": "cust_456",
"planId": "plan_free_123",
"effectivePriceId": "price_free_456",
"startTimestamp": "2024-01-01T00:00:00Z",
"endTimestamp": null,
"versionNumber": 1,
"createdAt": "2024-01-01T00:00:00Z",
"customer": {
"id": "cust_456",
"email": "customer@example.com",
"name": "John Doe"
},
"plan": {
"id": "plan_free_123",
"planName": "Free Plan",
"planDescription": "Get started with our free tier"
},
"subscriptionFeatures": []
},
"plan": {
"id": "plan_free_123",
"name": "Free Plan",
"description": "Get started with our free tier"
},
"credit_grants_created": 2
}
Examples
Creating a Basic Subscription
curl -X POST /api/subscriptions \
-H "Content-Type: application/json" \
-d '{
"customerId": "cust_123",
"planId": "plan_456",
"effectivePriceId": "price_789"
}'
Creating a Free Subscription
curl -X POST /api/subscriptions/create-free-subscription \
-H "Content-Type: application/json" \
-d '{
"customerEmail": "newuser@example.com",
"customerName": "Jane Smith",
"userId": "external_user_456",
"billingAddressLine1": "456 Oak Ave",
"billingCity": "San Francisco",
"billingPostalCode": "94102",
"billingCountry": "US"
}'
Adding Feature Overrides
curl -X POST /api/subscriptions/feature-overrides/sub_stable_123 \
-H "Content-Type: application/json" \
-d '{
"featureIds": ["feature_premium_123", "feature_advanced_456"]
}'
Applying Price Override
curl -X POST /api/subscriptions/price-override/sub_stable_123 \
-H "Content-Type: application/json" \
-d '{
"priceId": "price_discounted_789"
}'
Getting MRR Report
curl -X GET /api/subscriptions/mrr \
-H "Content-Type: application/json"
Canceling a Subscription
curl -X DELETE /api/subscriptions/sub_stable_123 \
-H "Content-Type: application/json"
Error Responses
All endpoints may return these error responses:
400 Bad Request
{
"error": "No featureIds provided"
}
404 Not Found
{
"error": "Subscription not found or access denied"
}
409 Conflict
{
"error": "Subscription already exists for this customer",
"subscription": {
"id": "sub_stable_existing_123"
}
}
500 Internal Server Error
{
"error": "Failed to create subscription"
}
Important Notes
Subscription Versioning
- Subscriptions support versioning for tracking changes over time
- Feature overrides and price overrides create new versions
- The stable subscription ID remains constant across versions
- Previous versions are soft-deleted when new versions are created
Feature Management
- Subscriptions inherit features from their associated plan
- Feature overrides completely replace plan features (not additive)
- Features can have values overridden at the subscription level
- Feature sources are tracked as "plan" or "override"
MRR Calculation
- Only active subscriptions (not ended or deleted) are included
- Monthly subscriptions contribute their full amount
- Yearly subscriptions contribute 1/12 of their annual amount
- Only "fixed" pricing components are included in MRR
- Usage-based components are excluded from MRR calculations
Free Subscriptions
- Automatically selects the latest free plan from active pricing tables
- Creates both customer and Stripe customer records if needed
- Handles credit grants for usage-based features
- Requires Stripe integration to be configured
Billing Integration
- Subscriptions automatically create billing records
- Price overrides update billing immediately
- Canceled subscriptions stop future billing
- Subscription details are soft-deleted on cancellation
ID Mapping
- Internal database IDs are mapped to stable IDs in responses
- Stable IDs are used in API requests for consistency
- Version numbers track subscription modifications
- Customer and plan relationships are maintained across versions
Lifecycle Management
- Active subscriptions have no
endTimestamp
- Canceled subscriptions have both
endTimestamp
anddeletedAt
- Subscription features and details are cascaded on cancellation
- Version history is preserved for audit purposes