Optimiciti Developer PortalOptimiciti Developer Portal
  • Pricing
  • Documentation
  • API Reference
  • Back to Optimiciti
Information
Problem
    Submit an optimization runpostPoll a run's status (never its routes)getCancel the optimization run identified by the problemId parameterpost
Utilities
    Health Checkget
Billing
    This month's task usagegetList public plansget
History
    Get User RunspostGet Run IdspostGet Run SummariespostList Example ScenariospostGet Run ResultspostGet a published example scenariogetUpdate Run NamepostDelete Runpost
Data-processing
    Calculate a cost matrix for the given locationspost
Optimization
    Get Run StatuspostCancel Runpost
System
    Read Rootget
Schemas
powered by Zuplo
Optimiciti API Specification
Optimiciti API Specification

Problem

Submit an optimization problem and follow it to completion. This is the core of the API - build your problem, submit it, poll for status, then read the optimized routes.


Submit an optimization run

POST
https://api.optimiciti.com
/problem

Queues a vehicle-routing or pickup-delivery problem for the solver and returns immediately with 202 Accepted and a run_id — it does not wait for the solve, and it does not compute travel costs. /problem uses the problemData.travelCosts you give it, so build that matrix first: either call POST /cost_matrix and pass its travelCostResponses straight into problemData.travelCosts (that endpoint computes from coordinates by default), or supply your own travelCosts. There is no costSettings on /problem; auto-calculation happens on POST /cost_matrix. An absent or empty matrix is rejected with MISSING_TRAVEL_COSTS, and a matrix with no usable pair at all with UNCOSTED_TRAVEL_MATRIX (see the 400 response); an all-zero matrix solves fine (every stop assigned). The solver treats a null cost or duration as unreachable, so a matrix that is only partly filled is accepted and the run succeeds with the stops behind the empty pairs left unassigned. Passing these checks is a floor, not a promise that every stop is assigned: read the assigned count in the results. See the warning on POST /cost_matrix. Poll GET /problem/{problemId} (or POST /run_status) until the run is terminal, then fetch results with POST /run_results_by_run_id.

Submit an optimization run › Request Body

The complete request payload for the /problem endpoint.
SolveRequest
​ProblemRequest · required

The Problem object embedded within the main solve request.

userId
​string | null

Your identity for ownership comes from your API key (or Clerk token), never from this field, so a run is owned by the credential that submitted it — POST /user_runs returns the runs your key made regardless of what userId you send. Required only when you call without a credential: an API-key or token request may omit it (the value is then ignored), but a request with neither a key nor a token must supply a non-empty userId as a self-assigned id, or it is rejected with 400 MISSING_USER_ID. The browser app's legacy soft-auth path uses it this way.

exampleSlug
​string

Optional. The slug of the published example scenario this solve was loaded from (as returned by /list_examples). Published examples legitimately exceed the free tier's size limits, so sending this grants a bounded allowance sized from that example's own row counts plus a small edit margin - enough to run and tweak the demo, and never more than the named example's real size. Omit it for a user's own scenarios; an unrecognised slug is ignored.

Submit an optimization run › Responses

Accepted. The run is queued and the solver runs in the background. The body carries data.run_id — the identifier you poll and fetch results with.

The body of the `202 Accepted` response to `POST /problem`. The run is queued and the solver runs in the background; poll for its status and then fetch results separately.
RequestAccepted
success
​boolean
Example: true
Default: true
​object
POST/problem
curl https://api.optimiciti.com/problem \ --request POST \ --header 'Content-Type: application/json' \ --header 'Authorization: Bearer <token>' \ --data '{ "userId": "acme-co", "problem": { "problemType": "vehicle-routing", "problemData": { "locations": [ { "locationId": "depot", "locationName": "Depot", "latitude": 39.7684, "longitude": -86.1581, "isDepot": true }, { "locationId": "a", "locationName": "Stop A", "latitude": 39.791, "longitude": -86.148, "demand": 1 }, { "locationId": "b", "locationName": "Stop B", "latitude": 39.755, "longitude": -86.175, "demand": 1 } ], "vehicles": [ { "vehicleId": "van-1", "vehicleTypeId": "van", "startLocationId": "depot", "endLocationId": "depot" } ], "vehicleTypes": [ { "vehicleTypeId": "van", "capacity": 10 } ], "travelCosts": [ { "fromLocationId": "depot", "toLocationId": "a", "distance": 1.9, "duration": 3.8, "cost": 3.8 }, { "fromLocationId": "a", "toLocationId": "depot", "distance": 1.9, "duration": 3.8, "cost": 3.8 }, { "fromLocationId": "depot", "toLocationId": "b", "distance": 1.6, "duration": 3.2, "cost": 3.2 }, { "fromLocationId": "b", "toLocationId": "depot", "distance": 1.6, "duration": 3.2, "cost": 3.2 }, { "fromLocationId": "a", "toLocationId": "b", "distance": 3, "duration": 6, "cost": 6 }, { "fromLocationId": "b", "toLocationId": "a", "distance": 3, "duration": 6, "cost": 6 }, { "fromLocationId": "depot", "toLocationId": "depot", "distance": 0, "duration": 0, "cost": 0 }, { "fromLocationId": "a", "toLocationId": "a", "distance": 0, "duration": 0, "cost": 0 }, { "fromLocationId": "b", "toLocationId": "b", "distance": 0, "duration": 0, "cost": 0 } ] } } }'
Example Request Body
{ "userId": "acme-co", "problem": { "problemType": "vehicle-routing", "problemData": { "locations": [ { "locationId": "depot", "locationName": "Depot", "latitude": 39.7684, "longitude": -86.1581, "isDepot": true }, { "locationId": "a", "locationName": "Stop A", "latitude": 39.791, "longitude": -86.148, "demand": 1 }, { "locationId": "b", "locationName": "Stop B", "latitude": 39.755, "longitude": -86.175, "demand": 1 } ], "vehicles": [ { "vehicleId": "van-1", "vehicleTypeId": "van", "startLocationId": "depot", "endLocationId": "depot" } ], "vehicleTypes": [ { "vehicleTypeId": "van", "capacity": 10 } ], "travelCosts": [ { "fromLocationId": "depot", "toLocationId": "a", "distance": 1.9, "duration": 3.8, "cost": 3.8 }, { "fromLocationId": "a", "toLocationId": "depot", "distance": 1.9, "duration": 3.8, "cost": 3.8 }, { "fromLocationId": "depot", "toLocationId": "b", "distance": 1.6, "duration": 3.2, "cost": 3.2 }, { "fromLocationId": "b", "toLocationId": "depot", "distance": 1.6, "duration": 3.2, "cost": 3.2 }, { "fromLocationId": "a", "toLocationId": "b", "distance": 3, "duration": 6, "cost": 6 }, { "fromLocationId": "b", "toLocationId": "a", "distance": 3, "duration": 6, "cost": 6 }, { "fromLocationId": "depot", "toLocationId": "depot", "distance": 0, "duration": 0, "cost": 0 }, { "fromLocationId": "a", "toLocationId": "a", "distance": 0, "duration": 0, "cost": 0 }, { "fromLocationId": "b", "toLocationId": "b", "distance": 0, "duration": 0, "cost": 0 } ] } } }
json
application/json
Example Responses
{ "success": true, "data": { "run_id": "550e8400-e29b-41d4-a716-446655440000", "status": "queued", "usage": { "tasksUsed": 9840, "tasksIncluded": 10000, "period": "2026-09", "resetsAt": "2026-10-01T00:00:00Z", "plan": "developer" } } }
json
application/json

Poll a run's status (never its routes)

GET
https://api.optimiciti.com
/problem/{problemId}

Returns the lifecycle status of the run identified by problemId (queued, running, succeeded, failed or cancelled) and nothing else: the routes are never in this response. Once data.status is succeeded, fetch the plan with POST /run_results_by_run_id. Poll every 2 to 5 seconds: a tight loop gains nothing and will run into the gateway's rate limit (429).

Poll a run's status (never its routes) › path Parameters

problemId
​string · required · explode: true

The problemId of a previously submitted problem to check the status of

Poll a run's status (never its routes) › Responses

The run's current lifecycle status. data.status is queued, running, or a terminal succeeded / failed / cancelled. This response never contains the routes — once data.status is succeeded, fetch the plan with POST /run_results_by_run_id.

success
​boolean
​RunStatus

The run lifecycle status returned by GET /problem/{problemId} and POST /run_status. This is what a poller branches on. It is deliberately small — it never carries the routes; fetch those from POST /run_results_by_run_id once the run has succeeded.

GET/problem/{problemId}
curl https://api.optimiciti.com/problem/:problemId \ --header 'Authorization: Bearer <token>'
Example Responses
{ "success": true, "data": { "run_id": "run_id", "status": "succeeded", "progress": 0, "error": "error", "error_code": "NO_FEASIBLE_SOLUTION", "run_datetime_unix": 0 } }
json
application/json

Cancel the optimization run identified by the problemId parameter

POST
https://api.optimiciti.com
/problem/cancel/{problemId}

Cancel the run identified by the problemId path parameter. A queued run is skipped by the worker; a running run is cancelled best-effort. If the run has already reached a terminal state (succeeded, failed, or cancelled) this has no effect. POST /cancel_run (which takes the id in the body) does the same thing; use whichever fits your client.

Cancel the optimization run identified by the problemId parameter › path Parameters

problemId
​string · required · explode: true

The problemId of a previously submitted problem to cancel

Cancel the optimization run identified by the problemId parameter › Responses

The cancellation was accepted. The body is the standard envelope; data carries the run's current record, including its status after the cancel was applied.

A standardized response envelope used across the API.
StandardResponse
success
​boolean

Indicates if the request was successful

Default: true
data
​

The main response payload. Can be an object, array, boolean, or string.

​ResponseError
POST/problem/cancel/{problemId}
curl https://api.optimiciti.com/problem/cancel/:problemId \ --request POST \ --header 'Authorization: Bearer <token>'
Example Responses
{ "success": true, "data": {}, "error": { "code": "code", "message": "message", "details": {} } }
json
application/json

Utilities