Charges API
Complete API reference for managing charge templates and pricing in the Billerang catalog.
Overview
A ChargeTemplate defines how a product is priced. Billerang supports four charge types, each with its own billing behavior:
| Type | Code | Billing Trigger | Example |
|---|---|---|---|
| Recurring | RECURRING | Calendar-based (monthly, annual) | Monthly subscription fee |
| Subscription | SUBSCRIPTION | On subscription activation | Setup fee |
| Termination | TERMINATION | On subscription cancellation | Early termination fee |
| Usage | USAGE | Per CDR/EDR event | API calls, data transfer |
| Other | OTHER | Manual application | Ad-hoc charges |
Endpoints
List Charges
GET /v1/catalog/charges?range=0-24&type=recurring&status=active
Query Parameters:
| Parameter | Type | Description |
|---|---|---|
range | string | Pagination range |
type | string | Filter: recurring, subscription, termination, usage, other |
status | string | Filter: draft, active, archived |
invoice_category | string | Filter by invoice sub-category |
expand | string | Include: pricing, pricing.versions |
Response:
[
{
"code": "RC_PLATFORM_MONTHLY",
"name": "Monthly Platform Fee",
"type": "recurring",
"status": "active",
"invoice_category": "ISC_SUBSCRIPTION",
"pricing_mode": "FLAT"
}
]
Get Charge
GET /v1/catalog/charges/{code}?expand=pricing
Response:
{
"code": "RC_PLATFORM_MONTHLY",
"name": "Monthly Platform Fee",
"type": "recurring",
"status": "active",
"invoice_category": "ISC_SUBSCRIPTION",
"tax_class": "TAX_STANDARD",
"accounting_article": "ART_PLATFORM",
"amount_editable": false,
"unit": {
"input": "each",
"rating": "each",
"multiplier": 1,
"decimals": 2
},
"recurring": {
"calendar": "MONTHLY",
"prorate_on_start": true,
"prorate_on_end": true,
"charge_in_advance": true,
"duration_months": null
},
"pricing": {
"mode": "FLAT",
"base_currency": "USD",
"dimensions": [],
"versions": [
{
"version": 1,
"status": "published",
"valid_from": "2024-01-01T00:00:00Z",
"price": 99.00
}
]
}
}
Create/Upsert Charge
POST /v1/catalog/charges/{code}
UPSERT semantics: creates if not found, updates if exists.
Recurring Charge Example
{
"code": "RC_PLATFORM_MONTHLY",
"name": "Monthly Platform Fee",
"type": "recurring",
"invoice_category": "ISC_SUBSCRIPTION",
"tax_class": "TAX_STANDARD",
"recurring": {
"calendar": "MONTHLY",
"prorate_on_start": true,
"prorate_on_end": true,
"charge_in_advance": true
},
"pricing": {
"mode": "FLAT",
"base_currency": "USD",
"price": 99.00,
"auto_publish": true
}
}
Usage Charge Example
{
"code": "UC_API_CALLS",
"name": "API Call Usage",
"type": "usage",
"invoice_category": "ISC_USAGE",
"tax_class": "TAX_STANDARD",
"usage": {
"filter_expression": "#{edr.parameter1 == 'API_CALL'}",
"priority": 1,
"counter_code": "CTR_MONTHLY_CALLS"
},
"pricing": {
"mode": "TIERED",
"base_currency": "USD",
"tiers": [
{ "from": 0, "to": 100000, "rate": 0.001 },
{ "from": 100001, "to": 1000000, "rate": 0.0008 },
{ "from": 1000001, "to": null, "rate": 0.0005 }
],
"auto_publish": true
}
}
One-Shot Charge Example
{
"code": "OS_SETUP_FEE",
"name": "Setup Fee",
"type": "subscription",
"invoice_category": "ISC_SETUP",
"one_shot": {
"immediate_invoicing": true
},
"pricing": {
"mode": "FLAT",
"base_currency": "USD",
"price": 499.00
}
}
Update Charge
PUT /v1/catalog/charges/{code}
Partial update. Change status, pricing, or any field:
{
"status": "active",
"name": "Updated Monthly Fee"
}
Delete Charge
DELETE /v1/catalog/charges/{code}
Only allowed for draft charges not linked to any product.
Pricing Modes
FLAT
Fixed price regardless of quantity.
{ "mode": "FLAT", "base_currency": "USD", "price": 99.00 }
PER_UNIT
Price multiplied by quantity.
{ "mode": "PER_UNIT", "base_currency": "USD", "price": 0.10 }
TIERED
Different rates at quantity thresholds (incremental).
{
"mode": "TIERED",
"base_currency": "USD",
"tiers": [
{ "from": 0, "to": 1000000, "rate": 0.002 },
{ "from": 1000001, "to": 10000000, "rate": 0.0015 },
{ "from": 10000001, "to": null, "rate": 0.001 }
]
}
Calculation for 15M tokens:
- First 1M: 1,000K * $0.002 = $2.00
- Next 9M: 9,000K * $0.0015 = $13.50
- Last 5M: 5,000K * $0.001 = $5.00
- Total: $20.50
VOLUME
Rate applies to ALL units once threshold is reached.
{
"mode": "VOLUME",
"base_currency": "USD",
"tiers": [
{ "from": 0, "to": 9999, "rate": 1.00 },
{ "from": 10000, "to": null, "rate": 0.80 }
]
}
MATRIX
Multi-dimensional pricing with dimension columns and price rows.
{
"mode": "MATRIX",
"base_currency": "USD",
"dimensions": [
{ "code": "REGION", "type": "String", "label": "Region" },
{ "code": "TIER", "type": "String", "label": "Customer Tier" }
],
"rows": [
{
"priority": 1,
"values": [
{ "dimensionCode": "REGION", "stringValue": "US" },
{ "dimensionCode": "TIER", "stringValue": "enterprise" }
],
"price": 500.00
},
{
"priority": 99,
"description": "Default fallback",
"price": 600.00
}
]
}
Matching logic:
- Find row with highest priority number of matching dimensions
nullvalues are wildcards (match anything)- Default row (priority 99, all nulls) is the fallback
FORMULA
Custom EL expression for dynamic pricing.
{
"mode": "FORMULA",
"base_currency": "USD",
"price_formula": "#{basePrice * (1 - billingAccount.cfValue('negotiated_discount'))}"
}
CUSTOM_SCRIPT
Groovy/Java script for complex pricing logic.
{
"mode": "CUSTOM_SCRIPT",
"base_currency": "USD",
"rating_script_code": "SCRIPT_COST_PLUS_MARGIN"
}
Pricing Versions
Each charge's pricing is versioned independently.
Create New Version
When you update pricing on an active charge, a new version is created:
{
"pricing": {
"mode": "FLAT",
"base_currency": "USD",
"price": 119.00,
"validity": { "from": "2025-01-01T00:00:00Z" },
"version_status": "DRAFT"
}
}
Publish Version
PUT /v1/catalog/price_plan_versions/{id}
{ "status": "published" }
Version Lifecycle
Rules:
- Only one version can be
PUBLISHEDat a time - Publishing closes the previous version
- Rating engine uses the version whose validity matches the billing date
Multi-Currency Support
{
"pricing": {
"mode": "FLAT",
"base_currency": "USD",
"price": 99.00,
"currency_prices": [
{ "currency_code": "EUR", "price": 89.00, "use_for_billing_accounts": true },
{ "currency_code": "GBP", "price": 79.00, "use_for_billing_accounts": true },
{ "currency_code": "BRL", "exchange_rate": 5.2 }
]
}
}
price: fixed price in that currency (overrides exchange rate)exchange_rate: multiply base price by this rateuse_for_billing_accounts: use this currency for BAs set to this currency
Charge Status Lifecycle
Usage Charge Filtering
Usage charges match incoming CDR/EDR events using filter parameters:
| Field | Purpose | Example |
|---|---|---|
filter_expression | EL expression for complex matching | #{edr.parameter1 == 'API_CALL'} |
priority | Matching order (lower = higher priority) | 1 |
counter_code | Linked counter for included units | CTR_MONTHLY_TOKENS |
See Multi-Instance Matching for advanced EDR routing patterns.
Error Codes
| Error Code | HTTP | Description |
|---|---|---|
CHARGE_NOT_FOUND | 404 | Charge code doesn't exist |
CHARGE_ALREADY_EXISTS | 409 | Duplicate charge code |
CHARGE_VALIDATION_FAILED | 400 | Invalid payload |
CHARGE_STATUS_TRANSITION_INVALID | 422 | Invalid status change |
CHARGE_HAS_ACTIVE_PRODUCTS | 422 | Cannot delete charge linked to products |
PRICING_VERSION_NOT_FOUND | 404 | Pricing version doesn't exist |
PRICING_VALIDATION_FAILED | 400 | Invalid pricing configuration |