Tariff Bands
Taxi & Private Hire › Products › Pricing › Tariff Bands
Generally available
Stepped pricing rates on top of a Tariff. Each band defines a threshold (distance, time, or speed) and the rate that applies once that threshold is crossed — supports patterns like "first 5 km at €2/km, then €1.50/km thereafter", "after 10 min waiting charge per-minute kicks in", "above 80 km/h motorway rate applies". Bands also carry pickup charge, minimum charge, per-person / per-luggage / technology fees, and optional duration/distance breakers.
Example request
POST /client/{clientId}/tariff/{tariffId}/tariffband
{
"bandAxis": "DISTANCE",
"distanceFromMetres": 0,
"timeFromSeconds": 0,
"maxBandDurationSeconds": 0,
"maxBandDistanceMetres": 0,
"totalTripDurationBreaker": 0,
"totalTripDistanceBreaker": 0,
"chargeMode": "DISTANCE_OR_TIME",
"speedThresholdKmh": 0,
"unitOfPricePerUnitOfDistance": 0,
"unitOfPricePerUnitOfTime": 0,
"pickupCharge": 0,
"minimumCharge": 0,
"perPersonCharge": 0,
"perLuggageCharge": 0,
"technologyFee": 0
}
Example shape, derived from the TariffBand fields — indicative,
not the authoritative schema (that arrives with the API reference).
Endpoints
| Method | Path | |
|---|---|---|
POST | /client/{clientId}/tariff/{tariffId}/vehicletype/{vehicleTypeId} | |
DELETE | /client/{clientId}/tariff/{tariffId}/vehicletype/{vehicleTypeId} | |
POST | /client/{clientId}/tariff/{tariffId}/tariffband · primary | |
DELETE | /client/{clientId}/tariff/{tariffId}/tariffband/{tariffbandId} | |
GET | /client/{clientId}/tariff/{tariffId}/tariffband | |
GET | /client/{clientId}/tariff/{tariffId}/tariffband/{tariffbandId} | |
POST | /client/{clientId}/tariff/{tariffId}/tariffband/{tariffbandId} |
Full request/response schemas and an interactive explorer will live in the API reference (coming soon).
Use cases
Operator flows that exercise this feature.
config risk: low
Apply a tariff to a specific vehicle type (vehicle-class pricing).
POST/client/{clientId}/tariff/{tariffId}/vehicletype/{vehicleTypeId}
config risk: medium
Create a tariff and add its first distance/time band.
POST/client/{clientId}/tariffPOST/client/{clientId}/tariff/{tariffId}/tariffband
Related
Fields
| Field | Type | Description |
|---|---|---|
tariff | Tariff | Parent tariff. Each band belongs to exactly one tariff and contributes one step to that tariff's piece-wise pricing curve. |
ref | string | Auto-generated label for operator UIs (e.g. "Band 1 0.00km", "Band 2 5.00km"). Read-only — derived from band thresholds at write time. |
bandAxis | BandAxis · DISTANCE | TIME | Primary axis the band orders on: DISTANCE (band activates when accumulated distance crosses the threshold) or TIME (activates on time threshold). Drives band-sequencing within the parent tariff. |
distanceFromMetres | integer | Distance threshold (metres) at which this band activates. Band 1 has 0; subsequent bands stair-step the curve ("first 5 km at €2/km, then €1.50/km"). |
timeFromSeconds | integer | Time threshold (seconds) at which this band activates when bandAxis = TIME. Mirrors distanceFromMetres on the time axis. |
maxBandDurationSeconds | integer | Forced exit from this band after N seconds inside it. Caps band-level dwell — useful for "5-min waiting allowance then the meter kicks in" patterns. Null = no breaker. |
maxBandDistanceMetres | integer | Forced exit from this band after N metres travelled inside it. Companion to maxBandDurationSeconds on the distance axis. |
totalTripDurationBreaker | integer | Total-trip-time breaker — forces escalation to the next band after this many seconds since trip start (not just time in this band). Trip-level cap. |
totalTripDistanceBreaker | integer | Total-trip-distance breaker — forces escalation to the next band after this many metres since trip start. Trip-level cap. |
chargeMode | ChargeMode · DISTANCE_OR_TIME | DISTANCE_AND_TIME | ALWAYS_BOTH | How distance and time charges combine inside this band. DISTANCE_OR_TIME picks whichever is higher per tick (typical metered taxi behaviour); other modes sum or only charge one axis. |
speedThresholdKmh | smallint | Speed threshold (km/h) below which time charging takes over from distance charging in DISTANCE_OR_TIME mode. Models the "stuck in traffic, charge per minute" behaviour. |
unitOfPricePerUnitOfDistance | integer | Distance-unit rate in price-cents-per-distance-unit (depends on tariff's uod/uop config — typically cents per km). The headline "€/km" figure. |
unitOfPricePerUnitOfTime | integer | Time-unit rate in price-cents-per-time-unit (typically cents per minute). The "waiting / slow-traffic" rate. |
pickupCharge | integer | Flat fee in cents applied once when the trip first enters this band. Typically only set on Band 1 (the "drop charge" / "hailing fee"). |
minimumCharge | integer | Floor charge in cents. If the running total in this band ends below this value, the charge is bumped up to the minimum. Stops very short trips from coming out free. |
perPersonCharge | integer | Per-passenger surcharge in cents — adds onto the band charge for each passenger above one (or however the tariff config counts). |
perLuggageCharge | integer | Per-luggage-item surcharge in cents — used in airport / station tariffs where luggage is priced per piece. |
technologyFee | integer | Booking / platform technology fee in cents — flat add-on charged once per trip in this band. Surfaces separately on the receipt for transparency. |
clientId | bigint | Tenant scope. Every tenant-aware entity carries this; `ClientFilter` enforces row-level isolation on read; the multi-tenancy routing layer (`/client/{clientId}`) sets it at create time. Surfaced only under `admin` / `tripLog` groups — never to end users. |
internalKey | string | Optional client-supplied external reference / idempotency key. When present, lets external systems correlate platform-side records back to their own source-of-truth ids. Not persisted to a column — populated by the request handler when the caller sets it. |
__objectType | string | Discriminator string (entity class short-name) emitted alongside the id in serialized output. Resolved at read time by `getObjectType()`; lets the FE dispatch entity-specific rendering without inspecting the URL. |
id | bigint | Snowflake-style primary key (unsigned BIGINT). Generated by `IdFactory` at create time; surfaced to the FE / API as a `G`-prefixed string and stripped back to plain bigint server-side before Doctrine lookup. |
createdDate | integer | Unix timestamp the row was first persisted. Set in the entity's PrePersist hook; never rewritten on subsequent updates. |
updatedDate | integer | Unix timestamp the row was last touched. Bumped on every commit that hits the Doctrine UoW for this entity; drives FE invalidation + the listing change cursor. |
passiveUpdatedDate | int | Read-through alias for `updatedDate` exposed under different serializer groups. Lets the FE distinguish "real edit" from "background touch" projections without changing the underlying column. |
listingUpdatedDate | int | Listing-projection timestamp surfaced only under the `listMode` group. Driven by `TripCache` and other listing-shape refreshers separately from `updatedDate` so a listing rebuild doesn't trigger detail-page invalidation. |