API Reference
TL;DR: base URL prefix is /api/v1, all endpoints accept and return JSON, errors follow a consistent {"code", "message", ...} shape, and every endpoint except /health requires two auth headers.
Base URL and versioning
All optimization, job, and meta endpoints are mounted under the API_V1_PREFIX setting, which defaults to /api/v1. There is currently a single API version; breaking changes would introduce a new prefix.
https://api.fieldgenius.be/api/v1/optimize/sync
Authentication
Every endpoint under /api/v1/* requires two headers. Only /health is open with no auth.
| Header | Type | Required | Description |
|---|---|---|---|
| X-API-Key | string | required | Your adapter/tenant key — identifies who is calling (e.g. a specific integration or product), not an individual end user. |
| X-Client-Key | string | required | Your client key, issued as a child of your X-API-Key tenant. Identifies a specific caller under your tenant. |
Both keys are checked against a shared caller registry: X-API-Key must match a top-level tenant, and X-Client-Key must match a client registered under that same tenant. A client key from one tenant cannot be used with a different tenant's API key. Contact your FieldGenius representative to have both issued.
HTTP status codes
| Status | Name | When |
|---|---|---|
| 200 | OK | Successful sync solve, validate, evaluate, suggest-insertion, reoptimize, replan, or GET. |
| 201 | Created | Recurring job pattern registered. |
| 202 | Accepted | Async job accepted and queued. |
| 204 | No Content | Recurring job pattern deleted. |
| 401 | Unauthorized | Missing X-API-Key or X-Client-Key header. |
| 403 | Forbidden | Invalid or unrecognized X-API-Key or X-Client-Key. |
| 404 | Not Found | Async job ID or recurring job ID not found. |
| 409 | Conflict | Async job already terminal (cancel), or optimistic-lock version conflict (recurring PATCH), or duplicate external_id (recurring POST). |
| 422 | Unprocessable Entity | Validation error, schema error, or solver-reported infeasibility/timeout-with-no-solution. |
| 500 | Internal Server Error | Unhandled internal or solver error. |
| 503 | Service Unavailable | (Planned, not yet implemented) concurrency limit reached. |
Error response shape
All structured errors (raised via the internal VRPError hierarchy) share one JSON shape in the response body's detail field:
{
"detail": {
"code": "VALIDATION_ERROR",
"message": "Resource 'truck-2' references depot 'base' which is not defined.",
"field": "resources[1].start_depot_id",
"detail": null
}
}
Some endpoints (notably jobs.py 404/409 responses) use a slightly simpler inline {"code", "message"} dict rather than the full VRPError shape; both forms always include code and message. See the full Errors reference for every code.
Endpoint summary
| Method | Path | Purpose |
|---|---|---|
| POST | /optimize/sync | Solve synchronously, return routes immediately. |
| POST | /optimize/async | Queue a solve, return a job_id immediately. |
| POST | /optimize/validate | Validate a request without solving. |
| POST | /optimize/evaluate | Score a caller-provided solution without re-solving freely. |
| POST | /optimize/suggest-insertion | Find the best insertion point for new jobs into an existing solution. |
| POST | /optimize/reoptimize | Re-solve with locks/seed already embedded in the request. |
| POST | /optimize/replan | Live re-optimization from current execution state. |
| POST | /optimize/replan/async | Queue a replan, return a job_id immediately. |
| POST | /travel/matrix | Compute a distance/time matrix from coordinates without solving. |
| GET | /jobs | List all async jobs. |
| GET | /jobs/{job_id} | Get async job status/result. |
| POST | /jobs/{job_id}/cancel | Cancel a running async job. |
| POST | /recurring-jobs | Register a recurring pattern. |
| GET | /recurring-jobs | List the tenant's recurring patterns. |
| GET | /recurring-jobs/{id} | Fetch one recurring pattern. |
| PATCH | /recurring-jobs/{id} | Partially edit a recurring pattern. |
| DELETE | /recurring-jobs/{id} | Hard-delete a recurring pattern. |
| POST | /recurring-jobs/expand | Preview expansion for a period without solving. |
| GET | /health | Liveness probe. |
| GET | /capabilities | Solver feature catalogue. |