Billing rules let you define conditional logic that modifies how sessions are priced. A rule is made up of conditions — criteria that must be true for the rule to fire — and actions — the pricing modifications to apply when they do.
Rules are evaluated at session close. When multiple rules match a session, they are applied in priority order (lowest number = highest priority).
Conditions
Condition Description time_of_dayMatches sessions that started between two times (e.g. 07:00–09:00) day_of_weekMatches sessions on specific days (e.g. ["sat", "sun"]) user_typeMatches sessions where the driver belongs to a named user type charger_idMatches sessions on a specific charger site_idMatches sessions at a specific site min_energy_kwhMatches sessions delivering at least N kWh max_energy_kwhMatches sessions delivering at most N kWh
Actions
Action Description apply_discountReduce the total cost by a percentage override_priceReplace the per-kWh rate with a fixed value free_sessionSet the total cost to zero add_flat_feeAdd a fixed amount to the total remove_componentRemove a specific tariff component (e.g. remove parking fee)
Create a billing rule
POST /api/v1/billing/rules
Display name for the rule.
Evaluation order. Lower numbers are evaluated first. Must be a positive integer.
Array of condition objects. All conditions must match for the rule to fire. Show condition properties
Condition type. See condition table above.
The value to match against. Type varies by condition: string, string array, or number.
Array of action objects to apply when conditions are met. Action type. See action table above.
Action parameter. For apply_discount, this is the percentage (e.g. 10 for 10%). For override_price, this is the new price per kWh. Omit for free_session.
Whether the rule is active. Inactive rules are stored but never evaluated.
curl -X POST "https://api.dynamo-csms.com/api/v1/billing/rules" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "Weekend off-peak discount",
"priority": 10,
"active": true,
"conditions": [
{
"type": "day_of_week",
"value": ["sat", "sun"]
},
{
"type": "time_of_day",
"value": { "start": "21:00", "end": "07:00" }
}
],
"actions": [
{
"type": "apply_discount",
"value": 25
}
]
}'
{
"rule_id" : "rule_8MXQP" ,
"name" : "Weekend off-peak discount" ,
"priority" : 10 ,
"active" : true ,
"conditions" : [
{ "type" : "day_of_week" , "value" : [ "sat" , "sun" ] },
{ "type" : "time_of_day" , "value" : { "start" : "21:00" , "end" : "07:00" } }
],
"actions" : [
{ "type" : "apply_discount" , "value" : 25 }
],
"created_at" : "2024-06-01T12:00:00Z"
}
Unique identifier for the created rule.
Evaluation order for this rule.
Whether the rule is currently being evaluated.
List billing rules
GET /api/v1/billing/rules
Returns all billing rules for your organisation, ordered by priority.
Filter by active status. Set to true to return only active rules.
curl "https://api.dynamo-csms.com/api/v1/billing/rules" \
-H "Authorization: Bearer YOUR_API_KEY"
{
"rules" : [
{
"rule_id" : "rule_8MXQP" ,
"name" : "Weekend off-peak discount" ,
"priority" : 10 ,
"active" : true ,
"conditions" : [
{ "type" : "day_of_week" , "value" : [ "sat" , "sun" ] }
],
"actions" : [
{ "type" : "apply_discount" , "value" : 25 }
],
"created_at" : "2024-06-01T12:00:00Z"
},
{
"rule_id" : "rule_3KLPN" ,
"name" : "Free sessions for staff" ,
"priority" : 1 ,
"active" : true ,
"conditions" : [
{ "type" : "user_type" , "value" : "staff" }
],
"actions" : [
{ "type" : "free_session" }
],
"created_at" : "2024-06-01T11:00:00Z"
}
],
"total" : 2
}
Get a billing rule
GET /api/v1/billing/rules/{rule_id}
The unique identifier of the billing rule.
curl "https://api.dynamo-csms.com/api/v1/billing/rules/rule_8MXQP" \
-H "Authorization: Bearer YOUR_API_KEY"
Update a billing rule
PUT /api/v1/billing/rules/{rule_id}
Replaces all fields on a billing rule. Changes apply to sessions closed after the update.
The unique identifier of the billing rule.
Full replacement condition set.
Full replacement action set.
curl -X PUT "https://api.dynamo-csms.com/api/v1/billing/rules/rule_8MXQP" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "Weekend off-peak discount",
"priority": 10,
"active": false,
"conditions": [
{ "type": "day_of_week", "value": ["sat", "sun"] }
],
"actions": [
{ "type": "apply_discount", "value": 25 }
]
}'
Delete a billing rule
DELETE /api/v1/billing/rules/{rule_id}
The unique identifier of the billing rule to delete.
curl -X DELETE "https://api.dynamo-csms.com/api/v1/billing/rules/rule_8MXQP" \
-H "Authorization: Bearer YOUR_API_KEY"
Returns 204 No Content on success.
Test a billing rule
POST /api/v1/billing/rules/{rule_id}/test
Evaluates a rule against a hypothetical session without creating any real charges. Use this to verify that your conditions and actions behave as expected before activating a rule.
Hypothetical session data to test against. ISO 8601 session start time.
ISO 8601 session end time.
Charger the session was on.
Starting cost before any rules are applied.
curl -X POST "https://api.dynamo-csms.com/api/v1/billing/rules/rule_8MXQP/test" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"session": {
"started_at": "2024-06-15T22:30:00Z",
"ended_at": "2024-06-16T00:15:00Z",
"energy_kwh": 12.8,
"charge_point_id": "CP-001",
"site_id": "site_01HZ4K8XVPQR3TY5N6M",
"user_type": "public",
"base_cost": 4.48,
"currency": "GBP"
}
}'
{
"rule_id" : "rule_8MXQP" ,
"rule_name" : "Weekend off-peak discount" ,
"matched" : true ,
"conditions_evaluated" : [
{ "type" : "day_of_week" , "value" : [ "sat" , "sun" ], "result" : true },
{ "type" : "time_of_day" , "value" : { "start" : "21:00" , "end" : "07:00" }, "result" : true }
],
"actions_applied" : [
{ "type" : "apply_discount" , "value" : 25 , "description" : "25% discount applied" }
],
"base_cost" : 4.48 ,
"adjusted_cost" : 3.36 ,
"savings" : 1.12 ,
"currency" : "GBP"
}
Whether all conditions matched the hypothetical session.
Each condition and whether it matched.
Actions that were applied and a description of the effect.
Cost before the rule was applied.
Cost after the rule was applied.
Difference between base cost and adjusted cost.