Skip to main content
V3 is in beta. General availability (GA) is planned for January 2027.
The V3 Routing API is a JSON API over HTTPS. A solve, evaluate or suggest call is a single POST: you send the whole problem and get the whole answer back in the response, and the API keeps no state between calls. For a long search, an async run takes the same body, answers at once and keeps the run for you to poll.

Base URL

Authentication

Send your API key in the Authorization header, as the bare key with no Bearer prefix:
Create a key under Settings → API Keys at platform.solvice.io. A missing or unrecognised key is a 401. See Authentication.

Endpoints

The full request and response schema of each endpoint is under Endpoints in the sidebar. The first three share one problem object, which a run takes too, described in The V3 API model.

Requests

  • Content type. Send Content-Type: application/json; a parameter such as ; charset=utf-8 is fine, and so is any application/*+json type. Anything else is a 415.
  • Compression. A body may be gzip-compressed with Content-Encoding: gzip. The 10 MiB size limit applies to the decompressed body.
  • Strict schema. Field names are snake_case. An unknown field, a missing required field or a wrong type is a 400 that names the field, so a misspelt or outdated field name is never dropped. A shipment’s own id in a relation is a 400 not_supported: name its legs by stop id ({shipment}:pickup, {shipment}:delivery) instead. See Relations and shipments.
  • Coordinates. [longitude, latitude], in that order.
  • Times. ISO 8601 date-times. Always include a UTC offset, as in 2026-04-01T08:00:00+02:00 or 2026-04-01T06:00:00Z. A timestamp without an offset is a 400 that names the field, since reading it as UTC would move every window and shift by your offset. The V2 endpoints still accept one and read it as UTC. Timestamps in a response are written in the UTC offset of the shift they belong to (the offset of that shift’s from, Z for UTC): the same instant, in local time.
  • Units. Durations are seconds (_s), distances are metres (_m), costs are in your own currency.

Dry run with /v3/routing/validate/solve

Send a request to POST /v3/routing/validate/solve, /v3/routing/validate/evaluate or /v3/routing/validate/suggest to check it without running it. The body is the body of that endpoint:
A valid request returns:
200 OK
An invalid one returns the same 400 the real call would, because the body is parsed and checked as that endpoint parses and checks its own, and a request for a feature your account does not have gets the same 403. No travel times are fetched, nothing is searched, no solver slot is taken (so there is no 503), and the call is not billed. It validates problem and options. Two checks need the travel times and are made only by the real call: coordinates that span more than one region (a 400), and the plan, whether it names the problem’s vehicles, shifts, tasks and depots and whether it can be imported, warm-start plan on solve included. Suggest’s own check that plan leaves a task to place does run here. warnings may contain warnings; none are produced today. The validate operations take no query parameters. Any query parameter (for example the removed validate_only) is a 400 with an unknown_field item; the item has no pointer and its message names the parameter.

Responses and errors

A 200 carries the result, the same shape on solve and evaluate. summary.tasks tells you whether every task was planned (unassigned_required counts the required tasks left out; a job and a shipment are one task each), summary.score.violation_count counts broken constraints, and unassigned[] explains every task that was not planned. Any other status from the routing service carries one JSON error body with status, code, message, request_id and, on a 400, an errors[] list with a JSON pointer to each problem. The exception is a 401 or 429: both are answered before the request reaches the routing service, and they can have a different body or none at all, so branch on the HTTP status for those two. See Authentication.

Response headers

To trace a call with your own id, send an X-Request-Id request header of 1 to 128 visible ASCII characters with no spaces. That value is then used as the request id: it is echoed in the x-request-id response header and as request_id in an error body. Without the header, or with a value outside that format, an id is generated for you.

Errors

The error body, every status and code, and unassigned-job reasons.

Limits

Request size, solve time and problem size limits.

Quickstart

Send your first solve request.

The V3 API model

How jobs, shipments, vehicles and the objective fit together.