Download OpenAPI specification:
Logistics operations API for the 4klyft platform.
This API provides comprehensive endpoints for managing:
All API endpoints (except /api/docs and /api/v1/iam/auth/*) require JWT Bearer token authentication.
Include the token in the Authorization header:
Authorization: Bearer <your-jwt-token>
API requests are rate-limited to ensure fair usage. Standard limits are:
The current tenant's routing config — a singleton sub-resource.
GET /routing/config returns the tenant's stored row or a virtual
platform-defaults-seeded config when no row exists.
PATCH /routing/config overwrites the row (creating it on first write).
The identifier is tenantId so the URI surfaces a stable, addressable id
even though the request path itself is parameterless — the tenant is
resolved bus-side from the execution context per Rule 17.
Returns the routing defaults for the authenticated tenant. When no per-tenant row has been written, the response is seeded from platform defaults — never a 404.
{- "@context": "string",
- "@id": "string",
- "@type": "string",
- "tenantId": "string",
- "defaultOptimizationGoal": "fastest",
- "defaultAvoidances": [
- "tolls"
], - "defaultSolverKind": "greedy_two_opt",
- "defaultAwaitDecisionTimeoutHours": 0,
- "defaultMaxStopsBeforeBreak": 0,
- "defaultMaxDailyDrivingMinutes": 0,
- "createdAt": "string",
- "updatedAt": "string"
}Overwrites the tenant's routing defaults. All fields are required (full replace, not a partial patch).
The updated TenantRoutingConfig resource
| defaultOptimizationGoal | string Default: "" Enum: "fastest" "shortest" "fuel_efficient" "balanced" |
| avoidances | Array of strings |
| defaultSolverKind | string Default: "" Enum: "greedy_two_opt" "external" |
| defaultAwaitDecisionTimeoutHours | integer > 0 Default: 24 |
| defaultMaxStopsBeforeBreak | integer > 0 Default: 0 |
| defaultMaxDailyDrivingMinutes | integer > 0 Default: 0 |
{- "defaultOptimizationGoal": "fastest",
- "avoidances": [
- "string"
], - "defaultSolverKind": "greedy_two_opt",
- "defaultAwaitDecisionTimeoutHours": 24,
- "defaultMaxStopsBeforeBreak": 0,
- "defaultMaxDailyDrivingMinutes": 0
}{- "@context": "string",
- "@id": "string",
- "@type": "string",
- "tenantId": "string",
- "defaultOptimizationGoal": "fastest",
- "defaultAvoidances": [
- "tolls"
], - "defaultSolverKind": "greedy_two_opt",
- "defaultAwaitDecisionTimeoutHours": 0,
- "defaultMaxStopsBeforeBreak": 0,
- "defaultMaxDailyDrivingMinutes": 0,
- "createdAt": "string",
- "updatedAt": "string"
}Retrieve a paginated list of route executions with optional filters.
| status | string Enum: "pending" "in_progress" "paused" "completed" "cancelled" "failed" Example: status=in_progress Filter by execution status |
| routeId | string <uuid> Example: routeId=01912345-6789-7abc-def0-123456789abc Filter by route UUID |
| driverId | string <uuid> Example: driverId=01912345-6789-7abc-def0-123456789abc Filter by driver UUID |
| dateFrom | string <date> Example: dateFrom=2024-06-01 Filter executions from this date (inclusive) |
| dateTo | string <date> Example: dateTo=2024-06-30 Filter executions up to this date (inclusive) |
| page | integer >= 1 Default: 1 Example: page=1 Page number for pagination |
| itemsPerPage | integer [ 1 .. 100 ] Default: 30 Example: itemsPerPage=30 Number of items per page |
{- "totalItems": 0,
- "search": {
- "@type": "string",
- "template": "string",
- "variableRepresentation": "string",
- "mapping": [
- {
- "@type": "string",
- "variable": "string",
- "property": "string",
- "required": true
}
]
}, - "view": {
- "@id": "string",
- "@type": "string",
- "first": "string",
- "last": "string",
- "previous": "string",
- "next": "string"
}, - "member": [
- {
- "@context": "string",
- "@id": "string",
- "@type": "string",
- "id": "01912345-6789-7abc-def0-123456789abc",
- "routeId": "01912345-6789-7abc-def0-123456789abc",
- "routeCode": "ROUTE-2024-001",
- "driverId": "01912345-6789-7abc-def0-123456789abc",
- "driverName": "string",
- "status": "pending",
- "completedNodes": 5,
- "totalNodes": 12,
- "progressPercent": 41.67,
- "startedAt": "2024-06-15T08:00:00+00:00",
- "completedAt": "2024-06-15T16:30:00+00:00",
- "currentLegToNodeId": "01912345-6789-7abc-def0-123456789abc",
- "nodeExecutions": [
- {
- "id": "string",
- "nodeId": "string",
- "sequence": 0,
- "status": "string",
- "arrivedAt": "string",
- "completedAt": "string",
- "signatureData": "string",
- "recipientName": "string",
- "arrivalSource": "string",
- "etaSeconds": 0,
- "etaAt": "string"
}
], - "createdAt": "2024-06-15T07:00:00+00:00",
- "updatedAt": "2024-06-15T12:30:00+00:00"
}
]
}Retrieve a single route execution by ID with detailed node execution progress.
| id required | string <uuid> Example: 01912345-6789-7abc-def0-123456789abc Route execution UUID |
{- "@context": "string",
- "@id": "string",
- "@type": "string",
- "id": "01912345-6789-7abc-def0-123456789abc",
- "routeId": "01912345-6789-7abc-def0-123456789abc",
- "routeCode": "ROUTE-2024-001",
- "driverId": "01912345-6789-7abc-def0-123456789abc",
- "driverName": "string",
- "status": "pending",
- "completedNodes": 5,
- "totalNodes": 12,
- "progressPercent": 41.67,
- "startedAt": "2024-06-15T08:00:00+00:00",
- "completedAt": "2024-06-15T16:30:00+00:00",
- "currentLegToNodeId": "01912345-6789-7abc-def0-123456789abc",
- "nodeExecutions": [
- {
- "id": "string",
- "nodeId": "string",
- "sequence": 0,
- "status": "string",
- "arrivedAt": "string",
- "completedAt": "string",
- "signatureData": "string",
- "recipientName": "string",
- "arrivalSource": "string",
- "etaSeconds": 0,
- "etaAt": "string"
}
], - "createdAt": "2024-06-15T07:00:00+00:00",
- "updatedAt": "2024-06-15T12:30:00+00:00"
}Mark a route execution as completed. All nodes must be in a terminal state.
| id required | string <uuid> Example: 01912345-6789-7abc-def0-123456789abc Route execution UUID |
{- "@context": "string",
- "@id": "string",
- "@type": "string",
- "id": "01912345-6789-7abc-def0-123456789abc",
- "routeId": "01912345-6789-7abc-def0-123456789abc",
- "routeCode": "ROUTE-2024-001",
- "driverId": "01912345-6789-7abc-def0-123456789abc",
- "driverName": "string",
- "status": "pending",
- "completedNodes": 5,
- "totalNodes": 12,
- "progressPercent": 41.67,
- "startedAt": "2024-06-15T08:00:00+00:00",
- "completedAt": "2024-06-15T16:30:00+00:00",
- "currentLegToNodeId": "01912345-6789-7abc-def0-123456789abc",
- "nodeExecutions": [
- {
- "id": "string",
- "nodeId": "string",
- "sequence": 0,
- "status": "string",
- "arrivedAt": "string",
- "completedAt": "string",
- "signatureData": "string",
- "recipientName": "string",
- "arrivalSource": "string",
- "etaSeconds": 0,
- "etaAt": "string"
}
], - "createdAt": "2024-06-15T07:00:00+00:00",
- "updatedAt": "2024-06-15T12:30:00+00:00"
}Retrieve all issues reported for a specific route execution.
| id required | string <uuid> Example: 01912345-6789-7abc-def0-123456789abc Route execution UUID |
| page | integer >= 1 Default: 1 Example: page=1 Page number for pagination |
| itemsPerPage | integer [ 1 .. 100 ] Default: 30 Example: itemsPerPage=30 Number of items per page |
{- "totalItems": 0,
- "search": {
- "@type": "string",
- "template": "string",
- "variableRepresentation": "string",
- "mapping": [
- {
- "@type": "string",
- "variable": "string",
- "property": "string",
- "required": true
}
]
}, - "view": {
- "@id": "string",
- "@type": "string",
- "first": "string",
- "last": "string",
- "previous": "string",
- "next": "string"
}, - "member": [
- {
- "@context": "string",
- "@id": "string",
- "@type": "string",
- "id": "01912345-6789-7abc-def0-123456789abc",
- "executionId": "01912345-6789-7abc-def0-123456789abc",
- "type": "vehicle_breakdown",
- "severity": "low",
- "description": "Heavy traffic on highway causing 30 minute delay",
- "reportedAt": "2024-06-15T10:30:00+00:00"
}
]
}Report an issue encountered during route execution.
| id required | string <uuid> Example: 01912345-6789-7abc-def0-123456789abc Route execution UUID |
Execution issue data
| type required | string Enum: "vehicle_breakdown" "traffic_delay" "customer_unavailable" "address_incorrect" "weather" "other" Type of issue |
| severity required | string Enum: "low" "medium" "high" "critical" Severity level of the issue |
| description required | string Description of the issue |
| nodeExecutionId | string or null <uuid> Optional node execution UUID this issue relates to |
{- "type": "traffic_delay",
- "severity": "medium",
- "description": "Heavy traffic on highway causing 30 minute delay",
- "nodeExecutionId": "01912345-6789-7abc-def0-123456789abc"
}{- "@context": "string",
- "@id": "string",
- "@type": "string",
- "id": "01912345-6789-7abc-def0-123456789abc",
- "executionId": "01912345-6789-7abc-def0-123456789abc",
- "type": "vehicle_breakdown",
- "severity": "low",
- "description": "Heavy traffic on highway causing 30 minute delay",
- "reportedAt": "2024-06-15T10:30:00+00:00"
}Mark the driver as having arrived at the specified route node. The driver app sends arrivalSource=geofence when auto-detected, manual otherwise.
| id required | string <uuid> Example: 01912345-6789-7abc-def0-123456789abc Route execution UUID |
| nodeId required | string <uuid> Example: 01912345-6789-7abc-def0-123456789abc Node execution UUID |
Node arrival data
| arrivalSource | string Default: "manual" Enum: "geofence" "manual" How the arrival was recorded |
{- "arrivalSource": "geofence"
}{- "@context": "string",
- "@id": "string",
- "@type": "string",
- "id": "01912345-6789-7abc-def0-123456789abc",
- "routeId": "01912345-6789-7abc-def0-123456789abc",
- "routeCode": "ROUTE-2024-001",
- "driverId": "01912345-6789-7abc-def0-123456789abc",
- "driverName": "string",
- "status": "pending",
- "completedNodes": 5,
- "totalNodes": 12,
- "progressPercent": 41.67,
- "startedAt": "2024-06-15T08:00:00+00:00",
- "completedAt": "2024-06-15T16:30:00+00:00",
- "currentLegToNodeId": "01912345-6789-7abc-def0-123456789abc",
- "nodeExecutions": [
- {
- "id": "string",
- "nodeId": "string",
- "sequence": 0,
- "status": "string",
- "arrivedAt": "string",
- "completedAt": "string",
- "signatureData": "string",
- "recipientName": "string",
- "arrivalSource": "string",
- "etaSeconds": 0,
- "etaAt": "string"
}
], - "createdAt": "2024-06-15T07:00:00+00:00",
- "updatedAt": "2024-06-15T12:30:00+00:00"
}Mark a route node as completed with optional delivery details.
| id required | string <uuid> Example: 01912345-6789-7abc-def0-123456789abc Route execution UUID |
| nodeId required | string <uuid> Example: 01912345-6789-7abc-def0-123456789abc Node execution UUID |
Node completion data
| notes | string or null Optional notes about the delivery |
| receiverName | string or null Name of the person who received the delivery |
| podId | string or null <uuid> Optional reference to the captured Pod aggregate for this delivery |
{- "notes": "Left package at front door",
- "receiverName": "John Smith",
- "podId": "01912345-6789-7abc-def0-123456789abc"
}{- "@context": "string",
- "@id": "string",
- "@type": "string",
- "id": "01912345-6789-7abc-def0-123456789abc",
- "routeId": "01912345-6789-7abc-def0-123456789abc",
- "routeCode": "ROUTE-2024-001",
- "driverId": "01912345-6789-7abc-def0-123456789abc",
- "driverName": "string",
- "status": "pending",
- "completedNodes": 5,
- "totalNodes": 12,
- "progressPercent": 41.67,
- "startedAt": "2024-06-15T08:00:00+00:00",
- "completedAt": "2024-06-15T16:30:00+00:00",
- "currentLegToNodeId": "01912345-6789-7abc-def0-123456789abc",
- "nodeExecutions": [
- {
- "id": "string",
- "nodeId": "string",
- "sequence": 0,
- "status": "string",
- "arrivedAt": "string",
- "completedAt": "string",
- "signatureData": "string",
- "recipientName": "string",
- "arrivalSource": "string",
- "etaSeconds": 0,
- "etaAt": "string"
}
], - "createdAt": "2024-06-15T07:00:00+00:00",
- "updatedAt": "2024-06-15T12:30:00+00:00"
}Mark a route node as failed with a reason. Distinct from skip — records a failed delivery outcome.
| id required | string <uuid> Example: 01912345-6789-7abc-def0-123456789abc Route execution UUID |
| nodeId required | string <uuid> Example: 01912345-6789-7abc-def0-123456789abc Node execution UUID |
Node failure data
| reason required | string Reason for the failed delivery |
{- "reason": "Recipient refused delivery"
}{- "@context": "string",
- "@id": "string",
- "@type": "string",
- "id": "01912345-6789-7abc-def0-123456789abc",
- "routeId": "01912345-6789-7abc-def0-123456789abc",
- "routeCode": "ROUTE-2024-001",
- "driverId": "01912345-6789-7abc-def0-123456789abc",
- "driverName": "string",
- "status": "pending",
- "completedNodes": 5,
- "totalNodes": 12,
- "progressPercent": 41.67,
- "startedAt": "2024-06-15T08:00:00+00:00",
- "completedAt": "2024-06-15T16:30:00+00:00",
- "currentLegToNodeId": "01912345-6789-7abc-def0-123456789abc",
- "nodeExecutions": [
- {
- "id": "string",
- "nodeId": "string",
- "sequence": 0,
- "status": "string",
- "arrivedAt": "string",
- "completedAt": "string",
- "signatureData": "string",
- "recipientName": "string",
- "arrivalSource": "string",
- "etaSeconds": 0,
- "etaAt": "string"
}
], - "createdAt": "2024-06-15T07:00:00+00:00",
- "updatedAt": "2024-06-15T12:30:00+00:00"
}Skip a route node with a reason.
| id required | string <uuid> Example: 01912345-6789-7abc-def0-123456789abc Route execution UUID |
| nodeId required | string <uuid> Example: 01912345-6789-7abc-def0-123456789abc Node execution UUID |
Node skip data
| reason required | string Reason for skipping the node |
{- "reason": "Customer not available, rescheduling delivery"
}{- "@context": "string",
- "@id": "string",
- "@type": "string",
- "id": "01912345-6789-7abc-def0-123456789abc",
- "routeId": "01912345-6789-7abc-def0-123456789abc",
- "routeCode": "ROUTE-2024-001",
- "driverId": "01912345-6789-7abc-def0-123456789abc",
- "driverName": "string",
- "status": "pending",
- "completedNodes": 5,
- "totalNodes": 12,
- "progressPercent": 41.67,
- "startedAt": "2024-06-15T08:00:00+00:00",
- "completedAt": "2024-06-15T16:30:00+00:00",
- "currentLegToNodeId": "01912345-6789-7abc-def0-123456789abc",
- "nodeExecutions": [
- {
- "id": "string",
- "nodeId": "string",
- "sequence": 0,
- "status": "string",
- "arrivedAt": "string",
- "completedAt": "string",
- "signatureData": "string",
- "recipientName": "string",
- "arrivalSource": "string",
- "etaSeconds": 0,
- "etaAt": "string"
}
], - "createdAt": "2024-06-15T07:00:00+00:00",
- "updatedAt": "2024-06-15T12:30:00+00:00"
}Start executing a confirmed route. Assigns a driver and begins tracking progress.
| id required | string <uuid> Example: 01912345-6789-7abc-def0-123456789abc Route execution UUID |
Execution start data
| driverId required | string <uuid> UUID of the driver executing the route |
| vehicleId | string or null <uuid> Optional vehicle UUID |
{- "driverId": "01912345-6789-7abc-def0-123456789abc",
- "vehicleId": "01912345-6789-7abc-def0-123456789abc"
}{- "@context": "string",
- "@id": "string",
- "@type": "string",
- "id": "01912345-6789-7abc-def0-123456789abc",
- "routeId": "01912345-6789-7abc-def0-123456789abc",
- "routeCode": "ROUTE-2024-001",
- "driverId": "01912345-6789-7abc-def0-123456789abc",
- "driverName": "string",
- "status": "pending",
- "completedNodes": 5,
- "totalNodes": 12,
- "progressPercent": 41.67,
- "startedAt": "2024-06-15T08:00:00+00:00",
- "completedAt": "2024-06-15T16:30:00+00:00",
- "currentLegToNodeId": "01912345-6789-7abc-def0-123456789abc",
- "nodeExecutions": [
- {
- "id": "string",
- "nodeId": "string",
- "sequence": 0,
- "status": "string",
- "arrivedAt": "string",
- "completedAt": "string",
- "signatureData": "string",
- "recipientName": "string",
- "arrivalSource": "string",
- "etaSeconds": 0,
- "etaAt": "string"
}
], - "createdAt": "2024-06-15T07:00:00+00:00",
- "updatedAt": "2024-06-15T12:30:00+00:00"
}Catalog of route-optimization engines available to the current tenant. Each entry carries its feature set, access tier, and whether the tenant may select it (accessible) and whether it is currently usable (available).
| page | integer Default: 1 The collection page number |
{- "totalItems": 0,
- "search": {
- "@type": "string",
- "template": "string",
- "variableRepresentation": "string",
- "mapping": [
- {
- "@type": "string",
- "variable": "string",
- "property": "string",
- "required": true
}
]
}, - "view": {
- "@id": "string",
- "@type": "string",
- "first": "string",
- "last": "string",
- "previous": "string",
- "next": "string"
}, - "member": [
- {
- "@context": "string",
- "@id": "string",
- "@type": "string",
- "kind": "",
- "label": "",
- "description": "",
- "features": [
- "string"
], - "tier": "",
- "accessible": false,
- "available": false
}
]
}Live status, phase, progress and — once ready — the staged proposal of an optimization run.
| id required | string OptimizationRun identifier |
{- "@context": "string",
- "@id": "string",
- "@type": "string",
- "id": "01912345-6789-7abc-def0-123456789abc",
- "routeId": "01912345-6789-7abc-def0-123456789abc",
- "status": "awaiting_decision",
- "phase": "solving",
- "phaseLabel": "Optimizing",
- "phaseDetail": "google",
- "progressPercent": 45,
- "engineKind": "in_house_greedy",
- "requestedBy": "string",
- "decidedBy": "string",
- "proposal": {
- "stopSequence": [
- "string"
], - "legs": {
- "property1": {
- "property1": 0,
- "property2": 0
}, - "property2": {
- "property1": 0,
- "property2": 0
}
}, - "totalDistanceMeters": 0,
- "totalDurationSeconds": 0,
- "geometry": "string",
- "unassignedStopIds": [
- "string"
], - "engineKind": "string"
}, - "failureReason": "string",
- "decisionReason": "string",
- "createdAt": "2026-07-14T09:00:00+00:00",
- "updatedAt": "2026-07-14T09:00:12+00:00"
}Write the staged proposal onto the route (nodes renumbered to the optimized sequence, distance/duration/geometry recorded) and close the run as applied.
| id required | string OptimizationRun identifier |
{- "@context": "string",
- "@id": "string",
- "@type": "string",
- "id": "01912345-6789-7abc-def0-123456789abc",
- "routeId": "01912345-6789-7abc-def0-123456789abc",
- "status": "awaiting_decision",
- "phase": "solving",
- "phaseLabel": "Optimizing",
- "phaseDetail": "google",
- "progressPercent": 45,
- "engineKind": "in_house_greedy",
- "requestedBy": "string",
- "decidedBy": "string",
- "proposal": {
- "stopSequence": [
- "string"
], - "legs": {
- "property1": {
- "property1": 0,
- "property2": 0
}, - "property2": {
- "property1": 0,
- "property2": 0
}
}, - "totalDistanceMeters": 0,
- "totalDurationSeconds": 0,
- "geometry": "string",
- "unassignedStopIds": [
- "string"
], - "engineKind": "string"
}, - "failureReason": "string",
- "decisionReason": "string",
- "createdAt": "2026-07-14T09:00:00+00:00",
- "updatedAt": "2026-07-14T09:00:12+00:00"
}Discard the staged proposal. The route is left exactly as it was — nothing was ever written to it.
| id required | string OptimizationRun identifier |
The new OptimizationRun resource
| reason | string or null <= 500 characters Why the operator rejected the proposal — recorded on the run for audit. |
{- "reason": "string"
}{- "@context": "string",
- "@id": "string",
- "@type": "string",
- "id": "01912345-6789-7abc-def0-123456789abc",
- "routeId": "01912345-6789-7abc-def0-123456789abc",
- "status": "awaiting_decision",
- "phase": "solving",
- "phaseLabel": "Optimizing",
- "phaseDetail": "google",
- "progressPercent": 45,
- "engineKind": "in_house_greedy",
- "requestedBy": "string",
- "decidedBy": "string",
- "proposal": {
- "stopSequence": [
- "string"
], - "legs": {
- "property1": {
- "property1": 0,
- "property2": 0
}, - "property2": {
- "property1": 0,
- "property2": 0
}
}, - "totalDistanceMeters": 0,
- "totalDurationSeconds": 0,
- "geometry": "string",
- "unassignedStopIds": [
- "string"
], - "engineKind": "string"
}, - "failureReason": "string",
- "decisionReason": "string",
- "createdAt": "2026-07-14T09:00:00+00:00",
- "updatedAt": "2026-07-14T09:00:12+00:00"
}Retrieve a paginated list of routes with optional filters. Supports filtering by status, team, and date range.
| status | string Enum: "draft" "confirmed" "in_progress" "completed" "cancelled" Example: status=confirmed Filter by route status |
| crewId | string <uuid> Example: crewId=01912345-6789-7abc-def0-123456789abc Filter by team UUID |
| date | string <date> Example: date=2024-06-15 Filter routes for an exact date |
| dateFrom | string <date> Example: dateFrom=2024-01-01 Filter routes from this date (inclusive) |
| dateTo | string <date> Example: dateTo=2024-12-31 Filter routes up to this date (inclusive) |
| page | integer >= 1 Default: 1 Example: page=1 Page number for pagination |
| itemsPerPage | integer [ 1 .. 100 ] Default: 30 Example: itemsPerPage=30 Number of items per page |
{- "totalItems": 0,
- "search": {
- "@type": "string",
- "template": "string",
- "variableRepresentation": "string",
- "mapping": [
- {
- "@type": "string",
- "variable": "string",
- "property": "string",
- "required": true
}
]
}, - "view": {
- "@id": "string",
- "@type": "string",
- "first": "string",
- "last": "string",
- "previous": "string",
- "next": "string"
}, - "member": [
- {
- "@context": "string",
- "@id": "string",
- "@type": "string",
- "id": "01912345-6789-7abc-def0-123456789abc",
- "code": "ROUTE-2024-001",
- "date": "2024-06-15",
- "crewId": "01912345-6789-7abc-def0-123456789abc",
- "teamName": "Express Logistics",
- "label": "Downtown Morning Route",
- "description": "Morning deliveries covering downtown area",
- "status": "draft",
- "nodeCount": 12,
- "loadCount": 45,
- "isLocked": false,
- "isOptimized": false,
- "defaultNodeDurationMinutes": 15,
- "distanceKm": 42.5,
- "durationMinutes": 60,
- "geometry": "ionF~vfe@k@fB{@hC",
- "progressPercent": 75,
- "createdAt": "2024-06-14T10:30:00+00:00",
- "updatedAt": "2024-06-14T14:45:00+00:00",
- "startAnchor": {
- "street": "string",
- "streetLine2": "string",
- "city": "string",
- "postalCode": "string",
- "countryCode": "string",
- "province": "string",
- "coordinates": {
- "latitude": 0,
- "longitude": 0
}, - "depotId": "string"
}, - "endAnchor": {
- "street": "string",
- "streetLine2": "string",
- "city": "string",
- "postalCode": "string",
- "countryCode": "string",
- "province": "string",
- "coordinates": {
- "latitude": 0,
- "longitude": 0
}, - "depotId": "string"
}, - "resources": [
- {
- "resourceRef": "string",
- "kind": "string",
- "role": "string",
- "name": "string"
}
]
}
]
}Create a new route in draft status. The route can then have nodes and loads added before confirmation.
Route creation data
| code required | string [ 2 .. 50 ] characters Unique route code |
| date required | string <date> Scheduled date for the route |
| crewId | string or null <uuid> Optional team UUID to assign |
| label | string or null <= 255 characters Short label for the route |
| description | string or null Detailed description of the route |
| defaultNodeDurationMinutes | integer >= 1 Default: 30 Default time allocated per stop in minutes |
{- "code": "ROUTE-2024-001",
- "date": "2024-06-15",
- "crewId": "01912345-6789-7abc-def0-123456789abc",
- "label": "Downtown Morning Route",
- "description": "Morning deliveries covering downtown area and business district",
- "defaultNodeDurationMinutes": 15
}{- "@context": "string",
- "@id": "string",
- "@type": "string",
- "id": "01912345-6789-7abc-def0-123456789abc",
- "code": "ROUTE-2024-001",
- "date": "2024-06-15",
- "crewId": "01912345-6789-7abc-def0-123456789abc",
- "teamName": "Express Logistics",
- "label": "Downtown Morning Route",
- "description": "Morning deliveries covering downtown area",
- "status": "draft",
- "nodeCount": 12,
- "loadCount": 45,
- "isLocked": false,
- "isOptimized": false,
- "defaultNodeDurationMinutes": 15,
- "distanceKm": 42.5,
- "durationMinutes": 60,
- "geometry": "ionF~vfe@k@fB{@hC",
- "progressPercent": 75,
- "createdAt": "2024-06-14T10:30:00+00:00",
- "updatedAt": "2024-06-14T14:45:00+00:00",
- "startAnchor": {
- "street": "string",
- "streetLine2": "string",
- "city": "string",
- "postalCode": "string",
- "countryCode": "string",
- "province": "string",
- "coordinates": {
- "latitude": 0,
- "longitude": 0
}, - "depotId": "string"
}, - "endAnchor": {
- "street": "string",
- "streetLine2": "string",
- "city": "string",
- "postalCode": "string",
- "countryCode": "string",
- "province": "string",
- "coordinates": {
- "latitude": 0,
- "longitude": 0
}, - "depotId": "string"
}, - "resources": [
- {
- "resourceRef": "string",
- "kind": "string",
- "role": "string",
- "name": "string"
}
]
}Retrieve a single route by its human-readable code. Useful when the UUID is not known.
| code required | string [ 2 .. 50 ] characters Example: ROUTE-2024-001 Route code (human-readable identifier) |
| id required | string Route identifier |
{- "@context": "string",
- "@id": "string",
- "@type": "string",
- "id": "01912345-6789-7abc-def0-123456789abc",
- "code": "ROUTE-2024-001",
- "date": "2024-06-15",
- "crewId": "01912345-6789-7abc-def0-123456789abc",
- "teamName": "Express Logistics",
- "label": "Downtown Morning Route",
- "description": "Morning deliveries covering downtown area",
- "status": "draft",
- "nodeCount": 12,
- "loadCount": 45,
- "isLocked": false,
- "isOptimized": false,
- "defaultNodeDurationMinutes": 15,
- "distanceKm": 42.5,
- "durationMinutes": 60,
- "geometry": "ionF~vfe@k@fB{@hC",
- "progressPercent": 75,
- "createdAt": "2024-06-14T10:30:00+00:00",
- "updatedAt": "2024-06-14T14:45:00+00:00",
- "startAnchor": {
- "street": "string",
- "streetLine2": "string",
- "city": "string",
- "postalCode": "string",
- "countryCode": "string",
- "province": "string",
- "coordinates": {
- "latitude": 0,
- "longitude": 0
}, - "depotId": "string"
}, - "endAnchor": {
- "street": "string",
- "streetLine2": "string",
- "city": "string",
- "postalCode": "string",
- "countryCode": "string",
- "province": "string",
- "coordinates": {
- "latitude": 0,
- "longitude": 0
}, - "depotId": "string"
}, - "resources": [
- {
- "resourceRef": "string",
- "kind": "string",
- "role": "string",
- "name": "string"
}
]
}Retrieve a single route by its UUID. Returns full route details including node and load counts.
| id required | string <uuid> Example: 01912345-6789-7abc-def0-123456789abc Route UUID |
{- "@context": "string",
- "@id": "string",
- "@type": "string",
- "id": "01912345-6789-7abc-def0-123456789abc",
- "code": "ROUTE-2024-001",
- "date": "2024-06-15",
- "crewId": "01912345-6789-7abc-def0-123456789abc",
- "teamName": "Express Logistics",
- "label": "Downtown Morning Route",
- "description": "Morning deliveries covering downtown area",
- "status": "draft",
- "nodeCount": 12,
- "loadCount": 45,
- "isLocked": false,
- "isOptimized": false,
- "defaultNodeDurationMinutes": 15,
- "distanceKm": 42.5,
- "durationMinutes": 60,
- "geometry": "ionF~vfe@k@fB{@hC",
- "progressPercent": 75,
- "createdAt": "2024-06-14T10:30:00+00:00",
- "updatedAt": "2024-06-14T14:45:00+00:00",
- "startAnchor": {
- "street": "string",
- "streetLine2": "string",
- "city": "string",
- "postalCode": "string",
- "countryCode": "string",
- "province": "string",
- "coordinates": {
- "latitude": 0,
- "longitude": 0
}, - "depotId": "string"
}, - "endAnchor": {
- "street": "string",
- "streetLine2": "string",
- "city": "string",
- "postalCode": "string",
- "countryCode": "string",
- "province": "string",
- "coordinates": {
- "latitude": 0,
- "longitude": 0
}, - "depotId": "string"
}, - "resources": [
- {
- "resourceRef": "string",
- "kind": "string",
- "role": "string",
- "name": "string"
}
]
}Update route details. Only draft routes can be modified. Provide only the fields you want to change.
| id required | string <uuid> Example: 01912345-6789-7abc-def0-123456789abc Route UUID |
Route update data (partial update supported)
| crewId | string or null <uuid> Team UUID to assign |
| label | string or null <= 255 characters Short label for the route |
| description | string or null Detailed description |
| defaultNodeDurationMinutes | integer >= 1 Default time per stop in minutes |
{- "crewId": "3bfb64a6-7eeb-4376-b155-bfb9c0405b76",
- "label": "string",
- "description": "string",
- "defaultNodeDurationMinutes": 1
}{- "@context": "string",
- "@id": "string",
- "@type": "string",
- "id": "01912345-6789-7abc-def0-123456789abc",
- "code": "ROUTE-2024-001",
- "date": "2024-06-15",
- "crewId": "01912345-6789-7abc-def0-123456789abc",
- "teamName": "Express Logistics",
- "label": "Downtown Morning Route",
- "description": "Morning deliveries covering downtown area",
- "status": "draft",
- "nodeCount": 12,
- "loadCount": 45,
- "isLocked": false,
- "isOptimized": false,
- "defaultNodeDurationMinutes": 15,
- "distanceKm": 42.5,
- "durationMinutes": 60,
- "geometry": "ionF~vfe@k@fB{@hC",
- "progressPercent": 75,
- "createdAt": "2024-06-14T10:30:00+00:00",
- "updatedAt": "2024-06-14T14:45:00+00:00",
- "startAnchor": {
- "street": "string",
- "streetLine2": "string",
- "city": "string",
- "postalCode": "string",
- "countryCode": "string",
- "province": "string",
- "coordinates": {
- "latitude": 0,
- "longitude": 0
}, - "depotId": "string"
}, - "endAnchor": {
- "street": "string",
- "streetLine2": "string",
- "city": "string",
- "postalCode": "string",
- "countryCode": "string",
- "province": "string",
- "coordinates": {
- "latitude": 0,
- "longitude": 0
}, - "depotId": "string"
}, - "resources": [
- {
- "resourceRef": "string",
- "kind": "string",
- "role": "string",
- "name": "string"
}
]
}Set or clear the route's start and end anchors. Each anchor carries an address with grouped coordinates and an optional depotId (bare Dispatch depot id). Anchors may be the same depot, different depots, or non-depot park spots. Omit or null an anchor to clear it.
| id required | string <uuid> Example: 01912345-6789-7abc-def0-123456789abc Route UUID |
The updated Route resource
RouteAnchorInput (object) or null | |
RouteAnchorInput (object) or null |
{- "startAnchor": {
- "street": "string",
- "streetLine2": "string",
- "city": "string",
- "postalCode": "string",
- "countryCode": "st",
- "province": "string",
- "coordinates": {
- "latitude": -90,
- "longitude": -180
}, - "depotId": "string"
}, - "endAnchor": {
- "street": "string",
- "streetLine2": "string",
- "city": "string",
- "postalCode": "string",
- "countryCode": "st",
- "province": "string",
- "coordinates": {
- "latitude": -90,
- "longitude": -180
}, - "depotId": "string"
}
}{- "@context": "string",
- "@id": "string",
- "@type": "string",
- "id": "01912345-6789-7abc-def0-123456789abc",
- "code": "ROUTE-2024-001",
- "date": "2024-06-15",
- "crewId": "01912345-6789-7abc-def0-123456789abc",
- "teamName": "Express Logistics",
- "label": "Downtown Morning Route",
- "description": "Morning deliveries covering downtown area",
- "status": "draft",
- "nodeCount": 12,
- "loadCount": 45,
- "isLocked": false,
- "isOptimized": false,
- "defaultNodeDurationMinutes": 15,
- "distanceKm": 42.5,
- "durationMinutes": 60,
- "geometry": "ionF~vfe@k@fB{@hC",
- "progressPercent": 75,
- "createdAt": "2024-06-14T10:30:00+00:00",
- "updatedAt": "2024-06-14T14:45:00+00:00",
- "startAnchor": {
- "street": "string",
- "streetLine2": "string",
- "city": "string",
- "postalCode": "string",
- "countryCode": "string",
- "province": "string",
- "coordinates": {
- "latitude": 0,
- "longitude": 0
}, - "depotId": "string"
}, - "endAnchor": {
- "street": "string",
- "streetLine2": "string",
- "city": "string",
- "postalCode": "string",
- "countryCode": "string",
- "province": "string",
- "coordinates": {
- "latitude": 0,
- "longitude": 0
}, - "depotId": "string"
}, - "resources": [
- {
- "resourceRef": "string",
- "kind": "string",
- "role": "string",
- "name": "string"
}
]
}Cancel a route. Routes can be cancelled in draft or confirmed status. In-progress routes should be completed or failed through the execution endpoints.
| id required | string <uuid> Example: 01912345-6789-7abc-def0-123456789abc Route UUID |
{- "@context": "string",
- "@id": "string",
- "@type": "string",
- "id": "01912345-6789-7abc-def0-123456789abc",
- "code": "ROUTE-2024-001",
- "date": "2024-06-15",
- "crewId": "01912345-6789-7abc-def0-123456789abc",
- "teamName": "Express Logistics",
- "label": "Downtown Morning Route",
- "description": "Morning deliveries covering downtown area",
- "status": "draft",
- "nodeCount": 12,
- "loadCount": 45,
- "isLocked": false,
- "isOptimized": false,
- "defaultNodeDurationMinutes": 15,
- "distanceKm": 42.5,
- "durationMinutes": 60,
- "geometry": "ionF~vfe@k@fB{@hC",
- "progressPercent": 75,
- "createdAt": "2024-06-14T10:30:00+00:00",
- "updatedAt": "2024-06-14T14:45:00+00:00",
- "startAnchor": {
- "street": "string",
- "streetLine2": "string",
- "city": "string",
- "postalCode": "string",
- "countryCode": "string",
- "province": "string",
- "coordinates": {
- "latitude": 0,
- "longitude": 0
}, - "depotId": "string"
}, - "endAnchor": {
- "street": "string",
- "streetLine2": "string",
- "city": "string",
- "postalCode": "string",
- "countryCode": "string",
- "province": "string",
- "coordinates": {
- "latitude": 0,
- "longitude": 0
}, - "depotId": "string"
}, - "resources": [
- {
- "resourceRef": "string",
- "kind": "string",
- "role": "string",
- "name": "string"
}
]
}Confirm a draft route for execution. Once confirmed, the route is ready to be assigned to a driver and started. This action validates all nodes and loads.
| id required | string <uuid> Example: 01912345-6789-7abc-def0-123456789abc Route UUID |
{- "@context": "string",
- "@id": "string",
- "@type": "string",
- "id": "01912345-6789-7abc-def0-123456789abc",
- "code": "ROUTE-2024-001",
- "date": "2024-06-15",
- "crewId": "01912345-6789-7abc-def0-123456789abc",
- "teamName": "Express Logistics",
- "label": "Downtown Morning Route",
- "description": "Morning deliveries covering downtown area",
- "status": "draft",
- "nodeCount": 12,
- "loadCount": 45,
- "isLocked": false,
- "isOptimized": false,
- "defaultNodeDurationMinutes": 15,
- "distanceKm": 42.5,
- "durationMinutes": 60,
- "geometry": "ionF~vfe@k@fB{@hC",
- "progressPercent": 75,
- "createdAt": "2024-06-14T10:30:00+00:00",
- "updatedAt": "2024-06-14T14:45:00+00:00",
- "startAnchor": {
- "street": "string",
- "streetLine2": "string",
- "city": "string",
- "postalCode": "string",
- "countryCode": "string",
- "province": "string",
- "coordinates": {
- "latitude": 0,
- "longitude": 0
}, - "depotId": "string"
}, - "endAnchor": {
- "street": "string",
- "streetLine2": "string",
- "city": "string",
- "postalCode": "string",
- "countryCode": "string",
- "province": "string",
- "coordinates": {
- "latitude": 0,
- "longitude": 0
}, - "depotId": "string"
}, - "resources": [
- {
- "resourceRef": "string",
- "kind": "string",
- "role": "string",
- "name": "string"
}
]
}Start a human-in-the-loop route dispatch: optimize the route (propose flow — nothing is written to the route yet), then ask the operator to Accept or Reject the optimized plan on the /api/operations feed before it is applied. Returns 202 with the route; the RouteDispatchSaga runs in the background.
| id required | string <uuid> Example: 01912345-6789-7abc-def0-123456789abc Route UUID |
{- "@context": "string",
- "@id": "string",
- "@type": "string",
- "id": "01912345-6789-7abc-def0-123456789abc",
- "code": "ROUTE-2024-001",
- "date": "2024-06-15",
- "crewId": "01912345-6789-7abc-def0-123456789abc",
- "teamName": "Express Logistics",
- "label": "Downtown Morning Route",
- "description": "Morning deliveries covering downtown area",
- "status": "draft",
- "nodeCount": 12,
- "loadCount": 45,
- "isLocked": false,
- "isOptimized": false,
- "defaultNodeDurationMinutes": 15,
- "distanceKm": 42.5,
- "durationMinutes": 60,
- "geometry": "ionF~vfe@k@fB{@hC",
- "progressPercent": 75,
- "createdAt": "2024-06-14T10:30:00+00:00",
- "updatedAt": "2024-06-14T14:45:00+00:00",
- "startAnchor": {
- "street": "string",
- "streetLine2": "string",
- "city": "string",
- "postalCode": "string",
- "countryCode": "string",
- "province": "string",
- "coordinates": {
- "latitude": 0,
- "longitude": 0
}, - "depotId": "string"
}, - "endAnchor": {
- "street": "string",
- "streetLine2": "string",
- "city": "string",
- "postalCode": "string",
- "countryCode": "string",
- "province": "string",
- "coordinates": {
- "latitude": 0,
- "longitude": 0
}, - "depotId": "string"
}, - "resources": [
- {
- "resourceRef": "string",
- "kind": "string",
- "role": "string",
- "name": "string"
}
]
}Queue asynchronous rendering of the route as a manifest / run-sheet Document (default PDF) — driver run-sheet listing every stop in optimized sequence with addresses, time windows, pickup/delivery tasks and the assigned rig. Returns immediately (202) with a QueueJobResponse; track progress and download on the /api/operations feed (its JobItem shares the returned jobId).
| id required | string <uuid> Example: 01912345-6789-7abc-def0-123456789abc Route UUID |
The new Route resource
| format | string Default: "pdf" Enum: "pdf" "html" Output format for the manifest. |
| includeLoads | boolean Default: true Whether to include detailed load information. |
| includeNodes | boolean Default: true Whether to include route node details. |
{- "format": "pdf",
- "includeLoads": true,
- "includeNodes": true
}{- "@context": "string",
- "@id": "string",
- "@type": "string",
- "jobId": "",
- "kind": "",
- "title": "",
- "status": "pending",
- "subjectRef": "string"
}Queue asynchronous optimization of the route's stop ordering to minimize travel time and distance. Returns immediately (202) with a QueueJobResponse; the optimized plan is written straight onto the route when the background run completes. Track progress and outcome on the /api/operations feed (its JobItem shares the returned jobId). All stops must have coordinates.
| id required | string <uuid> Example: 01912345-6789-7abc-def0-123456789abc Route UUID |
Optional optimization constraints plus an optional engine override. Omit everything to optimize with the route's persisted anchors/defaults and the registry's default engine.
| maxDurationMinutes | integer Max route duration in minutes |
| maxDistanceKm | integer Max route distance in kilometers |
| engine | string or null Optional optimization-engine key; omit to let the registry pick the default (in-house greedy). |
{- "maxDurationMinutes": 480,
- "maxDistanceKm": 500,
- "engine": "in_house_greedy"
}{- "@context": "string",
- "@id": "string",
- "@type": "string",
- "jobId": "",
- "kind": "",
- "title": "",
- "status": "pending",
- "subjectRef": "string"
}Spawn a new draft route carrying only the incomplete stops of a failed or cancelled route. A stop is incomplete unless its execution reached the completed state — pending, skipped, and failed stops are all recovered, re-sequenced 1..N, with their package/shipment refs and task definitions. Returns the newly created route. Fails (409) when the source route has no incomplete stops.
| id required | string <uuid> Example: 01912345-6789-7abc-def0-123456789abc UUID of the source (failed/cancelled) route to recover from |
{- "@context": "string",
- "@id": "string",
- "@type": "string",
- "id": "01912345-6789-7abc-def0-123456789abc",
- "code": "ROUTE-2024-001",
- "date": "2024-06-15",
- "crewId": "01912345-6789-7abc-def0-123456789abc",
- "teamName": "Express Logistics",
- "label": "Downtown Morning Route",
- "description": "Morning deliveries covering downtown area",
- "status": "draft",
- "nodeCount": 12,
- "loadCount": 45,
- "isLocked": false,
- "isOptimized": false,
- "defaultNodeDurationMinutes": 15,
- "distanceKm": 42.5,
- "durationMinutes": 60,
- "geometry": "ionF~vfe@k@fB{@hC",
- "progressPercent": 75,
- "createdAt": "2024-06-14T10:30:00+00:00",
- "updatedAt": "2024-06-14T14:45:00+00:00",
- "startAnchor": {
- "street": "string",
- "streetLine2": "string",
- "city": "string",
- "postalCode": "string",
- "countryCode": "string",
- "province": "string",
- "coordinates": {
- "latitude": 0,
- "longitude": 0
}, - "depotId": "string"
}, - "endAnchor": {
- "street": "string",
- "streetLine2": "string",
- "city": "string",
- "postalCode": "string",
- "countryCode": "string",
- "province": "string",
- "coordinates": {
- "latitude": 0,
- "longitude": 0
}, - "depotId": "string"
}, - "resources": [
- {
- "resourceRef": "string",
- "kind": "string",
- "role": "string",
- "name": "string"
}
]
}Replace the sequence of a route's nodes with an operator-supplied order. The supplied list must contain every current node id exactly once; partial sequences, duplicates, or unknown ids are rejected.
| id required | string <uuid> Example: 01912345-6789-7abc-def0-123456789abc Route UUID |
Ordered list of node ULIDs
| nodeSequence required | Array of strings Ordered node ULIDs, applied as positions 1..N. |
{- "nodeSequence": [
- "string"
]
}{- "@context": "string",
- "@id": "string",
- "@type": "string",
- "id": "01912345-6789-7abc-def0-123456789abc",
- "code": "ROUTE-2024-001",
- "date": "2024-06-15",
- "crewId": "01912345-6789-7abc-def0-123456789abc",
- "teamName": "Express Logistics",
- "label": "Downtown Morning Route",
- "description": "Morning deliveries covering downtown area",
- "status": "draft",
- "nodeCount": 12,
- "loadCount": 45,
- "isLocked": false,
- "isOptimized": false,
- "defaultNodeDurationMinutes": 15,
- "distanceKm": 42.5,
- "durationMinutes": 60,
- "geometry": "ionF~vfe@k@fB{@hC",
- "progressPercent": 75,
- "createdAt": "2024-06-14T10:30:00+00:00",
- "updatedAt": "2024-06-14T14:45:00+00:00",
- "startAnchor": {
- "street": "string",
- "streetLine2": "string",
- "city": "string",
- "postalCode": "string",
- "countryCode": "string",
- "province": "string",
- "coordinates": {
- "latitude": 0,
- "longitude": 0
}, - "depotId": "string"
}, - "endAnchor": {
- "street": "string",
- "streetLine2": "string",
- "city": "string",
- "postalCode": "string",
- "countryCode": "string",
- "province": "string",
- "coordinates": {
- "latitude": 0,
- "longitude": 0
}, - "depotId": "string"
}, - "resources": [
- {
- "resourceRef": "string",
- "kind": "string",
- "role": "string",
- "name": "string"
}
]
}Retrieve all nodes (stops) for a specific route, ordered by sequence.
| routeId required | string <uuid> Example: 01912345-6789-7abc-def0-123456789abc Route UUID |
| page | integer Default: 1 The collection page number |
{- "totalItems": 0,
- "search": {
- "@type": "string",
- "template": "string",
- "variableRepresentation": "string",
- "mapping": [
- {
- "@type": "string",
- "variable": "string",
- "property": "string",
- "required": true
}
]
}, - "view": {
- "@id": "string",
- "@type": "string",
- "first": "string",
- "last": "string",
- "previous": "string",
- "next": "string"
}, - "member": [
- {
- "@context": "string",
- "@id": "string",
- "@type": "string",
- "id": "string",
- "routeId": "string",
- "sequence": 1,
- "status": "pending",
- "street": "string",
- "streetLine2": "string",
- "city": "string",
- "postalCode": "string",
- "countryCode": "string",
- "province": "string",
- "latitude": 50.8503,
- "longitude": 4.3517,
- "shipmentId": "string",
- "serviceDurationMinutes": 15,
- "timeWindowStart": "09:00",
- "timeWindowEnd": "17:00",
- "instructions": "Gate code 4821, leave with reception.",
- "legDistanceKm": 12.4,
- "legDurationMinutes": 25,
- "arrivalTime": "string",
- "departureTime": "string",
- "createdAt": "string",
- "updatedAt": "string",
- "handlingRequirements": [
- "tail_lift",
- "two_person"
]
}
]
}Add a new stop/node to a route at a specific location.
| routeId required | string <uuid> Example: 01912345-6789-7abc-def0-123456789abc Route UUID |
The new RouteNode resource
| type required | string Default: "stop" Enum: "pickup" "delivery" "waypoint" "stop" |
| latitude required | number [ -90 .. 90 ] |
| longitude required | number [ -180 .. 180 ] |
| address | string or null <= 500 characters |
| street | string or null <= 255 characters |
| city | string or null <= 100 characters |
| postalCode | string or null <= 20 characters |
| countryCode | string or null <= 2 characters |
| province | string or null <= 100 characters |
| label | string or null <= 255 characters |
| timeWindowStart | string or null^(.*(^([01]\d|2[0-3]):[0-5]\d$).*)$ |
| timeWindowEnd | string or null^(.*(^([01]\d|2[0-3]):[0-5]\d$).*)$ |
| serviceDurationMinutes | integer or null > 0 |
| contactName | string or null <= 255 characters |
| contactPhone | string or null <= 50 characters |
| instructions | string or null <= 1000 characters |
| sequence | integer or null >= 0 |
| packageId | string or null |
{- "type": "pickup",
- "latitude": -90,
- "longitude": -180,
- "address": "string",
- "street": "string",
- "city": "string",
- "postalCode": "string",
- "countryCode": "st",
- "province": "string",
- "label": "string",
- "timeWindowStart": "string",
- "timeWindowEnd": "string",
- "serviceDurationMinutes": 0,
- "contactName": "string",
- "contactPhone": "string",
- "instructions": "string",
- "sequence": 0,
- "packageId": "string"
}{- "@context": "string",
- "@id": "string",
- "@type": "string",
- "id": "string",
- "routeId": "string",
- "sequence": 1,
- "status": "pending",
- "street": "string",
- "streetLine2": "string",
- "city": "string",
- "postalCode": "string",
- "countryCode": "string",
- "province": "string",
- "latitude": 50.8503,
- "longitude": 4.3517,
- "shipmentId": "string",
- "serviceDurationMinutes": 15,
- "timeWindowStart": "09:00",
- "timeWindowEnd": "17:00",
- "instructions": "Gate code 4821, leave with reception.",
- "legDistanceKm": 12.4,
- "legDurationMinutes": 25,
- "arrivalTime": "string",
- "departureTime": "string",
- "createdAt": "string",
- "updatedAt": "string",
- "handlingRequirements": [
- "tail_lift",
- "two_person"
]
}Remove a stop/node from a route (e.g. dragging a stop back to the unscheduled pool).
| routeId required | string <uuid> Example: 01912345-6789-7abc-def0-123456789abc Route UUID |
| nodeId required | string <uuid> Example: 01912345-6789-7abc-def0-123456789def Node UUID |
Update a node's arrival time window, service duration (time-at-stop) and delivery instructions.
| routeId required | string <uuid> Example: 01912345-6789-7abc-def0-123456789abc Route UUID |
| nodeId required | string <uuid> Example: 01912345-6789-7abc-def0-123456789def Node UUID |
The updated RouteNode resource
| timeWindowStart | string or null^(.*(^([01]\d|2[0-3]):[0-5]\d$).*)$ |
| timeWindowEnd | string or null^(.*(^([01]\d|2[0-3]):[0-5]\d$).*)$ |
| serviceDurationMinutes | integer > 0 |
| instructions | string or null <= 1000 characters |
{- "timeWindowStart": "string",
- "timeWindowEnd": "string",
- "serviceDurationMinutes": 0,
- "instructions": "string"
}{- "@context": "string",
- "@id": "string",
- "@type": "string",
- "id": "string",
- "routeId": "string",
- "sequence": 1,
- "status": "pending",
- "street": "string",
- "streetLine2": "string",
- "city": "string",
- "postalCode": "string",
- "countryCode": "string",
- "province": "string",
- "latitude": 50.8503,
- "longitude": 4.3517,
- "shipmentId": "string",
- "serviceDurationMinutes": 15,
- "timeWindowStart": "09:00",
- "timeWindowEnd": "17:00",
- "instructions": "Gate code 4821, leave with reception.",
- "legDistanceKm": 12.4,
- "legDurationMinutes": 25,
- "arrivalTime": "string",
- "departureTime": "string",
- "createdAt": "string",
- "updatedAt": "string",
- "handlingRequirements": [
- "tail_lift",
- "two_person"
]
}Retrieve all tasks (with their operations) for a specific route node.
| routeId required | string <uuid> Route UUID |
| nodeId required | string <uuid> Node UUID |
| page | integer Default: 1 The collection page number |
{- "totalItems": 0,
- "search": {
- "@type": "string",
- "template": "string",
- "variableRepresentation": "string",
- "mapping": [
- {
- "@type": "string",
- "variable": "string",
- "property": "string",
- "required": true
}
]
}, - "view": {
- "@id": "string",
- "@type": "string",
- "first": "string",
- "last": "string",
- "previous": "string",
- "next": "string"
}, - "member": [
- {
- "@context": "string",
- "@id": "string",
- "@type": "string",
- "id": "string",
- "routeId": "string",
- "nodeId": "string",
- "type": "delivery",
- "title": "string",
- "description": "string",
- "status": "pending",
- "packageId": "string",
- "completedAt": "string",
- "failureReason": "string",
- "createdAt": "string",
- "updatedAt": "string",
- "operations": [
- {
- "id": "string",
- "taskId": "string",
- "type": "barcode_scan",
- "title": "string",
- "status": "pending",
- "result": "string",
- "notes": "string",
- "completedAt": "string",
- "failureReason": "string"
}
], - "payload": {
- "unitRefs": [
- "string"
], - "fromCarrierRef": "string",
- "toCarrierRef": "string",
- "codAmountCents": 0,
- "codCurrency": "string",
- "codOrderRef": "string",
- "podRef": "string"
}
}
]
}Add a per-stop task to a route node. Returns the created task.
| routeId required | string <uuid> Route UUID |
| nodeId required | string <uuid> Node UUID |
The new RouteNodeTask resource
| type required | string Default: "custom" Enum: "delivery" "pickup" "service" "inspection" "signature" "photo" "payment" "transload" "pod" "custom" |
| title required | string <= 255 characters Default: "" |
| description | string or null <= 2000 characters |
| packageId | string or null |
AddNodeTaskPayloadInput (object) or null |
{- "type": "delivery",
- "title": "",
- "description": "string",
- "packageId": "string",
- "payload": {
- "unitRefs": [
- "string"
], - "fromCarrierRef": "string",
- "toCarrierRef": "string",
- "codAmountCents": 0,
- "codCurrency": "str",
- "codOrderRef": "string",
- "podRef": "string"
}
}{- "@context": "string",
- "@id": "string",
- "@type": "string",
- "id": "string",
- "routeId": "string",
- "nodeId": "string",
- "type": "delivery",
- "title": "string",
- "description": "string",
- "status": "pending",
- "packageId": "string",
- "completedAt": "string",
- "failureReason": "string",
- "createdAt": "string",
- "updatedAt": "string",
- "operations": [
- {
- "id": "string",
- "taskId": "string",
- "type": "barcode_scan",
- "title": "string",
- "status": "pending",
- "result": "string",
- "notes": "string",
- "completedAt": "string",
- "failureReason": "string"
}
], - "payload": {
- "unitRefs": [
- "string"
], - "fromCarrierRef": "string",
- "toCarrierRef": "string",
- "codAmountCents": 0,
- "codCurrency": "string",
- "codOrderRef": "string",
- "podRef": "string"
}
}Mark a node task as completed. For a POD task, submit the proof captured at the stop (recipient name, signature/photo Document refs, captured-at) to sign the Shipping Pod. Idempotent — completing an already-completed task, or replaying a POD completion, is a no-op.
| routeId required | string <uuid> Route UUID |
| nodeId required | string <uuid> Node UUID |
| taskId required | string Task ULID |
The new RouteNodeTask resource
| recipientName | string or null <= 255 characters |
| signatureDocumentRef | string or null ResourceUri / Document id of the uploaded signature image. |
| capturedAt | string or null ISO 8601 capture timestamp; required when proof is submitted. |
| photoDocumentRefs | Array of strings ResourceUris / Document ids of uploaded delivery photos. |
CoordinatesInput (object) or null | |
| notes | string or null <= 2000 characters |
| outcome | string or null Enum: "recipient" "third_party" "mailbox" "safe_place" "other" Delivery outcome recorded at the stop (recipient/third_party/mailbox/safe_place/other). |
{- "recipientName": "string",
- "signatureDocumentRef": "string",
- "capturedAt": "string",
- "photoDocumentRefs": [
- "string"
], - "coordinates": {
- "latitude": -90,
- "longitude": -180
}, - "notes": "string",
- "outcome": "recipient"
}{- "@context": "string",
- "@id": "string",
- "@type": "string",
- "id": "string",
- "routeId": "string",
- "nodeId": "string",
- "type": "delivery",
- "title": "string",
- "description": "string",
- "status": "pending",
- "packageId": "string",
- "completedAt": "string",
- "failureReason": "string",
- "createdAt": "string",
- "updatedAt": "string",
- "operations": [
- {
- "id": "string",
- "taskId": "string",
- "type": "barcode_scan",
- "title": "string",
- "status": "pending",
- "result": "string",
- "notes": "string",
- "completedAt": "string",
- "failureReason": "string"
}
], - "payload": {
- "unitRefs": [
- "string"
], - "fromCarrierRef": "string",
- "toCarrierRef": "string",
- "codAmountCents": 0,
- "codCurrency": "string",
- "codOrderRef": "string",
- "podRef": "string"
}
}Mark a node task as failed, optionally capturing a reason. A failed task is terminal and cannot subsequently be completed. Idempotent — failing an already-failed task is a no-op.
| routeId required | string <uuid> Route UUID |
| nodeId required | string <uuid> Node UUID |
| taskId required | string Task ULID |
The new RouteNodeTask resource
| reason | string or null <= 2000 characters |
{- "reason": "string"
}{- "@context": "string",
- "@id": "string",
- "@type": "string",
- "id": "string",
- "routeId": "string",
- "nodeId": "string",
- "type": "delivery",
- "title": "string",
- "description": "string",
- "status": "pending",
- "packageId": "string",
- "completedAt": "string",
- "failureReason": "string",
- "createdAt": "string",
- "updatedAt": "string",
- "operations": [
- {
- "id": "string",
- "taskId": "string",
- "type": "barcode_scan",
- "title": "string",
- "status": "pending",
- "result": "string",
- "notes": "string",
- "completedAt": "string",
- "failureReason": "string"
}
], - "payload": {
- "unitRefs": [
- "string"
], - "fromCarrierRef": "string",
- "toCarrierRef": "string",
- "codAmountCents": 0,
- "codCurrency": "string",
- "codOrderRef": "string",
- "podRef": "string"
}
}Add an operation (atomic step) to a node task. Returns the updated task.
| routeId required | string <uuid> Route UUID |
| nodeId required | string <uuid> Node UUID |
| taskId required | string Task ULID |
The new RouteNodeTask resource
| type required | string Default: "note" Enum: "barcode_scan" "signature_capture" "photo_capture" "payment_collection" "document_scan" "checklist" "note" "confirmation" |
| title required | string <= 255 characters Default: "" |
{- "type": "barcode_scan",
- "title": ""
}{- "@context": "string",
- "@id": "string",
- "@type": "string",
- "id": "string",
- "routeId": "string",
- "nodeId": "string",
- "type": "delivery",
- "title": "string",
- "description": "string",
- "status": "pending",
- "packageId": "string",
- "completedAt": "string",
- "failureReason": "string",
- "createdAt": "string",
- "updatedAt": "string",
- "operations": [
- {
- "id": "string",
- "taskId": "string",
- "type": "barcode_scan",
- "title": "string",
- "status": "pending",
- "result": "string",
- "notes": "string",
- "completedAt": "string",
- "failureReason": "string"
}
], - "payload": {
- "unitRefs": [
- "string"
], - "fromCarrierRef": "string",
- "toCarrierRef": "string",
- "codAmountCents": 0,
- "codCurrency": "string",
- "codOrderRef": "string",
- "podRef": "string"
}
}Mark a task operation as completed, optionally capturing a result and notes. Idempotent.
| routeId required | string <uuid> Route UUID |
| nodeId required | string <uuid> Node UUID |
| taskId required | string Task ULID |
| operationId required | string Operation ULID |
The new RouteNodeTask resource
| result | string or null <= 2000 characters |
| notes | string or null <= 2000 characters |
{- "result": "string",
- "notes": "string"
}{- "@context": "string",
- "@id": "string",
- "@type": "string",
- "id": "string",
- "routeId": "string",
- "nodeId": "string",
- "type": "delivery",
- "title": "string",
- "description": "string",
- "status": "pending",
- "packageId": "string",
- "completedAt": "string",
- "failureReason": "string",
- "createdAt": "string",
- "updatedAt": "string",
- "operations": [
- {
- "id": "string",
- "taskId": "string",
- "type": "barcode_scan",
- "title": "string",
- "status": "pending",
- "result": "string",
- "notes": "string",
- "completedAt": "string",
- "failureReason": "string"
}
], - "payload": {
- "unitRefs": [
- "string"
], - "fromCarrierRef": "string",
- "toCarrierRef": "string",
- "codAmountCents": 0,
- "codCurrency": "string",
- "codOrderRef": "string",
- "podRef": "string"
}
}Mark a task operation as failed, optionally capturing a reason. A failed operation is terminal and cannot subsequently be completed. Idempotent.
| routeId required | string <uuid> Route UUID |
| nodeId required | string <uuid> Node UUID |
| taskId required | string Task ULID |
| operationId required | string Operation ULID |
The new RouteNodeTask resource
| reason | string or null <= 2000 characters |
{- "reason": "string"
}{- "@context": "string",
- "@id": "string",
- "@type": "string",
- "id": "string",
- "routeId": "string",
- "nodeId": "string",
- "type": "delivery",
- "title": "string",
- "description": "string",
- "status": "pending",
- "packageId": "string",
- "completedAt": "string",
- "failureReason": "string",
- "createdAt": "string",
- "updatedAt": "string",
- "operations": [
- {
- "id": "string",
- "taskId": "string",
- "type": "barcode_scan",
- "title": "string",
- "status": "pending",
- "result": "string",
- "notes": "string",
- "completedAt": "string",
- "failureReason": "string"
}
], - "payload": {
- "unitRefs": [
- "string"
], - "fromCarrierRef": "string",
- "toCarrierRef": "string",
- "codAmountCents": 0,
- "codCurrency": "string",
- "codOrderRef": "string",
- "podRef": "string"
}
}Queue an optimization run for the route and return it immediately with status=running. The engine work happens in the background; poll GET /routing/optimization-runs/{id} (or subscribe to Mercure topic /routes/{routeId}) to follow the phases. When the run reaches awaiting_decision it carries a staged proposal — the route is NOT modified until the run is accepted. A route may only have ONE run in flight: requesting another while one is running or awaiting a decision is rejected with 409.
| routeId required | string <uuid> Example: 01912345-6789-7abc-def0-123456789abc Route UUID |
The new OptimizationRun resource
| maxDurationMinutes | integer or null > 0 |
| maxDistanceKm | integer or null > 0 |
OptimizationOverridesInput (object) or null |
{- "maxDurationMinutes": 0,
- "maxDistanceKm": 0,
- "overrides": {
- "startAt": "2019-08-24T14:15:22Z",
- "endAt": "2019-08-24T14:15:22Z",
- "startAnchor": {
- "street": "string",
- "streetLine2": "string",
- "city": "string",
- "postalCode": "string",
- "countryCode": "st",
- "province": "string",
- "coordinates": {
- "latitude": -90,
- "longitude": -180
}, - "depotId": "string"
}, - "endAnchor": {
- "street": "string",
- "streetLine2": "string",
- "city": "string",
- "postalCode": "string",
- "countryCode": "st",
- "province": "string",
- "coordinates": {
- "latitude": -90,
- "longitude": -180
}, - "depotId": "string"
}, - "returnToDepot": true,
- "avoidTolls": true,
- "avoidHighways": true,
- "routingPreference": "fastest"
}
}{- "@context": "string",
- "@id": "string",
- "@type": "string",
- "id": "01912345-6789-7abc-def0-123456789abc",
- "routeId": "01912345-6789-7abc-def0-123456789abc",
- "status": "awaiting_decision",
- "phase": "solving",
- "phaseLabel": "Optimizing",
- "phaseDetail": "google",
- "progressPercent": 45,
- "engineKind": "in_house_greedy",
- "requestedBy": "string",
- "decidedBy": "string",
- "proposal": {
- "stopSequence": [
- "string"
], - "legs": {
- "property1": {
- "property1": 0,
- "property2": 0
}, - "property2": {
- "property1": 0,
- "property2": 0
}
}, - "totalDistanceMeters": 0,
- "totalDurationSeconds": 0,
- "geometry": "string",
- "unassignedStopIds": [
- "string"
], - "engineKind": "string"
}, - "failureReason": "string",
- "decisionReason": "string",
- "createdAt": "2026-07-14T09:00:00+00:00",
- "updatedAt": "2026-07-14T09:00:12+00:00"
}Assign an individual fleet resource (power unit, load carrier, driver, or rigid vehicle) directly to a route. A route may be operated by a team OR by individually-assigned resources (or both). Cardinality: at most one propulsion resource, at most one driver, any number of load carriers. The role is derived from the resource when omitted.
| routeId required | string <uuid> Example: 01912345-6789-7abc-def0-123456789abc Route UUID |
| id required | string Route identifier |
Resource assignment data
| resourceRef required | string Opaque ResourceUri of the fleet unit or driver |
| role | string or null Enum: "power_unit" "load_carrier" "driver" "rigid_vehicle" Optional role override; derived from the resource kind when omitted |
{- "resourceRef": "glacia:///fleet/units/01912345-6789-7abc-def0-123456789abc",
- "role": "power_unit"
}{- "@context": "string",
- "@id": "string",
- "@type": "string",
- "id": "01912345-6789-7abc-def0-123456789abc",
- "code": "ROUTE-2024-001",
- "date": "2024-06-15",
- "crewId": "01912345-6789-7abc-def0-123456789abc",
- "teamName": "Express Logistics",
- "label": "Downtown Morning Route",
- "description": "Morning deliveries covering downtown area",
- "status": "draft",
- "nodeCount": 12,
- "loadCount": 45,
- "isLocked": false,
- "isOptimized": false,
- "defaultNodeDurationMinutes": 15,
- "distanceKm": 42.5,
- "durationMinutes": 60,
- "geometry": "ionF~vfe@k@fB{@hC",
- "progressPercent": 75,
- "createdAt": "2024-06-14T10:30:00+00:00",
- "updatedAt": "2024-06-14T14:45:00+00:00",
- "startAnchor": {
- "street": "string",
- "streetLine2": "string",
- "city": "string",
- "postalCode": "string",
- "countryCode": "string",
- "province": "string",
- "coordinates": {
- "latitude": 0,
- "longitude": 0
}, - "depotId": "string"
}, - "endAnchor": {
- "street": "string",
- "streetLine2": "string",
- "city": "string",
- "postalCode": "string",
- "countryCode": "string",
- "province": "string",
- "coordinates": {
- "latitude": 0,
- "longitude": 0
}, - "depotId": "string"
}, - "resources": [
- {
- "resourceRef": "string",
- "kind": "string",
- "role": "string",
- "name": "string"
}
]
}Remove an individually-assigned fleet resource from a route. The resourceRef path segment is the URL-encoded ResourceUri of the assigned resource. Unknown references are a no-op.
| routeId required | string <uuid> Example: 01912345-6789-7abc-def0-123456789abc Route UUID |
| resourceRef required | string Example: glacia:%2F%2F%2Ffleet%2Funits%2F01912345-6789-7abc-def0-123456789abc URL-encoded ResourceUri of the assigned resource |
Returns a single payload combining the route's plan facets (status, code, date, team, node and load counts), optimization-saga facets (current optimization id/status/progress/goal, pending and applied counters, last applied timestamp), and execution facets (execution id, status, progress, started/completed timestamps). Backed by the route_snapshot_views projection — eventually consistent with the underlying aggregates.
| routeId required | string <uuid> Example: 01912345-6789-7abc-def0-123456789abc Route UUID |
{- "@context": "string",
- "@id": "string",
- "@type": "string",
- "routeId": "01J0AAAAAAAAAAAAAAAAAAAAAA",
- "tenantId": "string",
- "status": "draft",
- "code": "ROUTE-2024-001",
- "date": "2024-06-15",
- "crewId": "string",
- "nodeCount": 12,
- "loadCount": 45,
- "currentOptimizationId": "string",
- "currentOptimizationStatus": "Running",
- "currentOptimizationOutcome": "applied",
- "currentOptimizationProgress": 57,
- "currentOptimizationGoal": "fastest",
- "pendingOptimizationCount": 0,
- "appliedOptimizationCount": 3,
- "lastOptimizationAppliedAt": "string",
- "executionId": "string",
- "executionStatus": "pending",
- "executionProgress": 42,
- "executionStartedAt": "string",
- "executionCompletedAt": "string",
- "updatedAt": "string"
}Represents a geocoding result.
Geocoding converts addresses to coordinates (forward geocoding) or coordinates to addresses (reverse geocoding).
Convert an address string to geographic coordinates (forward geocoding).
Address to geocode
| address required | string Full address to geocode |
{- "address": "Keizersgracht 123, 1015 CJ Amsterdam, Netherlands"
}{- "@context": "string",
- "@id": "string",
- "@type": "string",
- "address": "Keizersgracht 123, 1015 CJ Amsterdam, Netherlands",
- "coordinates": {
- "latitude": 52.3676,
- "longitude": 4.9041
}, - "confidence": 0.95
}Convert geographic coordinates to an address (reverse geocoding).
Coordinates to reverse geocode
| latitude required | number <float> [ -90 .. 90 ] Latitude coordinate |
| longitude required | number <float> [ -180 .. 180 ] Longitude coordinate |
{- "latitude": 52.3676,
- "longitude": 4.9041
}{- "@context": "string",
- "@id": "string",
- "@type": "string",
- "address": "Keizersgracht 123, 1015 CJ Amsterdam, Netherlands",
- "coordinates": {
- "latitude": 52.3676,
- "longitude": 4.9041
}, - "confidence": 0.95
}Generate a customer reference
The new CustomerReference resource
| number | string The generated customer reference |
| type | string Resource type |
| barcode | string or null GS1-128 barcode (if applicable) |
| generatedAt | string Generation timestamp (ISO 8601) |
{- "number": "CRF000000001",
- "type": "routing.customer_reference",
- "barcode": "string",
- "generatedAt": "2026-02-15T10:30:00+00:00"
}{- "@context": "string",
- "@id": "string",
- "@type": "string",
- "number": "CRF000000001",
- "type": "routing.customer_reference",
- "barcode": "string",
- "generatedAt": "2026-02-15T10:30:00+00:00"
}Generate a load barcode
The new LoadBarcode resource
| number | string The generated load barcode |
| type | string Resource type |
| barcode | string or null GS1-128 barcode (if applicable) |
| generatedAt | string Generation timestamp (ISO 8601) |
{- "number": "LDB000000001",
- "type": "routing.load_barcode",
- "barcode": "string",
- "generatedAt": "2026-02-15T10:30:00+00:00"
}{- "@context": "string",
- "@id": "string",
- "@type": "string",
- "number": "LDB000000001",
- "type": "routing.load_barcode",
- "barcode": "string",
- "generatedAt": "2026-02-15T10:30:00+00:00"
}Preview the next load barcode
| date | string <date> |
{- "@context": "string",
- "@id": "string",
- "@type": "string",
- "number": "LDB000000001",
- "type": "routing.load_barcode",
- "barcode": "string",
- "generatedAt": "2026-02-15T10:30:00+00:00"
}Generate a route code
The new RouteCode resource
| number | string The generated route code |
| type | string Resource type |
| barcode | string or null GS1-128 barcode (if applicable) |
| generatedAt | string Generation timestamp (ISO 8601) |
{- "number": "RTE000000001",
- "type": "routing.route_code",
- "barcode": "string",
- "generatedAt": "2026-02-15T10:30:00+00:00"
}{- "@context": "string",
- "@id": "string",
- "@type": "string",
- "number": "RTE000000001",
- "type": "routing.route_code",
- "barcode": "string",
- "generatedAt": "2026-02-15T10:30:00+00:00"
}Preview the next route code
| date | string <date> |
{- "@context": "string",
- "@id": "string",
- "@type": "string",
- "number": "RTE000000001",
- "type": "routing.route_code",
- "barcode": "string",
- "generatedAt": "2026-02-15T10:30:00+00:00"
}Generate a tracking number
The new TrackingNumber resource
| number | string The generated tracking number |
| type | string Resource type |
| barcode | string or null GS1-128 barcode (if applicable) |
| generatedAt | string Generation timestamp (ISO 8601) |
{- "number": "TRK000000001",
- "type": "routing.tracking_number",
- "barcode": "string",
- "generatedAt": "2026-02-15T10:30:00+00:00"
}{- "@context": "string",
- "@id": "string",
- "@type": "string",
- "number": "TRK000000001",
- "type": "routing.tracking_number",
- "barcode": "string",
- "generatedAt": "2026-02-15T10:30:00+00:00"
}Preview the next tracking number
| date | string <date> |
{- "@context": "string",
- "@id": "string",
- "@type": "string",
- "number": "TRK000000001",
- "type": "routing.tracking_number",
- "barcode": "string",
- "generatedAt": "2026-02-15T10:30:00+00:00"
}A load plan — where each handling unit (Shipping package) sits on a carrier (FleetUnit) for a trip, with live consumed-vs-capacity totals.
Served from the routing_load_plan_views / routing_load_placement_views read models. One plan exists per (carrier, route).
Paginated list of load plans, optionally filtered by route, carrier, or status.
| routeRef | string Filter by route reference |
| carrierRef | string Filter by carrier ResourceUri (glacia:///fleet/units/{id}) |
| status | string Enum: "draft" "planned" "sealed" "loading" "loaded" "in_transit" "unloading" "closed" Filter by plan status |
| page | integer >= 1 Default: 1 Page number |
| itemsPerPage | integer [ 1 .. 100 ] Default: 20 Items per page |
{- "totalItems": 0,
- "search": {
- "@type": "string",
- "template": "string",
- "variableRepresentation": "string",
- "mapping": [
- {
- "@type": "string",
- "variable": "string",
- "property": "string",
- "required": true
}
]
}, - "view": {
- "@id": "string",
- "@type": "string",
- "first": "string",
- "last": "string",
- "previous": "string",
- "next": "string"
}, - "member": [
- {
- "@context": "string",
- "@id": "string",
- "@type": "string",
- "id": "string",
- "carrierRef": "string",
- "routeRef": "string",
- "status": "draft",
- "maxWeightKg": 0,
- "maxVolumeM3": 0,
- "maxPallets": 0,
- "consumedWeightKg": 0,
- "consumedVolumeM3": 0,
- "consumedPallets": 0,
- "placementCount": 0,
- "openedAt": "string",
- "sealedAt": "string",
- "closedAt": "string",
- "updatedAt": "string",
- "placements": [
- {
- "placementId": "string",
- "unitRef": "glacia:///shipping/parcels/01J0...",
- "zone": "string",
- "bay": "string",
- "tier": "string",
- "positionLabel": "string",
- "loadSequence": 1,
- "status": "planned",
- "weightKg": 0,
- "volumeM3": 0
}
]
}
]
}Open a load plan for a carrier (FleetUnit) on a route. The carrier must have load capacity.
The new LoadPlan resource
| carrierId required | string <ulid> |
| routeId required | string <= 255 characters |
{- "carrierId": "string",
- "routeId": "string"
}{- "@context": "string",
- "@id": "string",
- "@type": "string",
- "id": "string",
- "carrierRef": "string",
- "routeRef": "string",
- "status": "draft",
- "maxWeightKg": 0,
- "maxVolumeM3": 0,
- "maxPallets": 0,
- "consumedWeightKg": 0,
- "consumedVolumeM3": 0,
- "consumedPallets": 0,
- "placementCount": 0,
- "openedAt": "string",
- "sealedAt": "string",
- "closedAt": "string",
- "updatedAt": "string",
- "placements": [
- {
- "placementId": "string",
- "unitRef": "glacia:///shipping/parcels/01J0...",
- "zone": "string",
- "bay": "string",
- "tier": "string",
- "positionLabel": "string",
- "loadSequence": 1,
- "status": "planned",
- "weightKg": 0,
- "volumeM3": 0
}
]
}Retrieve a single load plan with its placements and consumed totals.
| id required | string LoadPlan identifier |
{- "@context": "string",
- "@id": "string",
- "@type": "string",
- "id": "string",
- "carrierRef": "string",
- "routeRef": "string",
- "status": "draft",
- "maxWeightKg": 0,
- "maxVolumeM3": 0,
- "maxPallets": 0,
- "consumedWeightKg": 0,
- "consumedVolumeM3": 0,
- "consumedPallets": 0,
- "placementCount": 0,
- "openedAt": "string",
- "sealedAt": "string",
- "closedAt": "string",
- "updatedAt": "string",
- "placements": [
- {
- "placementId": "string",
- "unitRef": "glacia:///shipping/parcels/01J0...",
- "zone": "string",
- "bay": "string",
- "tier": "string",
- "positionLabel": "string",
- "loadSequence": 1,
- "status": "planned",
- "weightKg": 0,
- "volumeM3": 0
}
]
}Close the plan — trip done (carrier empty) or plan abandoned.
| id required | string LoadPlan identifier |
{- "@context": "string",
- "@id": "string",
- "@type": "string",
- "id": "string",
- "carrierRef": "string",
- "routeRef": "string",
- "status": "draft",
- "maxWeightKg": 0,
- "maxVolumeM3": 0,
- "maxPallets": 0,
- "consumedWeightKg": 0,
- "consumedVolumeM3": 0,
- "consumedPallets": 0,
- "placementCount": 0,
- "openedAt": "string",
- "sealedAt": "string",
- "closedAt": "string",
- "updatedAt": "string",
- "placements": [
- {
- "placementId": "string",
- "unitRef": "glacia:///shipping/parcels/01J0...",
- "zone": "string",
- "bay": "string",
- "tier": "string",
- "positionLabel": "string",
- "loadSequence": 1,
- "status": "planned",
- "weightKg": 0,
- "volumeM3": 0
}
]
}Place a handling unit (package) on the plan. Rejected if it would exceed carrier capacity or duplicates a unit already on the plan.
| id required | string LoadPlan identifier |
The new LoadPlan resource
| packageId required | string <ulid> |
| loadSequence | integer >= 0 Default: 0 |
LoadPositionPayload (object) or null |
{- "packageId": "string",
- "loadSequence": 0,
- "position": {
- "zone": "string",
- "bay": "string",
- "tier": "string",
- "label": "string"
}
}{- "@context": "string",
- "@id": "string",
- "@type": "string",
- "id": "string",
- "carrierRef": "string",
- "routeRef": "string",
- "status": "draft",
- "maxWeightKg": 0,
- "maxVolumeM3": 0,
- "maxPallets": 0,
- "consumedWeightKg": 0,
- "consumedVolumeM3": 0,
- "consumedPallets": 0,
- "placementCount": 0,
- "openedAt": "string",
- "sealedAt": "string",
- "closedAt": "string",
- "updatedAt": "string",
- "placements": [
- {
- "placementId": "string",
- "unitRef": "glacia:///shipping/parcels/01J0...",
- "zone": "string",
- "bay": "string",
- "tier": "string",
- "positionLabel": "string",
- "loadSequence": 1,
- "status": "planned",
- "weightKg": 0,
- "volumeM3": 0
}
]
}Move a placed unit to a new slot / load sequence (before sealing).
| id required | string LoadPlan identifier |
| packageId required | string LoadPlan identifier |
The updated LoadPlan resource
| loadSequence | integer >= 0 Default: 0 |
LoadPositionPayload (object) or null |
{- "loadSequence": 0,
- "position": {
- "zone": "string",
- "bay": "string",
- "tier": "string",
- "label": "string"
}
}{- "@context": "string",
- "@id": "string",
- "@type": "string",
- "id": "string",
- "carrierRef": "string",
- "routeRef": "string",
- "status": "draft",
- "maxWeightKg": 0,
- "maxVolumeM3": 0,
- "maxPallets": 0,
- "consumedWeightKg": 0,
- "consumedVolumeM3": 0,
- "consumedPallets": 0,
- "placementCount": 0,
- "openedAt": "string",
- "sealedAt": "string",
- "closedAt": "string",
- "updatedAt": "string",
- "placements": [
- {
- "placementId": "string",
- "unitRef": "glacia:///shipping/parcels/01J0...",
- "zone": "string",
- "bay": "string",
- "tier": "string",
- "positionLabel": "string",
- "loadSequence": 1,
- "status": "planned",
- "weightKg": 0,
- "volumeM3": 0
}
]
}Mark a unit physically loaded onto the carrier at the dock.
| id required | string LoadPlan identifier |
| packageId required | string LoadPlan identifier |
{- "@context": "string",
- "@id": "string",
- "@type": "string",
- "id": "string",
- "carrierRef": "string",
- "routeRef": "string",
- "status": "draft",
- "maxWeightKg": 0,
- "maxVolumeM3": 0,
- "maxPallets": 0,
- "consumedWeightKg": 0,
- "consumedVolumeM3": 0,
- "consumedPallets": 0,
- "placementCount": 0,
- "openedAt": "string",
- "sealedAt": "string",
- "closedAt": "string",
- "updatedAt": "string",
- "placements": [
- {
- "placementId": "string",
- "unitRef": "glacia:///shipping/parcels/01J0...",
- "zone": "string",
- "bay": "string",
- "tier": "string",
- "positionLabel": "string",
- "loadSequence": 1,
- "status": "planned",
- "weightKg": 0,
- "volumeM3": 0
}
]
}Mark a unit unloaded from the carrier at a stop / delivery.
| id required | string LoadPlan identifier |
| packageId required | string LoadPlan identifier |
{- "@context": "string",
- "@id": "string",
- "@type": "string",
- "id": "string",
- "carrierRef": "string",
- "routeRef": "string",
- "status": "draft",
- "maxWeightKg": 0,
- "maxVolumeM3": 0,
- "maxPallets": 0,
- "consumedWeightKg": 0,
- "consumedVolumeM3": 0,
- "consumedPallets": 0,
- "placementCount": 0,
- "openedAt": "string",
- "sealedAt": "string",
- "closedAt": "string",
- "updatedAt": "string",
- "placements": [
- {
- "placementId": "string",
- "unitRef": "glacia:///shipping/parcels/01J0...",
- "zone": "string",
- "bay": "string",
- "tier": "string",
- "positionLabel": "string",
- "loadSequence": 1,
- "status": "planned",
- "weightKg": 0,
- "volumeM3": 0
}
]
}Freeze the manifest — placements can no longer be edited; the carrier is ready to load.
| id required | string LoadPlan identifier |
{- "@context": "string",
- "@id": "string",
- "@type": "string",
- "id": "string",
- "carrierRef": "string",
- "routeRef": "string",
- "status": "draft",
- "maxWeightKg": 0,
- "maxVolumeM3": 0,
- "maxPallets": 0,
- "consumedWeightKg": 0,
- "consumedVolumeM3": 0,
- "consumedPallets": 0,
- "placementCount": 0,
- "openedAt": "string",
- "sealedAt": "string",
- "closedAt": "string",
- "updatedAt": "string",
- "placements": [
- {
- "placementId": "string",
- "unitRef": "glacia:///shipping/parcels/01J0...",
- "zone": "string",
- "bay": "string",
- "tier": "string",
- "positionLabel": "string",
- "loadSequence": 1,
- "status": "planned",
- "weightKg": 0,
- "volumeM3": 0
}
]
}Represents a client-facing service rate card containing pricing rules for route and shipment charges.
Retrieve a paginated list of rate cards with optional filters.
| crewId | string <uuid> Filter by partner UUID |
| status | string Enum: "draft" "active" "expired" "superseded" Filter by rate card status |
| page | integer >= 1 Default: 1 Page number for pagination |
| itemsPerPage | integer [ 1 .. 100 ] Default: 25 Number of items per page |
{- "totalItems": 0,
- "search": {
- "@type": "string",
- "template": "string",
- "variableRepresentation": "string",
- "mapping": [
- {
- "@type": "string",
- "variable": "string",
- "property": "string",
- "required": true
}
]
}, - "view": {
- "@id": "string",
- "@type": "string",
- "first": "string",
- "last": "string",
- "previous": "string",
- "next": "string"
}, - "member": [
- {
- "@context": "string",
- "@id": "string",
- "@type": "string",
- "id": "string",
- "crewId": "string",
- "teamName": "string",
- "currency": "USD",
- "effectiveFrom": "string",
- "effectiveTo": "string",
- "status": "draft",
- "rules": [
- {
- "property1": {
- "property1": 0,
- "property2": 0
}, - "property2": {
- "property1": 0,
- "property2": 0
}
}
], - "createdAt": "string",
- "updatedAt": "string"
}
]
}Create a new rate card in draft status.
Rate card creation data
| crewId | string or null <uuid> Partner UUID (null for tenant default) |
| currency required | string = 3 characters ISO 4217 currency code |
| effectiveFrom required | string <date-time> Start of effectiveness period |
| effectiveTo required | string <date-time> End of effectiveness period |
{- "crewId": "3bfb64a6-7eeb-4376-b155-bfb9c0405b76",
- "currency": "USD",
- "effectiveFrom": "2019-08-24T14:15:22Z",
- "effectiveTo": "2019-08-24T14:15:22Z"
}{- "@context": "string",
- "@id": "string",
- "@type": "string",
- "id": "string",
- "crewId": "string",
- "teamName": "string",
- "currency": "USD",
- "effectiveFrom": "string",
- "effectiveTo": "string",
- "status": "draft",
- "rules": [
- {
- "property1": {
- "property1": 0,
- "property2": 0
}, - "property2": {
- "property1": 0,
- "property2": 0
}
}
], - "createdAt": "string",
- "updatedAt": "string"
}Retrieve a single rate card by its UUID, including all rules.
| id required | string <uuid> Rate card UUID |
{- "@context": "string",
- "@id": "string",
- "@type": "string",
- "id": "string",
- "crewId": "string",
- "teamName": "string",
- "currency": "USD",
- "effectiveFrom": "string",
- "effectiveTo": "string",
- "status": "draft",
- "rules": [
- {
- "property1": {
- "property1": 0,
- "property2": 0
}, - "property2": {
- "property1": 0,
- "property2": 0
}
}
], - "createdAt": "string",
- "updatedAt": "string"
}Activate a draft rate card. The rate card must have at least one rule.
| id required | string <uuid> Rate card UUID |
{- "@context": "string",
- "@id": "string",
- "@type": "string",
- "id": "string",
- "crewId": "string",
- "teamName": "string",
- "currency": "USD",
- "effectiveFrom": "string",
- "effectiveTo": "string",
- "status": "draft",
- "rules": [
- {
- "property1": {
- "property1": 0,
- "property2": 0
}, - "property2": {
- "property1": 0,
- "property2": 0
}
}
], - "createdAt": "string",
- "updatedAt": "string"
}Add a pricing rule to a draft rate card.
| id required | string <uuid> Rate card UUID |
The new RateCard resource
| chargeType required | string |
| scope required | string |
| method required | string |
| amountInCents required | integer |
| percentage | number or null |
| percentageOf | string or null |
| priority | integer >= 0 Default: 0 |
object or null |
{- "chargeType": "string",
- "scope": "string",
- "method": "string",
- "amountInCents": 0,
- "percentage": 0,
- "percentageOf": "string",
- "priority": 0,
- "condition": {
- "property1": 0,
- "property2": 0
}
}{- "@context": "string",
- "@id": "string",
- "@type": "string",
- "id": "string",
- "crewId": "string",
- "teamName": "string",
- "currency": "USD",
- "effectiveFrom": "string",
- "effectiveTo": "string",
- "status": "draft",
- "rules": [
- {
- "property1": {
- "property1": 0,
- "property2": 0
}, - "property2": {
- "property1": 0,
- "property2": 0
}
}
], - "createdAt": "string",
- "updatedAt": "string"
}Remove a pricing rule from a draft rate card by its index.
| id required | string <uuid> Rate card UUID |
| index required | integer >= 0 Rule index (0-based) |
{- "@context": "string",
- "@id": "string",
- "@type": "string",
- "id": "string",
- "crewId": "string",
- "teamName": "string",
- "currency": "USD",
- "effectiveFrom": "string",
- "effectiveTo": "string",
- "status": "draft",
- "rules": [
- {
- "property1": {
- "property1": 0,
- "property2": 0
}, - "property2": {
- "property1": 0,
- "property2": 0
}
}
], - "createdAt": "string",
- "updatedAt": "string"
}Retrieve a paginated list of service rate cards with optional filters.
| clientId | string <uuid> Filter by client UUID |
| status | string Enum: "draft" "active" "archived" Filter by service rate card status |
| page | integer >= 1 Default: 1 Page number for pagination |
| itemsPerPage | integer [ 1 .. 100 ] Default: 25 Number of items per page |
{- "totalItems": 0,
- "search": {
- "@type": "string",
- "template": "string",
- "variableRepresentation": "string",
- "mapping": [
- {
- "@type": "string",
- "variable": "string",
- "property": "string",
- "required": true
}
]
}, - "view": {
- "@id": "string",
- "@type": "string",
- "first": "string",
- "last": "string",
- "previous": "string",
- "next": "string"
}, - "member": [
- {
- "@context": "string",
- "@id": "string",
- "@type": "string",
- "id": "string",
- "clientId": "string",
- "clientName": "string",
- "currency": "USD",
- "effectiveFrom": "string",
- "effectiveTo": "string",
- "status": "draft",
- "rules": [
- {
- "property1": {
- "property1": 0,
- "property2": 0
}, - "property2": {
- "property1": 0,
- "property2": 0
}
}
], - "createdAt": "string",
- "updatedAt": "string"
}
]
}Create a new service rate card in draft status.
Service rate card creation data
| clientId | string or null <uuid> Client UUID (null for tenant default) |
| currency required | string = 3 characters ISO 4217 currency code |
| effectiveFrom required | string <date-time> Start of effectiveness period |
| effectiveTo required | string <date-time> End of effectiveness period |
{- "clientId": "5e505642-9024-474d-9434-e5a44f505cc5",
- "currency": "USD",
- "effectiveFrom": "2019-08-24T14:15:22Z",
- "effectiveTo": "2019-08-24T14:15:22Z"
}{- "@context": "string",
- "@id": "string",
- "@type": "string",
- "id": "string",
- "clientId": "string",
- "clientName": "string",
- "currency": "USD",
- "effectiveFrom": "string",
- "effectiveTo": "string",
- "status": "draft",
- "rules": [
- {
- "property1": {
- "property1": 0,
- "property2": 0
}, - "property2": {
- "property1": 0,
- "property2": 0
}
}
], - "createdAt": "string",
- "updatedAt": "string"
}Retrieve a single service rate card by its UUID, including all rules.
| id required | string <uuid> Service rate card UUID |
{- "@context": "string",
- "@id": "string",
- "@type": "string",
- "id": "string",
- "clientId": "string",
- "clientName": "string",
- "currency": "USD",
- "effectiveFrom": "string",
- "effectiveTo": "string",
- "status": "draft",
- "rules": [
- {
- "property1": {
- "property1": 0,
- "property2": 0
}, - "property2": {
- "property1": 0,
- "property2": 0
}
}
], - "createdAt": "string",
- "updatedAt": "string"
}Activate a draft service rate card. The service rate card must have at least one rule.
| id required | string <uuid> Service rate card UUID |
{- "@context": "string",
- "@id": "string",
- "@type": "string",
- "id": "string",
- "clientId": "string",
- "clientName": "string",
- "currency": "USD",
- "effectiveFrom": "string",
- "effectiveTo": "string",
- "status": "draft",
- "rules": [
- {
- "property1": {
- "property1": 0,
- "property2": 0
}, - "property2": {
- "property1": 0,
- "property2": 0
}
}
], - "createdAt": "string",
- "updatedAt": "string"
}Add a pricing rule to a draft service rate card.
| id required | string <uuid> Service rate card UUID |
The new ServiceRateCard resource
| chargeType required | string |
| scope required | string |
| method required | string |
| amountInCents required | integer |
| percentage | number or null |
| percentageOf | string or null |
| priority | integer >= 0 Default: 0 |
object or null |
{- "chargeType": "string",
- "scope": "string",
- "method": "string",
- "amountInCents": 0,
- "percentage": 0,
- "percentageOf": "string",
- "priority": 0,
- "condition": {
- "property1": 0,
- "property2": 0
}
}{- "@context": "string",
- "@id": "string",
- "@type": "string",
- "id": "string",
- "clientId": "string",
- "clientName": "string",
- "currency": "USD",
- "effectiveFrom": "string",
- "effectiveTo": "string",
- "status": "draft",
- "rules": [
- {
- "property1": {
- "property1": 0,
- "property2": 0
}, - "property2": {
- "property1": 0,
- "property2": 0
}
}
], - "createdAt": "string",
- "updatedAt": "string"
}Remove a pricing rule from a draft service rate card by its index.
| id required | string <uuid> Service rate card UUID |
| index required | integer >= 0 Rule index (0-based) |
{- "@context": "string",
- "@id": "string",
- "@type": "string",
- "id": "string",
- "clientId": "string",
- "clientName": "string",
- "currency": "USD",
- "effectiveFrom": "string",
- "effectiveTo": "string",
- "status": "draft",
- "rules": [
- {
- "property1": {
- "property1": 0,
- "property2": 0
}, - "property2": {
- "property1": 0,
- "property2": 0
}
}
], - "createdAt": "string",
- "updatedAt": "string"
}Resource for real-time driver location tracking.
Drivers send their location updates to this endpoint during route execution. Updates are published via Mercure for real-time tracking on the dashboard.
Submit current driver location for real-time tracking.
Rate limiting: This endpoint is rate-limited to 1 request every 10 seconds per driver.
Real-time updates: Location updates are published via Mercure SSE to the /tracking/{driverId} topic.
Expected usage:
Driver location data
| lat required | number <float> Latitude coordinate |
| lng required | number <float> Longitude coordinate |
| routeId required | string <ulid> Route ID being executed |
| timestamp | string <date-time> When location was recorded (ISO 8601) |
| heading | number <float> [ 0 .. 360 ] Compass heading in degrees |
| speed | number <float> >= 0 Speed in km/h |
| accuracy | number <float> >= 0 GPS accuracy in meters |
| batteryLevel | integer [ 0 .. 100 ] Device battery percentage |
{- "lat": 50.8503,
- "lng": 4.3517,
- "routeId": "01HXY9Z8A7B6C5D4E3F2G1H0J",
- "timestamp": "2024-01-15T10:30:00+01:00",
- "heading": 45.5,
- "speed": 50,
- "accuracy": 5,
- "batteryLevel": 85
}{- "@context": "string",
- "@id": "string",
- "@type": "string",
- "driverId": "string",
- "routeId": "string",
- "latitude": 0,
- "longitude": 0,
- "heading": 0,
- "speed": 0,
- "accuracy": 0,
- "batteryLevel": 0,
- "recordedAt": "string"
}Per-zone operational policy (config store). Keyed by the zone's opaque id.
GET returns the current config or a default empty shape when none is set;
PUT upserts the whole config and is gated by the routing zone-policy manage
scope.
Returns the configured policy, or a default empty shape when the zone has no policy yet.
| zoneId required | string ZonePolicy identifier |
{- "@context": "string",
- "@id": "string",
- "@type": "string",
- "zoneId": "string",
- "policyId": "string",
- "defaultTeamRef": "string",
- "defaultCarrierRef": "string",
- "servingDepotId": "string",
- "overlapPriority": 0,
- "autoAssign": false,
- "overflowZoneRef": "string",
- "deliveryDays": [
- 0
], - "orderCutoffs": {
- "property1": "string",
- "property2": "string"
}, - "deliveryWindows": [
- "string"
], - "maxStopsPerDay": 0,
- "maxVehicles": 0,
- "allowedServiceLevels": [
- "string"
], - "serviceLevelSlas": {
- "property1": "string",
- "property2": "string"
}, - "surcharge": {
- "amount": 0,
- "currency": "string"
}, - "rateCardRef": "string",
- "minOrderValue": {
- "amount": 0,
- "currency": "string"
}, - "allowedVehicleTypes": [
- "string"
], - "accessRestrictions": {
- "lowEmissionZone": false,
- "ultraLowEmissionZone": false,
- "maxWeightKg": 0,
- "maxHeightCm": 0,
- "maxLengthCm": 0,
- "timeOfDayRestricted": false
}, - "createdAt": "string",
- "updatedAt": "string"
}Upserts the whole policy (get-or-create by tenant + zone). Requires the routing:zone-policy:manage scope.
| zoneId required | string ZonePolicy identifier |
The updated ZonePolicy resource
DispatchAssignmentInput (object) or null | |
ScheduleCapacityInput (object) or null | |
ServiceSlaInput (object) or null | |
CommercialAccessInput (object) or null |
{- "dispatch": {
- "defaultTeamRef": "string",
- "defaultCarrierRef": "string",
- "servingDepotId": "string",
- "overlapPriority": 0,
- "autoAssign": true,
- "overflowZoneRef": "string"
}, - "schedule": {
- "deliveryDays": [
- 0
], - "orderCutoffs": [
- "string"
], - "deliveryWindows": [
- "string"
], - "maxStopsPerDay": 0,
- "maxVehicles": 0
}, - "service": {
- "allowedServiceLevels": [
- "string"
], - "serviceLevelSlas": {
- "property1": "string",
- "property2": "string"
}
}, - "commercial": {
- "surcharge": {
- "amount": 0,
- "currency": "string"
}, - "rateCardRef": "string",
- "minOrderValue": {
- "amount": 0,
- "currency": "string"
}, - "allowedVehicleTypes": [
- "string"
], - "accessRestrictions": {
- "lowEmissionZone": true,
- "ultraLowEmissionZone": true,
- "maxWeightKg": 0,
- "maxHeightCm": 0,
- "maxLengthCm": 0,
- "timeOfDayRestricted": true
}
}
}{- "@context": "string",
- "@id": "string",
- "@type": "string",
- "zoneId": "string",
- "policyId": "string",
- "defaultTeamRef": "string",
- "defaultCarrierRef": "string",
- "servingDepotId": "string",
- "overlapPriority": 0,
- "autoAssign": false,
- "overflowZoneRef": "string",
- "deliveryDays": [
- 0
], - "orderCutoffs": {
- "property1": "string",
- "property2": "string"
}, - "deliveryWindows": [
- "string"
], - "maxStopsPerDay": 0,
- "maxVehicles": 0,
- "allowedServiceLevels": [
- "string"
], - "serviceLevelSlas": {
- "property1": "string",
- "property2": "string"
}, - "surcharge": {
- "amount": 0,
- "currency": "string"
}, - "rateCardRef": "string",
- "minOrderValue": {
- "amount": 0,
- "currency": "string"
}, - "allowedVehicleTypes": [
- "string"
], - "accessRestrictions": {
- "lowEmissionZone": false,
- "ultraLowEmissionZone": false,
- "maxWeightKg": 0,
- "maxHeightCm": 0,
- "maxLengthCm": 0,
- "timeOfDayRestricted": false
}, - "createdAt": "string",
- "updatedAt": "string"
}