Skip to main content
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

ConditionDescription
time_of_dayMatches sessions that started between two times (e.g. 07:0009: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

ActionDescription
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
name
string
required
Display name for the rule.
priority
number
required
Evaluation order. Lower numbers are evaluated first. Must be a positive integer.
conditions
object[]
required
Array of condition objects. All conditions must match for the rule to fire.
actions
object[]
required
Array of action objects to apply when conditions are met.
active
boolean
default:"true"
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"
}
rule_id
string
Unique identifier for the created rule.
priority
number
Evaluation order for this rule.
active
boolean
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.
active
boolean
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}
rule_id
string
required
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.
rule_id
string
required
The unique identifier of the billing rule.
name
string
required
Updated rule name.
priority
number
required
Updated priority.
conditions
object[]
required
Full replacement condition set.
actions
object[]
required
Full replacement action set.
active
boolean
required
Active status.
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}
rule_id
string
required
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.
rule_id
string
required
The rule to test.
session
object
required
Hypothetical session data to test against.
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"
}
matched
boolean
Whether all conditions matched the hypothetical session.
conditions_evaluated
object[]
Each condition and whether it matched.
actions_applied
object[]
Actions that were applied and a description of the effect.
base_cost
number
Cost before the rule was applied.
adjusted_cost
number
Cost after the rule was applied.
savings
number
Difference between base cost and adjusted cost.