Subscription Billing
Subscriptions allow you to set up recurring billing for your customers. Creating a Subscription will bill a customer according to a given Plan. Addons let you bill for additonal line items that get added onto the base plan price. An addon can be another plan that must have the same billing interval as the subscription's primary plan.
Subscriptions can have a fixed or infinite duration. Setting the cycles
property will end the subscription after a fixed number of billing cycles. Otherwise, the subscription must be canceled in order to be stopped.
By default subscriptions will renew each billing cycle on the same day of the cycle on which it was started. For example, a subscription that started on the 9th of the month will always renew on the 9th of the month. This is known as Anniversary Billing. We also support renewing subscriptions on a specific day of the month, i.e. the first. If the subscription does not begin on the day you've specified then the first bill will be prorated. This is called Calendar Billing.
Subscriptions can optionally include a contract period, the length of which is measured in a number of billing cycles. At the end of the contract term, these subscriptions can be set to renew or end automatically, or to renew pending manual approval.
Subscription Object
Attributes
{
"addons": [
{
"created_at": 1420391704,
"description": "",
"id": 3,
"object": "subscription_addon",
"plan": "ipad-license",
"quantity": 11,
"updated_at": 1420391704
}
],
"bill_in": "advance",
"bill_in_advance_days": 0,
"cancel_at_period_end": false,
"canceled_at": null,
"contract_period_end": 1449249304,
"contract_period_start": 1446657304,
"contract_renewal_cycles": null,
"contract_renewal_mode": "auto",
"created_at": 1420391704,
"customer": 15444,
"cycles": null,
"discounts": [],
"id": 595,
"metadata": [],
"mrr": 100,
"object": "subscription",
"paused": false,
"period_end": 1449249304,
"period_start": 1446657304,
"plan": "starter",
"quantity": 1,
"recurring_total": 1200,
"ship_to": null,
"start_date": 1420391704,
"status": "active",
"taxes": [],
"updated_at": 1420391704,
"url": "https://dundermifflin.invoiced.com/subscriptions/o2mAd2wWVfYy16XZto7xHwXX"
}
Parameter | Type | Description |
---|---|---|
id | integer | The subscription's unique ID |
object | string | Object type, subscription |
customer | integer | Associated Customer |
amount | string | Subscription price when the plans's pricing mode is custom |
plan | string | Plan ID |
start_date | timestamp | Timestamp subscription starts (or started) |
bill_in | string | advance or arrears . Defaults to advance |
bill_in_advance_days | integer | Issues invoices N days before billing period when bill_in=advance |
quantity | integer | Plan quantity. Defaults to 1 |
addons | array | Collection of Subscription Addons |
discounts | array | Collection of Coupon Objects |
cycles | integer | Number of billing cycles the subscription runs for, when null runs until canceled (default). |
period_start | timestamp | Start of the current billing period |
period_end | timestamp | End of the current billing period |
cancel_at_period_end | boolean | When true the subscription will be canceled at the end of the current billing period |
canceled_at | timestamp | Timestamp the subscription was canceled |
status | string | Subscription status, one of not_started , active , past_due , finished , canceled |
paused | boolean | When true, subscription is paused |
contract_period_start | timestamp | Start of current contract period |
contract_period_end | timestamp | End of current contract period |
contract_renewal_cycles | integer | Number of billing cycles in next contract period |
contract_renewal_mode | string | auto , manual , renew_once , or none . Defaults to none |
taxes | array | Collection of Tax Rate Objects |
ship_to | object | Shipping Detail object |
recurring_total | number | Total recurring amount (includes taxes) |
mrr | number | Monthly Recurring Revenue (MRR) |
url | string | URL to manage the subscription in the billing portal |
created_at | timestamp | Timestamp when created |
updated_at | timestamp | Timestamp when updated |
metadata | object | A hash of key/value pairs that can store additional information about this object. |
Subscription Addon Object
Attributes
{
"created_at": 1420391704,
"description": "",
"id": 3,
"object": "subscription_addon",
"plan": "ipad-license",
"quantity": 11,
"updated_at": 1420391704
}
Parameter | Type | Description |
---|---|---|
id | integer | The subscription's unique ID |
object | string | Object type, subscription_addon |
amount | string | Addon price when a plan is set and has pricing mode set to custom |
plan | string | PlanĀ ID |
quantity | integer | Quantity |
description | string | Optional description for line items generated from this addon |
created_at | timestamp | Timestamp when created |
updated_at | timestamp | Timestamp when updated |
Create a subscription
curl "https://api.invoiced.com/subscriptions" \
-u {API_KEY}: \
-d customer=15444 \
-d plan="starter" \
-d addons[0][plan]="ipad-license" \
-d addons[0][quantity]=11
invoiced.Subscription.create(
:customer => 15444,
:plan => "starter",
:addons => [
{
:plan => "ipad-license",
:quantity => 11
}
]
)
<?php
$invoiced->Subscription->create([
'customer' => 15444,
'plan' => "starter",
'addons' => [
[
'plan' => "ipad-license",
'quantity' => 11
]
]
]);
client.Subscription.create(
customer=15444,
plan="starter",
addons=[
{
'plan': "ipad-license",
'quantity': 11
}
]
)
Subscription subscription = invoiced.newSubscription();
subscription.customer = 15444;
subscription.plan = "starter";
subscription.addons = new SubscriptionAddon[1];
subscription.addons[0] = new SubscriptionAddon();
subscription.addons[0].plan = "ipad-license";
subscription.addons[0].quantity = 11;
subscription.create();
var subscription = invoiced.NewSubscription();
subscription.Customer = 15444;
subscription.Plan = "starter";
subscription.Addons = new SubscriptionAddon[1];
subscription.Addons[0] = new SubscriptionAddon();
subscription.Addons[0].Plan = "ipad-license";
subscription.Addons[0].Quantity = 11;
subscription.Create();
subscription, err := client.Subscription.Create(&invoiced.SubscriptionRequest{
Customer: invoiced.Int64(15444),
Plan: invoiced.String("starter"),
Addons: []*invoiced.SubscriptionAddon{
{
Plan: invoiced.String("ipad-license"),
Quantity: invoiced.Float64(11),
}
}
})
The above command returns JSON structured like this:
{
"addons": [
{
"created_at": 1420391704,
"description": "",
"id": 3,
"object": "subscription_addon",
"plan": "ipad-license",
"quantity": 11,
"updated_at": 1420391704
}
],
"bill_in": "advance",
"bill_in_advance_days": 0,
"cancel_at_period_end": false,
"canceled_at": null,
"contract_period_end": 1449249304,
"contract_period_start": 1446657304,
"contract_renewal_cycles": null,
"contract_renewal_mode": "auto",
"created_at": 1420391704,
"customer": 15444,
"cycles": null,
"discounts": [],
"id": 595,
"metadata": [],
"mrr": 100,
"object": "subscription",
"paused": false,
"period_end": 1420391704,
"period_start": null,
"plan": "starter",
"quantity": 1,
"recurring_total": 1200,
"ship_to": null,
"start_date": 1420391704,
"status": "active",
"taxes": [],
"updated_at": 1420391704,
"url": "https://dundermifflin.invoiced.com/subscriptions/o2mAd2wWVfYy16XZto7xHwXX"
}
Create a new subscription with this endpoint.
HTTP Request
POST /subscriptions
Attributes
Parameter | Type | Description |
---|---|---|
customer | integer | Customer ID, required |
plan | string | Plan ID, required |
start_date | integer | Timestamp subscription begins, defaults to now |
bill_in | string | advance or arrears . Defaults to advance |
bill_in_advance_days | integer | Issues invoices N days before billing period when bill_in=advance |
quantity | integer | Plan quantity. Defaults to 1 |
addons | array | Collection of optional Subscription Addons |
discounts | array | Collection of Coupon IDs |
cycles | integer | Number of billing cycles the subscription runs for, when null runs until canceled (default). |
snap_to_nth_day | integer | Snap billing cycles to a specific day of the month (also known as calendar billing), off by default |
paused | boolean | When true, subscription is paused |
contract_renewal_cycles | integer | Number of billing cycles in next contract period |
contract_renewal_mode | string | auto , manual , renew_once , or none |
taxes | array | Collection of Tax Rate IDs |
ship_to | object | Shipping Detail object |
cancel_at_period_end | boolean | When true the subscription will be canceled at the end of the current billing period |
metadata | object | A hash of key/value pairs that can store additional information about this object. |
Preview a subscription
curl "https://api.invoiced.com/subscriptions/preview" \
-u {API_KEY}: \
-d customer=481594 \
-d plan="starter" \
invoiced.Subscription.preview(
:customer => 481594,
:plan => "starter"
)
<?php
$invoiced->Subscription->preview([
'customer' => 481594,
'plan' => "starter"
]);
client.Subscription.preview(
customer=481594,
plan="starter"
)
Subscription subscription = invoiced.newSubscription();
subscription.customer = 481594;
subscription.plan = "starter";
subscription.preview();
var subscription = invoiced.NewSubscription();
subscription.Customer = 481594;
subscription.Plan = "starter";
subscription.Preview();
preview, err := client.Subscription.Preview(&invoiced.SubscriptionPreviewRequest{
Customer: invoiced.Int64(481594),
Plan: invoiced.String("starter"),
})
The above command returns JSON structured like this:
{
"first_invoice": {
"attempt_count": null,
"autopay": null,
"balance": 0,
"closed": false,
"created_at": null,
"csv_url": null,
"currency": "usd",
"customer": -1,
"date": 1571410119,
"discounts": [],
"draft": true,
"due_date": null,
"id": null,
"items": [
{
"amount": 49,
"catalog_item": null,
"created_at": null,
"description": "",
"discountable": true,
"discounts": [],
"id": null,
"metadata": [],
"name": "Starter",
"object": "line_item",
"plan": "starter",
"quantity": 1,
"taxable": true,
"taxes": [],
"type": "plan",
"unit_cost": 49,
"updated_at": null
}
],
"metadata": [],
"name": "Starter",
"next_payment_attempt": null,
"notes": null,
"number": null,
"object": "invoice",
"paid": false,
"payment_plan": null,
"payment_source": null,
"payment_terms": null,
"payment_url": null,
"pdf_url": null,
"ship_to": null,
"shipping": [],
"status": "draft",
"subscription": null,
"subtotal": 49,
"taxes": [],
"total": 49,
"updated_at": null,
"url": null
},
"mrr": 49,
"recurring_total": 49
}
The subscription preview endpoint lets you get an estimate of the first invoice, recurring total, and MRR of a subscription without creating a customer, subscription, or any other data.
The plan and any referenced items must exist.
HTTP Request
POST /subscriptions/preview
Attributes
Parameter | Type | Description |
---|---|---|
plan | string | Plan ID, required |
customer | integer | Optional customer ID |
quantity | integer | Plan quantity. Defaults to 1 |
addons | array | Collection of optional Subscription Addons |
discounts | array | Collection of Coupon IDs |
taxes | array | Collection of Tax Rate IDs |
pending_line_items | array | Collection of pending line items |
Retrieve a subscription
curl "https://api.invoiced.com/subscriptions/:id" \
-u {API_KEY}:
subscription = invoiced.Subscription.retrieve("{SUBSCRIPTION_ID}")
<?php
$subscription = $invoiced->Subscription->retrieve("{SUBSCRIPTION_ID}");
subscription = client.Subscription.retrieve("{SUBSCRIPTION_ID}")
Subscription subscription = invoiced.newSubscription().retrieve({SUBSCRIPTION_ID});
var subscription = invoiced.NewSubscription().Retrieve({SUBSCRIPTION_ID});
subscription, err := client.Subscription.Retrieve({SUBSCRIPTION_ID})
The above command returns JSON structured like this:
{
"addons": [
{
"created_at": 1420391704,
"description": "",
"id": 3,
"object": "subscription_addon",
"plan": "ipad-license",
"quantity": 11,
"updated_at": 1420391704
}
],
"bill_in": "advance",
"bill_in_advance_days": 0,
"cancel_at_period_end": false,
"canceled_at": null,
"contract_period_end": 1449249304,
"contract_period_start": 1446657304,
"contract_renewal_cycles": null,
"contract_renewal_mode": "auto",
"created_at": 1420391704,
"customer": 15444,
"cycles": null,
"discounts": [],
"id": 595,
"metadata": [],
"mrr": 100,
"object": "subscription",
"paused": false,
"period_end": 1449249304,
"period_start": 1446657304,
"plan": "starter",
"quantity": 1,
"recurring_total": 1200,
"ship_to": null,
"start_date": 1420391704,
"status": "active",
"taxes": [],
"updated_at": 1420391704,
"url": "https://dundermifflin.invoiced.com/subscriptions/o2mAd2wWVfYy16XZto7xHwXX"
}
This endpoint retrieves a specific subscription.
HTTP Request
GET /subscriptions/:id
Update a subscription
curl "https://api.invoiced.com/subscriptions/:id" \
-u {API_KEY}: \
-d plan="pro" \
-X PATCH
subscription.plan = "pro"
subscription.save
<?php
$subscription->plan = "pro";
$subscription->save();
subscription.plan = "pro"
subscription.save()
subscription.plan = "pro";
subscription.save();
subscription.Plan = "pro";
subscription.SaveAll();
subscription, err := client.Subscription.Update(&invoiced.SubscriptionRequest{
Plan: invoiced.String("pro"),
})
The above command returns JSON structured like this:
{
"addons": [
{
"created_at": 1420391704,
"description": "",
"id": 3,
"object": "subscription_addon",
"plan": "ipad-license",
"quantity": 11,
"updated_at": 1420391704
}
],
"bill_in": "advance",
"bill_in_advance_days": 0,
"cancel_at_period_end": false,
"canceled_at": null,
"contract_period_end": 1449249304,
"contract_period_start": 1446657304,
"contract_renewal_cycles": null,
"contract_renewal_mode": "auto",
"created_at": 1420391704,
"customer": 15444,
"cycles": null,
"discounts": [],
"id": 595,
"metadata": [],
"mrr": 200,
"object": "subscription",
"paused": false,
"period_end": 1449249304,
"period_start": 1446657304,
"plan": "pro",
"quantity": 1,
"recurring_total": 2400,
"ship_to": null,
"start_date": 1420391704,
"status": "active",
"taxes": [],
"updated_at": 1420391704,
"url": "https://dundermifflin.invoiced.com/subscriptions/o2mAd2wWVfYy16XZto7xHwXX"
}
Use this endpoint to update a subscription.
HTTP Request
PATCH /subscriptions/:id
Request Parameters
Parameter | Type | Description |
---|---|---|
plan | string | Plan ID, required |
start_date | integer | Timestamp subscription begins, defaults to now |
quantity | integer | Plan quantity. Defaults to 1 |
addons | array | Collection of optional Subscription Addons |
discounts | array | Collection of Coupon IDs |
paused | boolean | When true, subscription is paused |
taxes | array | Collection of Tax Rate IDs |
ship_to | object | Shipping Detail object |
contract_renewal_cycles | integer | Number of billing cycles in next contract period |
contract_renewal_mode | string | auto , manual , renew_once , or none |
cancel_at_period_end | boolean | When true the subscription will be canceled at the end of the current billing period |
prorate | boolean | Prorate changes to plan, quantities, or addons, defaults to true |
proration_date | integer | Timestamp when the proration happened, defaults to now |
metadata | object | A hash of key/value pairs that can store additional information about this object. |
Cancel a subscription
curl "https://api.invoiced.com/subscriptions/:id" \
-u {API_KEY}: \
-X DELETE
subscription.cancel
<?php
$subscription->cancel();
subscription.cancel()
subscription.cancel();
subscription.Cancel();
err := client.Subscription.Cancel({SUBSCRIPTION_ID})
The above command returns JSON structured like this:
{
"addons": [
{
"created_at": 1420391704,
"description": "",
"id": 3,
"object": "subscription_addon",
"plan": "ipad-license",
"quantity": 11,
"updated_at": 1420391704
}
],
"bill_in": "advance",
"bill_in_advance_days": 0,
"cancel_at_period_end": false,
"canceled_at": 1449162904,
"contract_period_end": 1449249304,
"contract_period_start": 1446657304,
"contract_renewal_cycles": null,
"contract_renewal_mode": "auto",
"created_at": 1420391704,
"customer": 15444,
"cycles": null,
"discounts": [],
"id": 595,
"metadata": [],
"mrr": 200,
"object": "subscription",
"paused": false,
"period_end": null,
"period_start": null,
"plan": "pro",
"quantity": 1,
"recurring_total": 2400,
"ship_to": null,
"start_date": 1420391704,
"status": "canceled",
"taxes": [],
"updated_at": 1420391704,
"url": "https://dundermifflin.invoiced.com/subscriptions/o2mAd2wWVfYy16XZto7xHwXX"
}
This endpoint cancels a subscription.
HTTP Request
DELETE /subscriptions/:id
List all subscriptions
curl "https://api.invoiced.com/subscriptions" \
-u {API_KEY}:
subscriptions, metadata = invoiced.Subscription.list(:per_page => 3)
<?php
list($subscriptions, $metadata) = $invoiced->Subscription->all(['per_page' => 3]);
subscriptions, metadata = client.Subscription.list(per_page=3)
EntityList<Subscription> subscriptions = invoiced.newSubscription().listAll();
var subscriptions = invoiced.NewSubscription().ListAll();
subscriptions, err := client.Subscription.ListAll(nil, nil)
The above command returns JSON structured like this:
[
{
"addons": [
{
"created_at": 1420391704,
"description": "",
"id": 3,
"object": "subscription_addon",
"plan": "ipad-license",
"quantity": 11,
"updated_at": 1420391704
}
],
"bill_in": "advance",
"bill_in_advance_days": 0,
"cancel_at_period_end": false,
"canceled_at": null,
"contract_period_end": 1449249304,
"contract_period_start": 1446657304,
"contract_renewal_cycles": null,
"contract_renewal_mode": "auto",
"created_at": 1420391704,
"customer": 15444,
"cycles": null,
"discounts": [],
"id": 595,
"metadata": [],
"mrr": 200,
"object": "subscription",
"paused": false,
"period_end": 1449249304,
"period_start": 1446657304,
"plan": "pro",
"quantity": 1,
"recurring_total": 2400,
"ship_to": null,
"start_date": 1420391704,
"status": "active",
"taxes": [],
"updated_at": 1420391704,
"url": "https://dundermifflin.invoiced.com/subscriptions/o2mAd2wWVfYy16XZto7xHwXX"
}
]
This endpoint retrieves all subscriptions. Unless specified, this endpoint will only return subscriptions that have an upcoming renewal.
HTTP Request
GET /subscriptions
Query Parameters
Parameter | Description |
---|---|
sort string | Column to sort by, i.e. period_end asc |
filter object | Filter object |
metadata object | Metadata filter object |
canceled boolean | When true returns only canceled subscriptions |
finished boolean | When true returns only finished subscriptions |
updated_after timestamp | Only gets records updated after the given timestamp |