V3 is in beta. General availability (GA) is planned for January 2027.
Overview
POST /v3/routing/solve holds the connection open until the plan is ready and caps the search at 300 seconds. An async run takes the same request body, answers at once, and solves in the background, with a search of up to 3,600 seconds. You then poll the run and fetch the plan when it is done.
Only solve runs in the background. Evaluate and suggest are quick, and stay synchronous.
All four are served from
https://api.solvice.io and take your API key in the Authorization header, as on the other endpoints. A run belongs to your account: another account’s run id is a 404.
The life of a run
succeeded, failed and cancelled are final.
Submit a run
Send the body you would send to/v3/routing/solve: a problem, and optionally a plan and options. These differ from solve:
options.time_limit_smay be up to3600(solve:300).callbackis not supported yet. A body that has it is a400with the item codenot_supportedat/callback.- The request is validated before the run is accepted, with the same checks and the same error body as solve, so a bad body is a
400here and never afailedrun later.
202 with the run. Keep its id:
202 Accepted
X-Request-Id header of 1 to 128 visible ASCII characters to trace the call. It is echoed in the x-request-id response header, and a generated req_… id is used when it is absent or malformed.
The run
Every endpoint but/result answers with the run:
string (UUID)
The run id, for the paths above.
string
queued, running, succeeded, failed or cancelled. See The life of a run.object
self and result: the paths to poll and to fetch the plan from, relative to the API host.object
On
failed only: status, code, message and, for an invalid request, errors[], in the shape of the error body. The code is invalid_request, matrix_provider_error, internal or worker_lost.string (RFC 3339, UTC)
When a worker claimed the run. Absent while it is
queued.string (RFC 3339, UTC)
When the run became final. Absent before then.
string (RFC 3339, UTC)
When the run and its plan are deleted:
finished_at plus 365 days. Absent before the run is final.Poll a run
status is final. While the worker runs:
200 OK, running
200 OK, succeeded
running for ever. Each poll checks the worker, and the run turns failed with error.code worker_lost when the worker is gone or the run is older than 6,000 seconds. A run that is still queued after 30 minutes turns failed with internal.
Fetch the plan
succeeded run the answer is 200 with exactly the response POST /v3/routing/solve returns: summary, routes, plan and unassigned. See The V3 API model for every field, and send plan back in a later request to re-optimise. The plan is kept until expires_at.
For any other status /result answers 409:
Cancel a run
200 with the run: cancelled, or unchanged when it had already finished, since finishing wins a race. A run is cancelled whether it is queued or running.
200 OK, cancelled
/result is a 409 with no_result.
Limits
The other request limits apply as on solve. Over the rate limit the answer is a
429 as on every endpoint.
Errors
A bad request body is answered with the error body of solve, with the same400, 403, 413 and 415 cases. The gateway answers the rest in its own shape, so branch on the HTTP status first:
Each of these has a
message that begins with a code, then a colon and a sentence. Never parse the sentence.
Next steps
The V3 API model
The request, and the plan a run returns
Errors
The error body and every code