Plans
Define a billing cadence. Plans carry no price — the price lives on each invoice line.
Plans
PUT https://api.faurya.com/api/v1/billing/plans/{external_id}
GET https://api.faurya.com/api/v1/billing/plans/{external_id}Requires Bearer Token authentication with your Faurya API key.
A plan is a name and a billing cadence: "Pro, billed every month", "Team, billed every year". That cadence is what turns a line amount into a monthly figure, so it is the piece Faurya needs to compute MRR.
A plan has no price. The price is stated on every invoice line that uses the plan. That is deliberate: it means grandfathered pricing, discounts, local currencies and per-seat amounts all work without a plan per price point.
Send your plans before the invoices whose lines name them — a line naming an unknown plan is refused with PLAN_NOT_FOUND.
Create or update a plan
const response = await fetch(
"https://api.faurya.com/api/v1/billing/plans/plan_pro_monthly",
{
method: "PUT",
headers: {
Authorization: `Bearer ${process.env.FAURYA_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
name: "Pro",
interval_unit: "month",
interval_count: 1,
}),
},
);Request body
All three fields are required.
name(string): What you call the plan. At most 255 characters.interval_unit(string):day,week,monthoryear.interval_count(integer): How many of those units one billing cycle is. Between 1 and 365.
So a quarterly plan is interval_unit: "month" with interval_count: 3; a two-weekly plan is "week" with 2.
Response
{
"object": "plan",
"external_id": "plan_pro_monthly",
"created": true,
"data": {
"external_id": "plan_pro_monthly",
"name": "Pro",
"interval_unit": "month",
"interval_count": 1
},
"warnings": [],
"request_id": "req_01JQ8Z0Y5N6W3K2M4P7R9T1V3X"
}The cadence locks once the plan is in use
A plan's name can always change. Its cadence can only change while nothing is priced on it.
Once any invoice line or subscription state uses the plan, changing interval_unit or interval_count is refused with 409 PLAN_CADENCE_LOCKED:
{
"message": "This plan's billing interval cannot change because invoices already use it. Create a new plan instead.",
"error": "PLAN_CADENCE_LOCKED",
"request_id": "req_01JQ8Z0Y5N6W3K2M4P7R9T1V3X"
}The reason is that the cadence is the only thing converting every historical line amount on that plan into a monthly figure. Flipping a plan from monthly to yearly would quietly divide every MRR figure it ever produced by twelve, retroactively.
If you genuinely move customers from monthly to yearly billing, create a second plan and bill the new periods against it. The move then shows up as a plan change, which is what it is.
Read a plan
const response = await fetch(
"https://api.faurya.com/api/v1/billing/plans/plan_pro_monthly",
{ headers: { Authorization: `Bearer ${process.env.FAURYA_API_KEY}` } },
);Answers 200 with the plan, or 404 if nothing was written under that id.
Response codes
200 OK— plan updated, or the request matched what was stored.201 Created— the plan did not exist before.400 Bad Request— missing or invalid fields.errorsnames every one.401 Unauthorized— missing or invalid API key.404 Not Found— (GETonly) no plan with that id.409 Conflict—PLAN_CADENCE_LOCKED, or another request is writing the same plan.429 Too Many Requests— over the rate limit.