openapi: 3.1.0 info: title: Routific Route Optimization API description: | Routific's Route Optimization API solves the vehicle routing problem (VRP) and the pickup-and-delivery problem (PDP) for last-mile delivery fleets. It supports time-windows, capacity constraints, driver shifts, multi-depot fleets, balanced routes, traffic simulation, and polyline output. The API offers four solving surfaces: - `POST /v1/vrp` — synchronous vehicle routing for small problems (< 60 visits). - `POST /v1/vrp-long` — asynchronous vehicle routing for problems up to 2,500 visits. - `POST /v1/pdp-long` — asynchronous pickup-and-delivery routing. - `POST /v1/fix` and `POST /v1/fix-pdp` — insert new visits into an existing optimized solution without re-solving the whole problem. Asynchronous endpoints return a `job_id` immediately; clients poll `GET /jobs/{job_id}` until the job reaches `finished` or `error`. version: '1.11' contact: name: Routific Support email: support@routific.com url: https://docs.routific.com termsOfService: https://routific.com/terms license: name: Routific Terms of Service url: https://routific.com/terms x-logo: url: https://routific.com/favicon.ico servers: - url: https://api.routific.com description: Production Server security: - BearerAuth: [] tags: - name: VRP description: Vehicle Routing Problem — assign and order visits across a fleet. - name: PDP description: Pickup and Delivery Problem — paired pickup/dropoff routing. - name: Jobs description: Asynchronous long-running optimization jobs. - name: Fix description: Insert new visits into an existing optimized solution. paths: /v1/vrp: post: summary: Solve Vehicle Routing Problem description: | Synchronously solve a vehicle routing problem. Send the addresses of your visits and your fleet; the API returns the optimal allocation and the order in which each vehicle should visit them. Use for small problems (< 60 visits). Larger problems should use `/v1/vrp-long`. operationId: solveVrp tags: - VRP requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/VrpRequest' examples: minimalExample: $ref: '#/components/examples/VrpRequestExample' responses: '200': description: Optimized route solution content: application/json: schema: $ref: '#/components/schemas/VrpSolution' '400': $ref: '#/components/responses/InputError' '401': $ref: '#/components/responses/Unauthorized' '408': $ref: '#/components/responses/RequestTimeout' '412': $ref: '#/components/responses/NoSolution' '429': $ref: '#/components/responses/RateLimited' '500': $ref: '#/components/responses/InternalError' /v1/vrp-long: post: summary: Solve Vehicle Routing Problem (Async) description: | Submit a vehicle routing problem for asynchronous processing. Returns a `job_id` immediately; poll `GET /jobs/{job_id}` for status and result. Hard limit of 2,500 visits per call. operationId: solveVrpLong tags: - VRP - Jobs requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/VrpRequest' responses: '202': description: Job accepted for asynchronous processing content: application/json: schema: $ref: '#/components/schemas/JobAccepted' '400': $ref: '#/components/responses/InputError' '401': $ref: '#/components/responses/Unauthorized' '429': $ref: '#/components/responses/RateLimited' /v1/pdp-long: post: summary: Solve Pickup And Delivery Problem (Async) description: | Submit a pickup-and-delivery routing problem for asynchronous processing. Each visit pairs a pickup and a dropoff location with their own time-windows and durations. Returns a `job_id` immediately. operationId: solvePdpLong tags: - PDP - Jobs requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/PdpRequest' responses: '202': description: Job accepted for asynchronous processing content: application/json: schema: $ref: '#/components/schemas/JobAccepted' '400': $ref: '#/components/responses/InputError' '401': $ref: '#/components/responses/Unauthorized' '429': $ref: '#/components/responses/RateLimited' /jobs/{job_id}: get: summary: Get Optimization Job Status description: | Retrieve the status and result of an asynchronous routing job submitted via `/v1/vrp-long` or `/v1/pdp-long`. Statuses are `pending`, `processing`, `finished`, or `error`. When `finished`, the response payload is in `output`. operationId: getJob tags: - Jobs parameters: - name: job_id in: path required: true schema: type: string description: Identifier returned by `/v1/vrp-long` or `/v1/pdp-long`. responses: '200': description: Current job state content: application/json: schema: $ref: '#/components/schemas/Job' '401': $ref: '#/components/responses/Unauthorized' '404': description: Job not found content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' /v1/fix: post: summary: Insert New Visits Into VRP Solution description: | Insert one or more new visits into an existing optimized VRP solution without re-solving the entire problem. Pass the current `solution`, the remaining `visits`, and the new visit IDs in `unserved`. operationId: fixVrp tags: - Fix - VRP requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/FixRequest' responses: '200': description: Updated solution content: application/json: schema: $ref: '#/components/schemas/VrpSolution' '400': $ref: '#/components/responses/InputError' '401': $ref: '#/components/responses/Unauthorized' /v1/fix-pdp: post: summary: Insert New Visits Into PDP Solution description: | Insert one or more new pickup-and-delivery visits into an existing optimized PDP solution without re-solving the entire problem. operationId: fixPdp tags: - Fix - PDP requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/FixPdpRequest' responses: '200': description: Updated solution content: application/json: schema: $ref: '#/components/schemas/PdpSolution' '400': $ref: '#/components/responses/InputError' '401': $ref: '#/components/responses/Unauthorized' components: securitySchemes: BearerAuth: type: http scheme: bearer bearerFormat: JWT description: | Routific issues per-account JWT tokens. Send as `Authorization: bearer `. schemas: Location: type: object description: Geocoded address for a visit, pickup, dropoff, or depot. required: [lat, lng] properties: id: type: string description: Optional location identifier (e.g. `depot`). name: type: string description: Human-readable address. lat: type: number format: double description: Latitude in decimal degrees. lng: type: number format: double description: Longitude in decimal degrees. Visit: type: object description: A single visit with location, time-window, and service duration. required: [location] properties: location: $ref: '#/components/schemas/Location' start: type: string description: Earliest time the visit can begin (`hh:mm` or UNIX seconds). example: '9:00' end: type: string description: Latest time the visit can begin (`hh:mm` or UNIX seconds). example: '12:00' duration: type: integer description: Service duration in minutes. minimum: 1 load: oneOf: - type: number - type: object additionalProperties: type: number description: Load contributed by this visit (single value or per-dimension object). priority: type: integer description: Optional priority level. type: oneOf: - type: string - type: number - type: array items: oneOf: - type: string - type: number description: Compatibility type(s) the assigned vehicle must support. PickupDeliveryVisit: type: object description: Paired pickup and dropoff entry for the pickup-and-delivery problem. required: [pickup, dropoff] properties: pickup: $ref: '#/components/schemas/Visit' dropoff: $ref: '#/components/schemas/Visit' Vehicle: type: object description: A single vehicle/driver in the fleet. required: [start_location] properties: start_location: $ref: '#/components/schemas/Location' end_location: $ref: '#/components/schemas/Location' shift_start: type: string description: Earliest time the driver can begin (`hh:mm` or UNIX seconds). example: '8:00' shift_end: type: string description: Latest time the driver must finish (`hh:mm` or UNIX seconds). example: '17:00' capacity: oneOf: - type: number - type: object additionalProperties: type: number description: Vehicle capacity (single value or per-dimension object). min_visits: type: integer description: Minimum number of visits the vehicle must handle. type: oneOf: - type: string - type: number - type: array items: oneOf: - type: string - type: number description: Compatibility type(s) the vehicle supports. Options: type: object description: Tunable parameters that adjust how the optimization engine runs. properties: traffic: type: string enum: [faster, fast, normal, slow, 'very slow'] default: faster description: Traffic simulation level. min_visits_per_vehicle: type: integer minimum: 1 description: Minimum number of visits per vehicle. balance: type: boolean description: Keep variance across driver shift times as small as possible. visit_balance_coefficient: type: number minimum: 0 maximum: 1 description: Trade off route balance vs efficiency (0.0 = efficient, 1.0 = balanced). Available on `/vrp-long` v1.10+. min_vehicles: type: boolean default: false description: Minimize the number of vehicles used. shortest_distance: type: boolean default: false description: Optimize for shortest distance rather than total driving time. squash_durations: type: integer minimum: 1 description: Squash subsequent visit durations at the same address to this many minutes. max_vehicle_overtime: type: integer minimum: 0 description: Maximum minutes a driver is allowed to work overtime. max_visit_lateness: type: integer minimum: 0 description: Maximum minutes a stop is allowed to be late. polylines: type: boolean default: false description: Return encoded polylines and per-stop distances. avoid_tolls: type: boolean default: false description: Avoid toll roads when calculating routes. geocoder: type: string enum: [google, here] default: google description: Geocoding provider for address strings. VrpRequest: type: object description: Vehicle routing problem request. required: [visits, fleet] properties: visits: type: object description: Map of visit ID to visit definition. additionalProperties: $ref: '#/components/schemas/Visit' fleet: type: object description: Map of vehicle ID to vehicle definition. additionalProperties: $ref: '#/components/schemas/Vehicle' options: $ref: '#/components/schemas/Options' PdpRequest: type: object description: Pickup-and-delivery problem request. required: [visits, fleet] properties: visits: type: object additionalProperties: $ref: '#/components/schemas/PickupDeliveryVisit' fleet: type: object additionalProperties: $ref: '#/components/schemas/Vehicle' options: $ref: '#/components/schemas/Options' StopAssignment: type: object description: A single stop in a vehicle's route. properties: location_id: type: string arrival_time: type: string finish_time: type: string type: type: string enum: [pickup, dropoff] too_late: type: boolean late_by: type: integer description: Minutes by which the stop is late (when overtime/lateness options used). distance: type: number description: Meters from the previous stop (when `polylines` is true). VrpSolution: type: object description: Optimized solution returned by the engine. properties: status: type: string enum: [success, error] total_travel_time: type: integer description: Total travel time across all vehicles in minutes. total_idle_time: type: integer total_working_time: type: integer total_visit_lateness: type: integer num_late_visits: type: integer total_overtime: type: integer vehicle_overtime: type: object additionalProperties: type: integer num_unserved: type: integer unserved: oneOf: - type: array items: type: string - type: object additionalProperties: type: string description: Visits that could not be scheduled (or a map of visit-id to reason). solution: type: object additionalProperties: type: array items: $ref: '#/components/schemas/StopAssignment' polylines: type: object additionalProperties: type: string description: Encoded polyline per vehicle (when `options.polylines` is true). PdpSolution: allOf: - $ref: '#/components/schemas/VrpSolution' FixRequest: type: object required: [visits, fleet, solution, unserved] properties: visits: type: object additionalProperties: $ref: '#/components/schemas/Visit' fleet: type: object additionalProperties: $ref: '#/components/schemas/Vehicle' options: $ref: '#/components/schemas/Options' solution: type: object description: Existing solution — map of vehicle ID to ordered list of visit IDs. additionalProperties: type: array items: type: string unserved: type: array description: New visit IDs to insert into the existing solution. items: type: string FixPdpRequest: type: object required: [visits, fleet, solution, unserved] properties: visits: type: object additionalProperties: $ref: '#/components/schemas/PickupDeliveryVisit' fleet: type: object additionalProperties: $ref: '#/components/schemas/Vehicle' options: $ref: '#/components/schemas/Options' solution: type: object additionalProperties: type: array items: $ref: '#/components/schemas/StopAssignment' unserved: type: array items: type: string JobAccepted: type: object required: [job_id] properties: job_id: type: string Job: type: object description: Asynchronous optimization job state. required: [status] properties: job_id: type: string status: type: string enum: [pending, processing, finished, error] created_at: type: string format: date-time finished_at: type: string format: date-time output: oneOf: - $ref: '#/components/schemas/VrpSolution' - type: string description: Solution payload when status is `finished`; error message when `error`. ErrorResponse: type: object properties: error: type: string description: Routific error code (e.g. `ERR_DRIVER_NOT_SAME_REGION`). message: type: string description: Human-readable error message. examples: VrpRequestExample: summary: Minimal VRP request value: visits: order_1: location: name: '6800 Cambie' lat: 49.227107 lng: -123.1163085 start: '9:00' end: '12:00' duration: 10 fleet: vehicle_1: start_location: id: depot name: '800 Kingsway' lat: 49.2553636 lng: -123.0873365 shift_start: '8:00' shift_end: '12:00' responses: InputError: description: Input error — see the error message and code for details. content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' Unauthorized: description: Missing or invalid bearer token. content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' RequestTimeout: description: Request was too large for the synchronous endpoint — use `/v1/vrp-long` or `/v1/pdp-long`. content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' NoSolution: description: No solution could be found — usually due to incorrect time-windows. content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' RateLimited: description: Daily request limit exceeded or problem size larger than account limits. content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' InternalError: description: Internal server error. content: application/json: schema: $ref: '#/components/schemas/ErrorResponse'