Skip to content

Plans & Pricing

Plans define what a customer pays and how pricing is calculated. Each plan has a base price, a billing interval, and one or more charges tied to billable metrics. BoxBilling supports eight charge models, letting you build flat-rate subscriptions, usage-based pricing, tiered pricing, and hybrid models from the same building blocks.

FieldTypeDescription
iduuidUnique plan identifier
codestringUnique plan code (used in API references)
namestringDisplay name
descriptionstring?Optional description
intervalstringBilling interval: weekly, monthly, quarterly, yearly
amount_centsintegerBase price in cents (default: 0)
currencystring3-letter ISO currency code (default: USD)
trial_period_daysintegerFree trial length in days (default: 0)
chargesarrayList of charges attached to this plan
created_atdatetimeCreation timestamp
updated_atdatetimeLast update timestamp
Terminal window
curl -X POST /v1/plans/ \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{
"code": "pro_monthly",
"name": "Pro Monthly",
"description": "Professional tier with metered API access",
"interval": "monthly",
"amount_cents": 4900,
"currency": "USD",
"trial_period_days": 14,
"charges": [
{
"billable_metric_id": "metric-uuid",
"charge_model": "graduated",
"properties": {
"graduated_ranges": [
{"from_value": 0, "to_value": 1000, "per_unit_amount": "0.00"},
{"from_value": 1001, "to_value": null, "per_unit_amount": "0.01"}
]
}
}
]
}'

Response:

{
"id": "550e8400-e29b-41d4-a716-446655440000",
"code": "pro_monthly",
"name": "Pro Monthly",
"description": "Professional tier with metered API access",
"interval": "monthly",
"amount_cents": 4900,
"currency": "USD",
"trial_period_days": 14,
"charges": [
{
"id": "charge-uuid",
"plan_id": "550e8400-e29b-41d4-a716-446655440000",
"billable_metric_id": "metric-uuid",
"charge_model": "graduated",
"properties": {
"graduated_ranges": [
{"from_value": 0, "to_value": 1000, "per_unit_amount": "0.00"},
{"from_value": 1001, "to_value": null, "per_unit_amount": "0.01"}
]
},
"created_at": "2026-03-08T10:00:00Z",
"updated_at": "2026-03-08T10:00:00Z"
}
],
"created_at": "2026-03-08T10:00:00Z",
"updated_at": "2026-03-08T10:00:00Z"
}

The code must be unique across all plans and is used to reference the plan in commitment and usage threshold endpoints.

Terminal window
curl -X PUT /v1/plans/{plan_id} \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "Pro Monthly (Updated)",
"amount_cents": 5900,
"charges": [
{
"billable_metric_id": "metric-uuid",
"charge_model": "standard",
"properties": {"amount": "0.02"}
}
]
}'

All update fields are optional — only the fields you include are modified. Updating charges replaces the entire charge list.

Terminal window
DELETE /v1/plans/{plan_id}

Returns 204 No Content on success. Plans with active subscriptions cannot be deleted.

IntervalBilling period
weeklyEvery 7 days
monthlyEvery calendar month
quarterlyEvery 3 months
yearlyEvery 12 months

The interval determines how often invoices are generated for subscriptions on this plan. Combined with billing_time on the subscription (calendar or anniversary), this controls the exact billing dates.

Each charge on a plan links a billable metric to a pricing model. The charge_model field determines how usage is converted into a dollar amount. The properties object configures the model’s parameters.

Fixed price per unit of usage.

{
"charge_model": "standard",
"properties": {
"amount": "0.10"
}
}

Example: 500 API calls at $0.10/call = $50.00

Tiered pricing where different rates apply to different quantity ranges. Each unit is priced at the rate for the tier it falls into.

{
"charge_model": "graduated",
"properties": {
"graduated_ranges": [
{"from_value": 0, "to_value": 100, "per_unit_amount": "1.00", "flat_amount": "0.00"},
{"from_value": 101, "to_value": 500, "per_unit_amount": "0.80", "flat_amount": "0.00"},
{"from_value": 501, "to_value": null, "per_unit_amount": "0.50", "flat_amount": "0.00"}
]
}
}

Example: 250 units = (100 x $1.00) + (150 x $0.80) = $220.00

Each tier can also include a flat_amount added once when that tier is reached.

The tier reached applies its rate to all units (not just units in that tier).

{
"charge_model": "volume",
"properties": {
"volume_ranges": [
{"from_value": 0, "to_value": 100, "per_unit_amount": "1.00", "flat_amount": "0.00"},
{"from_value": 101, "to_value": 500, "per_unit_amount": "0.80", "flat_amount": "0.00"},
{"from_value": 501, "to_value": null, "per_unit_amount": "0.50", "flat_amount": "0.00"}
]
}
}

Example: 250 units = 250 x $0.80 = $200.00 (all units priced at the 101–500 tier rate)

Price per package (bundle) of units. Partial packages are billed as full.

{
"charge_model": "package",
"properties": {
"package_size": 100,
"amount": "25.00"
}
}

Example: 250 units = 3 packages x $25.00 = $75.00

A percentage of a base amount (typically a transaction value or revenue metric).

{
"charge_model": "percentage",
"properties": {
"rate": "2.5",
"fixed_amount": "0.30"
}
}

Example: $1,000 transaction = ($1,000 x 2.5%) + $0.30 = $25.30

The optional fixed_amount adds a flat fee on top of the percentage.

Tiered percentage rates — different percentages apply to different amount ranges.

{
"charge_model": "graduated_percentage",
"properties": {
"graduated_percentage_ranges": [
{"from_value": 0, "to_value": 10000, "rate": "3.0", "flat_amount": "0.00"},
{"from_value": 10001, "to_value": 50000, "rate": "2.0", "flat_amount": "0.00"},
{"from_value": 50001, "to_value": null, "rate": "1.0", "flat_amount": "0.00"}
]
}
}

Example: $30,000 in volume = ($10,000 x 3.0%) + ($20,000 x 2.0%) = $300 + $400 = $700.00

Dynamically calculated pricing resolved at billing time. Configuration depends on the dynamic pricing provider.

Custom pricing logic for edge cases not covered by the built-in models.

ModelBest forUnit pricingExample use case
standardSimple per-unit billingSame rate for all unitsAPI calls, storage per GB
graduatedRewarding higher usageDecreasing per-tier ratesSaaS seats, message volume
volumeVolume discount pricingOne rate for all unitsBulk data transfer
packageBundle-based billingPer-package priceSMS packs, credit bundles
percentageTransaction fees% of amountPayment processing
graduated_percentageTiered transaction feesDecreasing % by tierMarketplace commissions
dynamicVariable pricingResolved at billingSpot pricing, auction
customEdge casesCustom logicNegotiated enterprise deals

Charges support filters to apply different pricing to different segments of a billable metric. Each filter references a billable metric filter and specifies which values it applies to:

{
"billable_metric_id": "metric-uuid",
"charge_model": "standard",
"properties": {"amount": "0.10"},
"filters": [
{
"billable_metric_filter_id": "filter-uuid",
"values": ["us-east-1", "us-west-2"],
"properties": {"amount": "0.08"},
"invoice_display_name": "US Regions"
},
{
"billable_metric_filter_id": "filter-uuid",
"values": ["eu-west-1"],
"properties": {"amount": "0.12"},
"invoice_display_name": "EU Regions"
}
]
}

Filters let you price the same metric differently based on dimensions like region, tier, or product type.

Test how a plan prices a given number of units before applying it to real subscriptions:

Terminal window
curl -X POST /v1/plans/{plan_id}/simulate \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{"units": 500}'

Response:

{
"plan_id": "plan-uuid",
"base_amount_cents": 4900,
"currency": "USD",
"charges": [
{
"charge_id": "charge-uuid",
"billable_metric_id": "metric-uuid",
"charge_model": "graduated",
"units": 500,
"amount_cents": 400,
"properties": {}
}
],
"total_amount_cents": 5300
}

Use simulation to validate pricing before publishing a plan or to build pricing calculators in your UI.

Plans can include minimum spend commitments. Commitments are managed per plan using the plan’s code:

Terminal window
# Create a commitment
curl -X POST /v1/plans/{plan_code}/commitments \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{
"minimum_amount_cents": 100000,
"invoice_display_name": "Monthly minimum"
}'
# List commitments
GET /v1/plans/{plan_code}/commitments

When a subscription’s usage falls below the commitment, the difference is billed as a true-up charge at the end of the billing period.

Define usage thresholds on a plan to trigger alerts or progressive billing when usage reaches defined amounts:

Terminal window
# Create a threshold
curl -X POST /v1/plans/{plan_code}/usage_thresholds \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{
"amount_cents": 50000,
"recurring": true
}'
# List thresholds
GET /v1/plans/{plan_code}/usage_thresholds

Thresholds are evaluated during usage ingestion. When a threshold is crossed, the configured action (webhook notification, progressive billing, etc.) fires automatically.

See how many active subscriptions exist per plan:

Terminal window
GET /v1/plans/subscription_counts

Useful for understanding plan adoption and identifying plans that may be candidates for retirement.

View revenue broken down by plan:

Terminal window
GET /dashboard/revenue_by_plan?start_date=2026-01-01&end_date=2026-03-08

Response:

{
"by_plan": [
{"plan_id": "plan-uuid", "plan_name": "Pro Monthly", "amount_cents": 1250000},
{"plan_id": "plan-uuid-2", "plan_name": "Enterprise Yearly", "amount_cents": 5000000}
],
"currency": "USD"
}

Plans connect to several other entities in BoxBilling:

EntityRelationship
SubscriptionsA subscription references a single plan that determines its pricing
ChargesEach plan contains one or more charges, each tied to a billable metric
Billable metricsMetrics define what is measured; charges define how it is priced
CommitmentsMinimum spend requirements attached to a plan
Usage thresholdsAlert/billing triggers defined at the plan level
FeaturesPlans can grant feature entitlements to subscribers
PortalPlans are listed in the customer portal for self-service plan changes
EventTrigger
plan.createdNew plan created
plan.updatedPlan properties or charges modified
plan.deletedPlan deleted
MethodPathDescription
POST/v1/plans/Create a plan
GET/v1/plans/List plans
GET/v1/plans/{plan_id}Get plan details
PUT/v1/plans/{plan_id}Update a plan
DELETE/v1/plans/{plan_id}Delete a plan
POST/v1/plans/{plan_id}/simulateSimulate plan pricing
GET/v1/plans/subscription_countsGet subscription counts per plan
POST/v1/plans/{plan_code}/commitmentsCreate a plan commitment
GET/v1/plans/{plan_code}/commitmentsList plan commitments
POST/v1/plans/{plan_code}/usage_thresholdsCreate a plan usage threshold
GET/v1/plans/{plan_code}/usage_thresholdsList plan usage thresholds
GET/dashboard/revenue_by_planRevenue breakdown by plan
GET/portal/plansList plans (customer portal)