Description
Overview
The Tariffs API provides functionality for managing pricing and fee calculations:
- Tariff management (CRUD operations)
- Fee range definitions
- Velocity rules
- Fee calculations
- Multi-currency support
- Channel-based pricing
- Asset-specific fees
Core Concepts
Fee Calculation Methods
fixed: Fixed amount feepercentage: Percentage of transaction amountgreater: Greater of fixed or percentagelesser: Lesser of fixed or percentagesum: Sum of fixed and percentage
Transaction Types
- Transaction type filtering is available for both fee ranges and velocity rules
- Valid values: Product codes of type
transfers(e.g.,iwt,owt,int,own,crw) oranyfor all transaction types - The transaction type must be an active product in the
products.productstable withtype = 'transfers' - Use
anyto apply the rule to all transaction types
Velocity Types
transaction_count: Limit number of transactionsamount: Limit total transaction amount
Velocity Intervals
once: One-time limitdaily: Daily limitweekly: Weekly limitmonthly: Monthly limitquarterly: Quarterly limit (3 months)annually: Annual limit
Endpoints
Tariff Management
Create Tariff
POST /v1/tariffs
Create a new tariff.
Request Body:
{
"name": "standard",
"description": "Standard pricing tier",
"fallback_tariff_id": "uuid",
"active": true,
"default": false
}Response:
{
"id": "uuid",
"name": "standard",
"description": "Standard pricing tier",
"fallback_tariff_id": "uuid",
"active": true,
"default": false,
"created_at": "timestamp",
"created_by": "uuid"
}Get Tariff
GET /v1/tariffs/{id}
Get a specific tariff.
Response:
{
"id": "uuid",
"name": "standard",
"description": "Standard pricing tier",
"fallback_tariff_id": "uuid",
"active": true,
"default": true,
"fee_ranges": [
{
"id": "uuid",
"range_start": 0,
"range_end": 1000,
"fixed_fee": 2.5,
"percent_fee": 1.0,
"method": "sum",
"min_fee": 2.0,
"max_fee": 20.0,
"media": "card",
"asset": "EUR",
"from_channel": "pos",
"to_channel": "bank_account",
"transaction_type": "iwt",
"valid_from": "2024-01-01T00:00:00Z",
"valid_to": "2024-12-31T23:59:59Z"
}
],
"velocity_rules": [
{
"id": "uuid",
"type": "transaction_count",
"interval": "daily",
"limit": 1000,
"transaction_type": "any",
"active": true
}
]
}Update Tariff
PUT /v1/tariffs/{id}
Update an existing tariff.
Request Body:
{
"name": "standard",
"description": "Updated standard pricing tier",
"fallback_tariff_id": "uuid",
"active": true,
"default": false
}Delete Tariff
DELETE /v1/tariffs/{id}
Delete a tariff and all associated fee ranges and velocity rules.
Get All Tariffs
GET /v1/tariffs
Retrieve all tariffs.
Query Parameters:
- active: Filter by active status
- name: Filter by name
- search: Search in name/description
Response:
[
{
"id": "uuid",
"name": "standard",
"description": "Standard pricing tier",
"fallback_tariff_id": "uuid",
"active": true,
"default": true,
"fee_ranges": [
{
"id": "uuid",
"range_start": 0,
"range_end": 1000,
"fixed_fee": 2.5,
"percent_fee": 1.0,
"method": "sum",
"min_fee": 2.0,
"max_fee": 20.0,
"transaction_type": "iwt"
}
],
"velocity_rules": [
{
"id": "uuid",
"type": "transaction_count",
"interval": "daily",
"limit": 1000,
"transaction_type": "any"
}
]
}
]Clone Tariff
POST /v1/tariffs/{id}/clone
Duplicates a tariff with a new ID, copying all fee ranges and velocity rules. The clone is never marked as default.
Request Body (optional):
{
"name": "Copy of Standard"
}When name is omitted, the server uses Copy of {source name} and appends (n) if that name already exists.
Response: 201 Created with the full tariff (including fee_ranges and velocity_rules).
Export Tariff Seeds to Server DATA_DIR
POST /v1/tariffs/export-seed
Writes one .import.json file per tariff under DATA_DIR/tariffs on the API host.
If tariff_ids is omitted or empty, all tariffs are exported.
Request Body:
{
"tariff_ids": ["uuid"]
}Response:
{
"dir": "/abs/path/to/DATA_DIR/tariffs",
"written": [
{
"tariff_id": "uuid",
"name": "standard",
"filename": "standard-2f4c8b1d.import.json",
"path": "/abs/path/to/DATA_DIR/tariffs/standard-2f4c8b1d.import.json"
}
]
}Fee Range Management
Create Fee Range
POST /v1/tariffs/ranges
Create a new fee range.
Request Body:
{
"tariff_id": "uuid",
"range_start": 0,
"range_end": 1000,
"fixed_fee": 2.5,
"percent_fee": 1.0,
"method": "sum",
"min_fee": 2.0,
"max_fee": 20.0,
"media": "card",
"asset": "EUR",
"from_channel": "pos",
"to_channel": "bank_account",
"transaction_type": "iwt",
"valid_from": "2024-01-01T00:00:00Z",
"valid_to": "2024-12-31T23:59:59Z",
"active": true
}Get Fee Range
GET /v1/tariffs/ranges/{range_id}
Get a specific fee range.
Response:
{
"id": "uuid",
"tariff_id": "uuid",
"range_start": 0,
"range_end": 1000,
"fixed_fee": 2.5,
"percent_fee": 1.0,
"method": "sum",
"min_fee": 2.0,
"max_fee": 20.0,
"media": "card",
"asset": "EUR",
"from_channel": "pos",
"to_channel": "bank_account",
"transaction_type": "iwt",
"valid_from": "2024-01-01T00:00:00Z",
"valid_to": "2024-12-31T23:59:59Z",
"active": true
}Update Fee Range
PUT /v1/tariffs/ranges/{range_id}
Update an existing fee range.
Request Body:
{
"tariff_id": "uuid",
"range_start": 0,
"range_end": 2000,
"fixed_fee": 3.0,
"percent_fee": 1.5,
"method": "sum",
"min_fee": 3.0,
"max_fee": 25.0,
"media": "card",
"asset": "EUR",
"from_channel": "pos",
"to_channel": "bank_account",
"transaction_type": "iwt",
"valid_from": "2024-01-01T00:00:00Z",
"valid_to": "2024-12-31T23:59:59Z",
"active": true
}Delete Fee Range
DELETE /v1/tariffs/ranges/{range_id}
Delete a fee range.
Velocity Rule Management
Create Velocity Rule
POST /v1/tariffs/velocity-rules
Create a new velocity rule.
Request Body:
{
"tariff_id": "uuid",
"reference_id": "customer_12345",
"type": "transaction_count",
"interval": "daily",
"limit": 1000,
"media": "card",
"asset": "EUR",
"from_channel": "pos",
"to_channel": "bank_account",
"transaction_type": "iwt",
"valid_from": "2024-01-01T00:00:00Z",
"valid_to": "2024-12-31T23:59:59Z",
"priority": 10,
"active": true
}Response:
{
"id": "uuid",
"tariff_id": "uuid",
"reference_id": "customer_12345",
"type": "transaction_count",
"interval": "daily",
"limit": 1000,
"media": "card",
"asset": "EUR",
"from_channel": "pos",
"to_channel": "bank_account",
"transaction_type": "iwt",
"valid_from": "2024-01-01T00:00:00Z",
"valid_to": "2024-12-31T23:59:59Z",
"priority": 10,
"active": true,
"created_at": "timestamp",
"created_by": "uuid",
"modified_at": "timestamp",
"modified_by": "uuid",
"metadata": {}
}Get Velocity Rule
GET /v1/tariffs/velocity-rules/{rule_id}
Get a specific velocity rule.
Response:
{
"id": "uuid",
"tariff_id": "uuid",
"reference_id": "customer_12345",
"type": "transaction_count",
"interval": "daily",
"limit": 1000,
"media": "card",
"asset": "EUR",
"from_channel": "pos",
"to_channel": "bank_account",
"transaction_type": "iwt",
"valid_from": "2024-01-01T00:00:00Z",
"valid_to": "2024-12-31T23:59:59Z",
"priority": 10,
"active": true,
"created_at": "timestamp",
"created_by": "uuid",
"modified_at": "timestamp",
"modified_by": "uuid",
"metadata": {}
}Update Velocity Rule
PUT /v1/tariffs/velocity-rules/{rule_id}
Update an existing velocity rule.
Request Body:
{
"reference_id": "customer_12345",
"type": "amount",
"interval": "monthly",
"limit": 50000,
"media": "any",
"asset": "EUR",
"from_channel": "any",
"to_channel": "any",
"transaction_type": "any",
"valid_from": "2024-01-01T00:00:00Z",
"valid_to": "2024-12-31T23:59:59Z",
"priority": 5,
"active": true
}Note: The reference_id field is optional in update requests. If not provided, the existing value will be preserved.
Response:
{
"id": "uuid",
"tariff_id": "uuid",
"reference_id": "customer_12345",
"type": "amount",
"interval": "monthly",
"limit": 50000,
"media": "any",
"asset": "EUR",
"from_channel": "any",
"to_channel": "any",
"transaction_type": "any",
"valid_from": "2024-01-01T00:00:00Z",
"valid_to": "2024-12-31T23:59:59Z",
"priority": 5,
"active": true,
"created_at": "timestamp",
"created_by": "uuid",
"modified_at": "timestamp",
"modified_by": "uuid",
"metadata": {}
}Delete Velocity Rule
DELETE /v1/tariffs/velocity-rules/{rule_id}
Delete a velocity rule.
Get Tariff Velocity Rules
GET /v1/tariffs/{id}/velocity-rules
Get all velocity rules for a specific tariff.
Response:
[
{
"id": "uuid",
"tariff_id": "uuid",
"reference_id": "customer_12345",
"type": "transaction_count",
"interval": "daily",
"limit": 1000,
"media": "card",
"asset": "EUR",
"from_channel": "pos",
"to_channel": "bank_account",
"transaction_type": "iwt",
"valid_from": "2024-01-01T00:00:00Z",
"valid_to": "2024-12-31T23:59:59Z",
"priority": 10,
"active": true,
"created_at": "timestamp",
"created_by": "uuid",
"modified_at": "timestamp",
"modified_by": "uuid",
"metadata": {}
},
{
"id": "uuid",
"tariff_id": "uuid",
"reference_id": "global",
"type": "amount",
"interval": "monthly",
"limit": 50000,
"media": "any",
"asset": "EUR",
"from_channel": "any",
"to_channel": "any",
"transaction_type": "any",
"valid_from": "2024-01-01T00:00:00Z",
"valid_to": "2024-12-31T23:59:59Z",
"priority": 5,
"active": true,
"created_at": "timestamp",
"created_by": "uuid",
"modified_at": "timestamp",
"modified_by": "uuid",
"metadata": {}
}
]Fee Calculation
Calculate Fee
POST /v1/tariffs/calculate-fee
Calculate transaction fee.
Parameters:
value_date(optional): Future date for tariff calculation. If not provided, current date is used. Useful for calculating fees for future transactions based on scheduled tariff changes.
Velocity reference: Provide either customer_id (recommended) or reference_id. When customer_id is set, the API resolves reference_id from customer metadata as {customer_id}:{package_year} (customers.metadata.package_year, default year 1). With commit: true, pass transfer_id so velocity commits are idempotent per transfer and matched rule (transfer_id:rule_id).
Channel filters: from_channel and to_channel are optional. When omitted or sent as an empty string, the server defaults both to any (wildcard matching against fee ranges and velocity rules that use any).
Request Body:
The amount field uses the CcyAmt format — a monetary amount in minor/atomic units with its currency code. See Currencies - CcyAmt for details.
{
"customer_id": "uuid",
"transfer_id": "uuid",
"amount": {
"amount": "10000",
"currency": "EUR"
},
"asset": "EUR",
"from_channel": "pos",
"to_channel": "bank_account",
"media": "card",
"transaction_type": "iwt",
"value_date": "2024-12-25T10:00:00Z",
"commit": true
}| Field | Type | Description |
|---|---|---|
customer_id | uuid | Optional. Resolves velocity reference_id from customer metadata; use instead of sending reference_id manually |
reference_id | string | Optional when customer_id is set. Required when customer_id is omitted (explicit velocity bucket key) |
transfer_id | uuid | Optional. When commit is true, scopes velocity commit idempotency per transfer and rule |
amount.amount | string | Amount in minor units (e.g., "10000" = 100.00 EUR with precision 2) |
amount.currency | string | ISO currency code or asset code (e.g., "EUR", "USDC") |
asset | string | Asset filter for fee range matching. If omitted or "any", the currency from amount is used for fee denomination |
from_channel | string | Optional. Origin channel filter; defaults to any when omitted or empty |
to_channel | string | Optional. Destination channel filter; defaults to any when omitted or empty |
media | string | Required. Payment media filter (e.g. card, any) |
commit | boolean | When true, records velocity usage for matched rules |
Response:
Monetary fee fields (fixed_fee, total_fee, min_fee, max_fee) are returned in CcyAmtWithPrecision format — minor units with currency and precision metadata. The percent_fee remains a numeric rate.
{
"tariff_id": "uuid",
"tariff_name": "standard",
"fee_range_id": "uuid",
"fixed_fee": {
"amount": "250",
"currency": "EUR",
"precision": 2
},
"percent_fee": 1.0,
"total_fee": {
"amount": "350",
"currency": "EUR",
"precision": 2
},
"min_fee": {
"amount": "200",
"currency": "EUR",
"precision": 2
},
"max_fee": {
"amount": "2000",
"currency": "EUR",
"precision": 2
},
"method": "sum",
"is_fallback": false
}| Field | Type | Description |
|---|---|---|
fixed_fee | CcyAmtWithPrecision | Fixed component of the fee in minor units |
percent_fee | number | Percentage rate applied to the amount (e.g., 1.0 = 1%) |
total_fee | CcyAmtWithPrecision | Total calculated fee in minor units |
min_fee | CcyAmtWithPrecision | Minimum fee cap in minor units |
max_fee | CcyAmtWithPrecision | Maximum fee cap in minor units |
:::tip Converting to major units
To convert any CcyAmtWithPrecision value to major units: major = parseInt(amount) / 10^precision.
For example, {"amount": "350", "currency": "EUR", "precision": 2} = 3.50 EUR.
:::
Get customer velocity usage
GET /v1/tariffs/customers/{customer_id}/velocity-usage
Returns RAM-backed velocity usage for the customer's transfer and FX tariffs: per-rule used, limit, remaining, exceeded, ttl_seconds, and bucket_resets_at. Requires read permission on the customer record. transfer lists payment-tariff rules; fx lists FX spread rules (empty array when not applicable).
{
"customer_id": "uuid",
"package_year": 2,
"reference_id": "uuid:2",
"transfer": [
{
"velocity_rule_id": "uuid",
"tariff_id": "uuid",
"tariff_kind": "transfer",
"type": "amount",
"interval": "annual",
"limit": 100000,
"used": 2500,
"remaining": 97500,
"exceeded": false,
"package_year": 2,
"reference_id": "uuid:2",
"ttl_seconds": 86400,
"bucket_resets_at": "2026-12-31T23:59:59Z",
"asset": "EUR",
"media": "any",
"transaction_type": "any"
}
],
"fx": []
}DSL Action Output
When fee calculation is invoked via the DSL transfer action, the output map provides both major units (backwards-compatible) and minor units for monetary amounts. The transaction amount / amount_minor is included for consistency with the exchange action, enabling uniform access to $state.*.amount_minor:
{
"amount": 200.00,
"amount_minor": 20000,
"tariff_id": "uuid",
"tariff_name": "standard",
"fee_range_id": "uuid",
"fixed_fee": 2.50,
"percent_fee": 1.0,
"total_fee": 3.50,
"min_fee": 2.00,
"max_fee": 20.00,
"method": "sum",
"is_fallback": false,
"currency": "EUR",
"precision": 2,
"total_fee_minor": 350,
"fixed_fee_minor": 250,
"percent_fee_minor": 1.0,
"min_fee_minor": 200,
"max_fee_minor": 2000
}| Field | Type | Description |
|---|---|---|
amount | number | Transaction amount in major units (e.g., 200.00) |
amount_minor | integer | Transaction amount in minor/atomic units (e.g., 20000) |
total_fee | number | Total calculated fee in major units (backwards-compatible) |
total_fee_minor | integer | Total calculated fee in minor/atomic units |
fixed_fee | number | Fixed fee component in major units |
fixed_fee_minor | integer | Fixed fee component in minor units |
percent_fee | number | Percentage rate (not a monetary amount, same in both) |
percent_fee_minor | number | Same as percent_fee (rate, not minor units) |
min_fee / min_fee_minor | number / integer | Minimum fee cap in major / minor units |
max_fee / max_fee_minor | number / integer | Maximum fee cap in major / minor units |
currency | string | Fee currency code |
precision | integer | Number of decimal places for the currency |
:::tip DSL path references
Use $state.tariff.amount_minor for the transaction amount and $state.tariff.total_fee_minor for fees in DSL expressions. Both transfer and exchange actions provide amount_minor, so you can access $state.*.amount_minor uniformly.
:::
Dictionary Endpoints
Get Asset Types
GET /v1/tariffs/asset-types
Get available asset types.
Response:
[
{
"name": "EUR",
"description": "Euro"
},
{
"name": "USD",
"description": "US Dollar"
}
]Get Channels
GET /v1/tariffs/channels
Get available channels.
Response:
[
{
"name": "pos",
"description": "Point of Sale"
},
{
"name": "bank_account",
"description": "Bank Account"
}
]Get Media Types
GET /v1/tariffs/media-types
Get available media types.
Response:
[
{
"name": "card",
"description": "Payment Card"
},
{
"name": "bank_transfer",
"description": "Bank Transfer"
}
]Get Fee Methods
GET /v1/tariffs/fee-methods
Get available fee calculation methods.
Response:
[
"fixed",
"percentage",
"greater",
"lesser",
"sum"
]Get Velocity Types
GET /v1/tariffs/velocity-types
Get available velocity types.
Response:
[
"transaction_count",
"amount"
]Get Velocity Intervals
GET /v1/tariffs/velocity-intervals
Get available velocity intervals.
Response:
[
"once",
"daily",
"weekly",
"monthly",
"quarterly",
"annually"
]Error Handling
All errors follow a standard format:
{
"code": "error_code",
"message": "Error description"
}Error Codes
General Errors
| Code | Description |
|---|---|
| tariffs_m.tariff_not_found | Tariff not found |
| tariffs_m.tariff_already_exists | Tariff with this name already exists |
| tariffs_m.invalid_tariff_data | Invalid tariff data provided |
| tariffs_m.insufficient_rights | Insufficient permissions |
| tariffs_m.default_tariff_exists | Another default tariff already exists |
Fee Range Errors
| Code | Description |
|---|---|
| tariffs_m.fee_range_not_found | Fee range not found |
| tariffs_m.invalid_fee_range | Invalid fee range data |
| tariffs_m.overlapping_ranges | Fee ranges overlap |
| tariffs_m.invalid_date_range | Invalid date range |
| tariffs_m.invalid_calculation_method | Invalid fee calculation method |
Velocity Rule Errors
| Code | Description |
|---|---|
| tariffs_m.velocity_rule_not_found | Velocity rule not found |
| tariffs_m.invalid_velocity_rule | Invalid velocity rule data |
| tariffs_m.velocity_limit_exceeded | Velocity limit exceeded |
| tariffs_m.invalid_velocity_interval | Invalid velocity interval |
| tariffs_m.invalid_velocity_type | Invalid velocity type |
| tariffs_m.failed_to_create_velocity_rule | Failed to create velocity rule |
| tariffs_m.failed_to_update_velocity_rule | Failed to update velocity rule |
| tariffs_m.failed_to_delete_velocity_rule | Failed to delete velocity rule |
| tariffs_m.failed_to_retrieve_velocity_rule | Failed to retrieve velocity rule |
Fee Calculation Errors
| Code | Description |
|---|---|
| tariffs_m.failed_to_calculate_fee | Fee calculation failed |
| tariffs_m.no_valid_tariff_entry | No valid tariff entry found |
| tariffs_m.invalid_transaction_data | Invalid transaction data |
| tariffs_m.unsupported_asset_type | Unsupported asset type |
| tariffs_m.unsupported_channel | Unsupported channel |
| tariffs_m.invalid_amount | Invalid amount |