Skip to content

Trip Segments

Taxi & Private HireProductsTrip › Trip Segments

Generally available

A TripSegment is one leg of a Trip — the work between two stops with its own pickup, dropoff, capacity requirements, lifecycle status, pricing snapshot and tracking code. Single-load trips have exactly one segment; multi-load trips have several. Segments are the unit of dispatch, the unit of meter recording, and the unit of charge.

Example request

GET /client/{clientId}/trip/{tripId}/tripsegment

See the API reference for the full request and response schema.

Endpoints

MethodPath
GET /client/{clientId}/trip/{tripId}/tripsegment · primary
PUT /client/{clientId}/tripsegment/{tripSegmentId}/clientcapability/{clientCapabilityId}
POST /client/{clientId}/trip/{tripId}/tripsegment/{tripSegmentId}/copy
DELETE /client/{clientId}/trip/{tripId}/tripsegment/{tripSegmentId}
GET /client/{clientId}/trip/{tripId}/tripsegment/{tripSegmentId}
POST /client/{clientId}/tripsegment/{tripSegmentId}/dropoff-verify
POST /client/{clientId}/trip/{tripId}/tripsegment/{tripSegmentId}/promote
POST /client/{clientId}/trip/{tripId}/tripsegment/{tripSegmentId}
DELETE /client/{clientId}/tripsegment/{tripSegmentId}/clientcapability/{clientCapabilityId}

Full request/response schemas and an interactive explorer will live in the API reference (coming soon).

Use cases

Operator flows that exercise this feature.

Add a service requirement

config risk: low

Attach a required capability (wheelchair, pet, etc.) to a booking segment.

  1. PUT /client/{clientId}/tripsegment/{tripSegmentId}/clientcapability/{clientCapabilityId}
Duplicate a trip leg

action risk: low

Copy a segment within a trip (e.g. a repeat stop).

  1. POST /client/{clientId}/trip/{tripId}/tripsegment/{tripSegmentId}/copy
Remove a trip leg

action risk: low

Delete a segment (booking leg) from a trip.

  1. DELETE /client/{clientId}/trip/{tripId}/tripsegment/{tripSegmentId}
Verify a school drop-off

action risk: low

Confirm a safeguarded drop-off (PIN / guardian handoff) for a school passenger.

  1. POST /client/{clientId}/tripsegment/{tripSegmentId}/dropoff-verify
Promote a trip leg

action risk: low

Elevate a segment position / order within a trip.

  1. POST /client/{clientId}/trip/{tripId}/tripsegment/{tripSegmentId}/promote

Fields

FieldTypeDescription
trip Trip Parent Trip — the booking container that owns this segment. Required for active segments; nullable only during the brief construction phase.
customer Customer The customer who booked + is billed for this segment. When `scp` is also set, the customer is the booker/guardian and `scp` is the actual traveller. Editing the customer is price-sensitive — re-quotes the segment.
scp SpecialCategoryPassenger Optional Special Category Passenger — child / vulnerable adult / named third party who travels under the booker's account. When set, the customer remains the billable + notification target but the SCP is the actual passenger; SCP-driver preferences + safety-envelope checks engage.
dropoffPin string
dropoffPinAttempts integer
dropoffVerifiedAt integer
dropoffVerifiedBy bigint
trackingCode string Short shareable tracking code (3-char tenant prefix + 10-char unique part) for the public /p/track/{code} endpoint. Generated at segment creation; case-insensitive, exclude-confusing-chars alphabet.
arriveDate integer Unix timestamp the driver arrived at the pickup. Distinct from passengerOnBoardDate (waiting time = POB - arrive).
requestedPickupDate integer Customer-requested pickup time (unix). Required. Drives release-time calculation for pre-booked trips and pricing time-of-day modifiers. Price-sensitive — editing re-quotes.
expectedPickupDate integer Platform-projected pickup time accounting for current dispatch state. Differs from requestedPickupDate when delays push the realistic arrival forward.
predictedLateAtAssignment integer Predicted lateness in seconds at the moment of dispatch assignment. Set once by detectLateAtAssignment; always positive (guard skips below-threshold cases). Drives the late-trip alert + customer notification flow.
customerSharedEta integer The system's at-booking ETA commitment to the customer (unix). Pre-booked = `requestedPickupDate`; ASAP = bookingTime + ReleaseTimeDecision.offsetSeconds. Set once and frozen — never updated by later projections. The baseline for system-fault lateness attribution; see analytics.outcome-score.
assignedEta integer Driver-specific the routing service-projected pickup ETA at the moment of assignment (unix). Frozen except on reassignment, where it's overwritten with the new driver's projection. The boundary between systemFault (customerSharedEta → assignedEta) and driverFault (assignedEta → arriveDate); see analytics.outcome-score.
firstAssignedEta integer The very first assignedEta value for this segment (unix). Write-once — preserved through any reassignment so the reshuffle delta (`currentAssignedEta − firstAssignedEta`) attributes correctly to system fault; see analytics.outcome-score.
firstPickupProximityDate integer Unix timestamp the serving driver first came within the learning threshold (guard.pickup_proximity.threshold_metres) of this segment's pickup. Passive GPS-derived stamp, distinct from the gameable `arriveDate`; stamped once per assignment, reset on reassignment. Feeds approach-time percentiles + release-timing learning.
firstPickupProximityDistanceMetres integer Haversine distance in metres from the driver's GPS to the pickup at the moment firstPickupProximityDate was stamped. Always within the proximity threshold. Diagnostic for the stamp.
firstPickupProximityGpsAgeSeconds integer Age in seconds of the GPS reading used for the proximity stamp (now − session timestamp). Stale readings are rejected by guard.arrival.max_gps_age_seconds; this records the accepted age for confidence weighting.
firstPickupProximitySource string How firstPickupProximityDate was produced — LIVE_STAMP (from a live location tick) or GPS_BACKFILL (reconstructed from GPS history). See App\Domain\Trip\Enum\PickupProximitySource.
firstPickupProximityTransporterId bigint The transporter id the proximity stamp belongs to. On reassignment the stamp resets (the serving driver is what matters); the stamping service overwrites the stamp when the assigned transporter differs from this id.
arrivalDriftMetres smallint Haversine distance in metres between the driver's ARRIVED-press location and the booked pickup coordinates. Set once at the first PICKUP stop's ENROUTE→ARRIVED transition. Not used for per-trip scoring (driver-vs-address-data attribution is ambiguous per-trip); aggregated across drivers per `(pickupLat, pickupLng)` to surface address-quality candidates. See analytics.outcome-score.
arrivalRejectionCount smallint Count of arrival-guard-rejected attempts on this segment before a successful ARRIVED transition. Incremented atomically on each rejection. Not used for per-trip scoring; aggregated per-driver to surface repeat-offender patterns. See analytics.outcome-score.
earlySeconds integer For pre-booked segments only: seconds the driver arrived BEFORE the customer-requested pickup time (floored at zero). Driver-bad signal — fixes the "Outside SMS too early" pressure. Null/0 for ASAP segments. Feeds `driverTransporterScore` in Phase 2a. See analytics.outcome-score.
actualTripDistanceMetres integer Actual driven distance in metres for the with-passenger leg (POB → dropoff). v1 uses the routing service single-call at finalisation, which captures the traffic-adjusted optimal route at finish-time (not the driver's literal driven route — that needs breadcrumb-sum). Recorded for aggregate deviation analytics; not used for per-trip scoring. See analytics.outcome-score.
actualTripDurationSeconds integer Actual with-passenger duration in seconds — wall-clock from passengerOnBoardDate to segment finishedDate. Includes any dropoff handover time. Not used for per-trip scoring. See analytics.outcome-score.
actualTripPrice integer Final priced amount in cents for the segment. Metered fares only; fixed-fare segments leave null (price equals quote by design). Not used for per-trip scoring. See analytics.outcome-score.
timeDriftSeconds integer Time drift in seconds: `actualTripDurationSeconds − quoted.routeDuration`. Can be negative (came in faster than quoted) or positive (took longer). Recorded for aggregate deviation analytics; not used for per-trip scoring. See analytics.outcome-score.
distanceDriftMetres integer Distance drift in metres: `actualTripDistanceMetres − quoted.routeDistance`. Can be negative or positive. v1 inherits the routing service-vs-the routing service noise (traffic-adjusted optimal at finish vs at quote); breadcrumb-based actual-vs-optimal is a planned refinement. See analytics.outcome-score.
priceDriftCents integer Price drift in cents: `actualTripPrice − quote.price`. Metered fares only; null for fixed-fare. Can be negative or positive. Not used for per-trip scoring. See analytics.outcome-score.
scheduleAnchor ScheduleAnchor · PICKUP | DROPOFF | WINDOW Which timing column is the authoritative anchor for this segment: PICKUP (requestedPickupDate), DROPOFF (requestedDropoffDate), or WINDOW (pickupWindowStart/End). Hospital appointments anchor on DROPOFF; schools anchor on WINDOW; everything else anchors on PICKUP.
requestedDropoffDate integer
pickupWindowStart integer
pickupWindowEnd integer
dropoffWindowStart integer
dropoffWindowEnd integer
passengerOnBoardDate integer Unix timestamp the passenger was onboard (POB) — set when the driver finishes the pickup stop. Drives waiting-time pricing (the meter switches from "approach" to "fare" at POB) and serves as the fixed-fare lock-in moment.
dispatchedDate integer Unix timestamp the segment entered the ALLOCATION lifecycle (became dispatch-eligible). For ASAP trips that's shortly after creation; for pre-booked trips it's the release moment.
finishedDate integer Unix timestamp the segment reached a terminal state (FINISHED or CANCELLED). Anchors the archive cursor — segments older than the cursor get archived in batch.
status TripSegmentLifecycleEnum · NONE | SCHEDULED | INPROGRESS | FINISHED | CANCELLED Lifecycle state: NONE → SCHEDULED → ALLOCATION → ASSIGNED → ENROUTE → ONBOARD → FINISHED, or → CANCELLED / NOSHOW from various points. Drives every downstream visibility / dispatch / pricing decision.
passengerType PassengerType · HUMAN | ANIMAL | PACKAGE Passenger classification (STANDARD / VIP / SCHOOL_RUN / MEDICAL / etc.). Drives tariff-decision-tree matching and capability-requirement defaults. Price-sensitive — editing re-quotes.
tripSegmentStops Collection Ordered stops the driver visits — pickup, dropoff, and any intermediate waypoints. Mutations are price-sensitive (route changes → re-quote).
quote Quote BILLING-role Quote for this segment — the priced snapshot at booking time. Shadow quotes (fixed-fare alternates) live on the Trip-level quote instead.
price Price
resolvedSharePercentage integer
operatorSharePercentage integer
discountOverridePercentage integer
account Account
accountDepartment AccountDepartment
accountEmployee AccountEmployee
paymentMethod TripPaymentMethod · CASH | CARD | INVOICE | VOUCHER
customerPaymentMethod CustomerPaymentMethod
pricingMode PricingMode · FIXED | METERED
requiredClientCapabilities Collection
originatingFleet Fleet
vehicleType VehicleType
passengerCapacityRequirement smallint
tripSegmentChargeableItems Collection
pickupZone Zone
accountFieldData JsonStorage
brand Brand
mergeGroup string
planCostMetres integer
planDetourPercentage smallint
sharingRatio smallint
dispatchScore smallint System-attributable lateness score (0–100, floor 10). `computeScore(systemFaultSeconds)` where `systemFaultSeconds = max(0, assignedEta − customerSharedEta) + max(0, assignedEta − firstAssignedEta)`. Renamed from `outcomeScore` in Phase 2a — now represents the system-fault slice only, not the blended customer view. `null` until segment reaches FINISHED. See analytics.outcome-score.
driverTransporterScore smallint Driver-attributable conduct score (0–100, floor 10). Pre-booked: `(computeScore(driverFaultSeconds) × 0.7) + (computeScore(earlySeconds) × 0.3)`. ASAP: `computeScore(driverFaultSeconds)` only — earliness is neutral for ASAP. Aggregated per driver_id → Driver page KPI; per transporter_id → Transporter page KPI. See analytics.outcome-score.
blendedScore smallint Blended customer-experience score (0–100, floor 10). `round((dispatchScore + driverTransporterScore) / 2)` — simple 50/50 mean. Successor to the legacy outcome score for fleet/zone headline KPIs. `null` if either component is null. See analytics.outcome-score.
pricingStartDate integer
pricingEndDate integer
excludeFromMultiload bool
allowedMergeStrategy MergeStrategy · NONE | ACCOUNT | ACCOUNT_DEPARTMENT | ALL
region Region
fixedStopSequence bool
note string
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.