Monigo supports four pricing models that cover the full spectrum of usage-based billing. Each model is attached to a Price, which is in turn attached to a Plan. One plan can have multiple prices, each tracking a different metric with its own model.
Quick reference
| Model | Value | tiers field | How the charge is calculated |
|---|
| Flat / Per-unit | flat_unit / per_unit | Not used | Fixed unit_price per unit, regardless of volume |
| Tiered | tiered | PriceTier[] | Each unit charged at the rate of the tier it falls into (graduated) |
| Package | package | PackageConfig object | Usage rounded up to whole bundles; price is per bundle |
| Overage | overage | OverageConfig object | base_price covers included_units; overage_price per unit beyond that |
The tiers field is polymorphic — its structure depends on the pricing model. For tiered it is a JSON array; for package and overage it is a JSON object. The Go SDK accepts json.RawMessage; the JavaScript SDK accepts PriceTier[] | PackageConfig | OverageConfig.
Prerequisites
All examples assume you have already created a metric and a customer. See Metering and the Quickstart for how to create these.
1. Flat / Per-unit pricing
Every unit costs the same fixed amount regardless of how many units are consumed.
Model value: flat_unit (use PricingModel.Flat / monigo.PricingModelFlat in the SDKs)
Example: ₦2.00 per API call.
curl -X POST https://api.monigo.co/v1/plans \
-H "Authorization: Bearer mk_live_..." \
-H "Content-Type: application/json" \
-d '{
"name": "API Pro – Flat",
"currency": "NGN",
"plan_type": "collection",
"billing_period": "monthly",
"prices": [
{
"metric_id": "<metric_id>",
"model": "flat_unit",
"unit_price": "2.000000"
}
]
}'
plan, err := client.Plans.Create(ctx, monigo.CreatePlanRequest{
Name: "API Pro – Flat",
Currency: "NGN",
PlanType: monigo.PlanTypeCollection,
BillingPeriod: monigo.BillingPeriodMonthly,
Prices: []monigo.CreatePriceRequest{
{
MetricID: metricID,
Model: monigo.PricingModelFlat, // "flat_unit"
UnitPrice: "2.000000",
},
},
})
const plan = await client.plans.create({
name: 'API Pro – Flat',
currency: 'NGN',
plan_type: PlanType.Collection,
billing_period: BillingPeriod.Monthly,
prices: [
{
metric_id: metricId,
model: PricingModel.Flat, // 'flat_unit'
unit_price: '2.000000',
},
],
})
Invoice line item example (1 500 calls):
| Description | Qty | Unit price | Amount |
|---|
| API Calls | 1 500 | ₦2.00 | ₦3 000.00 |
2. Tiered pricing (graduated)
Usage is divided into bands. Each unit is charged at the rate of the tier it falls into. As volume grows, units in higher tiers get cheaper — but earlier units still cost their tier’s rate.
Model value: tiered
tiers field: A JSON array of { up_to, unit_amount } objects. The last tier must have up_to: null (infinity).
Example: ₦5 for the first 1 000 calls, ₦3 for the next 9 000, ₦1 beyond that.
curl -X POST https://api.monigo.co/v1/plans \
-H "Authorization: Bearer mk_live_..." \
-H "Content-Type: application/json" \
-d '{
"name": "API Pro – Tiered",
"currency": "NGN",
"plan_type": "collection",
"billing_period": "monthly",
"prices": [
{
"metric_id": "<metric_id>",
"model": "tiered",
"tiers": [
{ "up_to": 1000, "unit_amount": "5.000000" },
{ "up_to": 10000, "unit_amount": "3.000000" },
{ "up_to": null, "unit_amount": "1.000000" }
]
}
]
}'
tiersJSON, _ := json.Marshal([]monigo.PriceTier{
{UpTo: ptr(int64(1_000)), UnitAmount: "5.000000"},
{UpTo: ptr(int64(10_000)), UnitAmount: "3.000000"},
{UpTo: nil, UnitAmount: "1.000000"},
})
plan, err := client.Plans.Create(ctx, monigo.CreatePlanRequest{
Name: "API Pro – Tiered",
Currency: "NGN",
PlanType: monigo.PlanTypeCollection,
BillingPeriod: monigo.BillingPeriodMonthly,
Prices: []monigo.CreatePriceRequest{
{
MetricID: metricID,
Model: monigo.PricingModelTiered,
Tiers: tiersJSON,
},
},
})
const plan = await client.plans.create({
name: 'API Pro – Tiered',
currency: 'NGN',
plan_type: PlanType.Collection,
billing_period: BillingPeriod.Monthly,
prices: [
{
metric_id: metricId,
model: PricingModel.Tiered,
tiers: [
{ up_to: 1_000, unit_amount: '5.000000' },
{ up_to: 10_000, unit_amount: '3.000000' },
{ up_to: null, unit_amount: '1.000000' },
],
},
],
})
The final tier must always have up_to: null (REST/JS) or UpTo: nil (Go). Monigo rejects tier arrays that do not end with an open-ended tier.
Invoice line item example (12 000 calls):
| Tier | Units | Rate | Amount |
|---|
| Tier 1 (1 – 1 000) | 1 000 | ₦5.00 | ₦5 000.00 |
| Tier 2 (1 001 – 10 000) | 9 000 | ₦3.00 | ₦27 000.00 |
| Tier 3 (10 001+) | 2 000 | ₦1.00 | ₦2 000.00 |
| Total | 12 000 | | ₦34 000.00 |
3. Package pricing
Usage is sold in fixed-size bundles. Partial bundles are always rounded up to the next whole bundle.
Model value: package
tiers field: A PackageConfig object (not an array).
| Field | Type | Description |
|---|
package_size | integer | Number of units per bundle |
package_price | decimal string | Price per complete bundle |
round_up_partial_block | boolean | Round partial bundles up (true) or truncate (false) |
Example: ₦500 per bundle of 1 000 SMS. Sending 1 500 SMS → 2 bundles → ₦1 000.
curl -X POST https://api.monigo.co/v1/plans \
-H "Authorization: Bearer mk_live_..." \
-H "Content-Type: application/json" \
-d '{
"name": "SMS – Package",
"currency": "NGN",
"plan_type": "collection",
"billing_period": "monthly",
"prices": [
{
"metric_id": "<metric_id>",
"model": "package",
"tiers": {
"package_size": 1000,
"package_price": "500.000000",
"round_up_partial_block": true
}
}
]
}'
packageJSON, _ := json.Marshal(monigo.PackageConfig{
PackageSize: 1000,
PackagePrice: "500.000000",
RoundUpPartialBlock: true,
})
plan, err := client.Plans.Create(ctx, monigo.CreatePlanRequest{
Name: "SMS – Package",
Currency: "NGN",
PlanType: monigo.PlanTypeCollection,
BillingPeriod: monigo.BillingPeriodMonthly,
Prices: []monigo.CreatePriceRequest{
{
MetricID: metricID,
Model: monigo.PricingModelPackage,
Tiers: packageJSON,
},
},
})
const plan = await client.plans.create({
name: 'SMS – Package',
currency: 'NGN',
plan_type: PlanType.Collection,
billing_period: BillingPeriod.Monthly,
prices: [
{
metric_id: metricId,
model: PricingModel.Package,
tiers: {
package_size: 1000,
package_price: '500.000000',
round_up_partial_block: true,
},
},
],
})
Invoice line item example (1 500 SMS → 2 bundles):
| Description | Bundles | Price / bundle | Amount |
|---|
| SMS Sent (1 000 per bundle) | 2 | ₦500.00 | ₦1 000.00 |
4. Overage pricing
A flat base_price covers up to included_units. Every unit above that quota is charged at overage_price.
Model value: overage
tiers field: An OverageConfig object (not an array).
| Field | Type | Description |
|---|
included_units | integer | Free quota. Set to 0 for no included allowance. |
base_price | decimal string | Flat fee for usage up to included_units. Set to "0.000000" for no base fee. |
overage_price | decimal string | Per-unit rate applied to every unit above included_units. |
Charge formula:
if usage ≤ included_units:
charge = base_price
else:
charge = base_price + (usage − included_units) × overage_price
Example: 10 000 API calls included per month; ₦1.50 per call beyond that.
curl -X POST https://api.monigo.co/v1/plans \
-H "Authorization: Bearer mk_live_..." \
-H "Content-Type: application/json" \
-d '{
"name": "API Pro – Overage",
"currency": "NGN",
"plan_type": "collection",
"billing_period": "monthly",
"prices": [
{
"metric_id": "<metric_id>",
"model": "overage",
"tiers": {
"included_units": 10000,
"base_price": "0.000000",
"overage_price": "1.500000"
}
}
]
}'
overageJSON, _ := json.Marshal(monigo.OverageConfig{
IncludedUnits: 10_000,
BasePrice: "0.000000",
OveragePrice: "1.500000",
})
plan, err := client.Plans.Create(ctx, monigo.CreatePlanRequest{
Name: "API Pro – Overage",
Currency: "NGN",
PlanType: monigo.PlanTypeCollection,
BillingPeriod: monigo.BillingPeriodMonthly,
Prices: []monigo.CreatePriceRequest{
{
MetricID: metricID,
Model: monigo.PricingModelOverage,
Tiers: overageJSON,
},
},
})
const plan = await client.plans.create({
name: 'API Pro – Overage',
currency: 'NGN',
plan_type: PlanType.Collection,
billing_period: BillingPeriod.Monthly,
prices: [
{
metric_id: metricId,
model: PricingModel.Overage,
tiers: {
included_units: 10_000,
base_price: '0.000000',
overage_price: '1.500000',
},
},
],
})
Invoice line item example (13 500 calls):
| Description | Qty | Rate | Amount |
|---|
| API Calls (included) | 10 000 | ₦0.00 | ₦0.00 |
| API Calls (overage) | 3 500 | ₦1.50 | ₦5 250.00 |
Set included_units: 0 and base_price: "0.000000" for a pure overage plan with no free tier — every unit is charged at overage_price from the first unit.
Choosing a model
| Scenario | Recommended model |
|---|
| Simple, predictable per-unit pricing | flat_unit |
| Reward heavy usage with progressively cheaper rates | tiered |
| Sell credits, messages, or API calls in bundles | package |
| Include a free quota then charge beyond it | overage |
Combining multiple prices on one plan
A plan can carry multiple prices — one per metric. Each price is calculated independently and totals are summed on the invoice.
curl -X POST https://api.monigo.co/v1/plans \
-H "Authorization: Bearer mk_live_..." \
-H "Content-Type: application/json" \
-d '{
"name": "Platform Pro",
"currency": "NGN",
"plan_type": "collection",
"billing_period": "monthly",
"prices": [
{
"metric_id": "<api_calls_metric_id>",
"model": "tiered",
"tiers": [
{ "up_to": 10000, "unit_amount": "2.000000" },
{ "up_to": null, "unit_amount": "0.500000" }
]
},
{
"metric_id": "<sms_metric_id>",
"model": "package",
"tiers": {
"package_size": 1000,
"package_price": "500.000000",
"round_up_partial_block": true
}
}
]
}'
Complete runnable examples
The Monigo SDKs ship with a pricing-models example that creates all four plan types, subscribes a customer to each, and prints a summary.
# Go SDK
MONIGO_API_KEY=mk_test_... go run ./examples/pricing-models
# JavaScript / TypeScript SDK
cd examples && MONIGO_API_KEY=mk_test_... npm run pricing-models
See the Go SDK and JavaScript SDK reference for full installation instructions.