cuopt-server-api-python
nvidia/skills
Deploy and call the cuOpt REST server with Python/curl examples for routing and LP/MILP problems.
What is cuopt-server-api-python?
This skill covers starting the cuOpt REST server and writing clients against it in Python or curl. Use it when deploying the server to a target environment, mapping optimization problems to HTTP endpoints, or debugging API payloads.
- Start the cuOpt server locally or in Docker with GPU support
- POST optimization problems to /cuopt/request and poll /cuopt/solution/{reqId} for results
- Translate between Python API and REST field names (e.g., order_locations → task_locations)
- Verify server health and diagnose connection, payload, and configuration errors
- Run example VRP, pickup-delivery, LP, and MILP problems via REST
How to install cuopt-server-api-python
npx skills add https://github.com/nvidia/skills --skill cuopt-server-api-python- NVIDIA GPU with working CUDA driver
- cuopt-server installed or Docker with NVIDIA Container Toolkit
- Python clients require the requests library; no API key or auth token needed
How to use cuopt-server-api-python
- 1.Start the server: python -m cuopt_server.cuopt_service --ip 0.0.0.0 --port 8000 (or docker run with --gpus all)
- 2.Verify health: GET http://localhost:8000/cuopt/health (expect HTTP 200)
- 3.POST your problem to /cuopt/request with cost_matrix_data, task_data, fleet_data, and solver_config
- 4.Extract reqId from the response
- 5.Poll /cuopt/solution/{reqId} until the solution is ready (validate reqId before interpolating into URL)
- 6.Parse and use the returned solution
Use cases
- Deploy cuOpt as a microservice in Docker or Kubernetes for routing and LP/MILP solving
- Build a Python or curl client to submit vehicle routing problems and retrieve optimized routes
- Migrate from the Python API to REST by mapping field names and payload structure
- Debug 422 Unprocessable Entity errors caused by schema mismatches or malformed capacity arrays
- Set up polling loops with proper timeout and reqId validation for production clients
- Backend engineers deploying optimization services
- Data scientists building REST clients for routing or LP/MILP
- DevOps engineers containerizing cuOpt for cloud or on-premise deployment
- Anyone integrating cuOpt into a microservice architecture
cuopt-server-api-python FAQ
Routing and LP/MILP. Quadratic programming (QP) is not exposed over REST; use the Python or C API instead.
Check field names against the OpenAPI spec at /cuopt.yaml. Common mistakes: transit_time_matrix_data should be travel_time_matrix_data, and capacities should be [[50, 50]] (one list per dimension), not [[50], [50]].
No. The server ships with no auth or TLS. Treat it as a trusted-network endpoint only and put it behind a gateway in production.
Use docker run --gpus all -d -p 8000:8000 nvidia/cuopt:latest-cu13 (or latest-cu12 to match your CUDA version). Pin to a full release tag in production instead of latest-*.
Save the reqId and the full response body—both are needed to diagnose server-side rejections.
Full instructions (SKILL.md)
Source of truth, from nvidia/skills.
name: cuopt-server-api-python version: "26.10.00" description: cuOpt REST server — start server, endpoints, Python/curl client examples. Use when the user is deploying or calling the REST API. license: Apache-2.0 metadata: author: NVIDIA cuOpt Team tags: - cuopt - server - rest-api - python - deployment
cuOpt Server — Deploy and client (Python/curl)
This skill covers starting the server and client examples (curl, Python). Server has no separate C API (clients can be any language).
Purpose
Use this skill when the user is deploying the cuOpt REST server or writing a client against it — choosing a deployment target, mapping a problem onto the HTTP endpoints, translating between Python-API and REST field names, or debugging a rejected payload.
Prerequisites
- An NVIDIA GPU with a working CUDA driver (the server requires one;
--gpus allfor Docker). cuopt-serverinstalled, or Docker with the NVIDIA Container Toolkit. See the install skill.- Python clients need
requests. No API key or auth token is required by the server itself.
Problem types supported
| Problem type | Supported |
|---|---|
| Routing | ✓ |
| LP | ✓ |
| MILP | ✓ |
| QP | ✗ |
Required questions
Ask these if not already clear:
- Problem type — Routing or LP/MILP? (QP not available via REST.)
- Deployment — Local, Docker, Kubernetes, or cloud?
- Client — Which language or tool will call the API (e.g. Python, curl, another service)?
Start server
# Development
python -m cuopt_server.cuopt_service --ip 0.0.0.0 --port 8000
# Docker — pick the tag matching your CUDA major version
docker run --gpus all -d -p 8000:8000 -e CUOPT_SERVER_PORT=8000 \
nvidia/cuopt:latest-cu13
Use latest-cu12 or latest-cu13 to match your driver's CUDA major version (latest-cu13-ubi10 for a UBI10 base). Prefer these over the CUDA+Python-specific tags such as latest-cuda12.9-py3.13 — those track a single Python line and go stale when it stops receiving builds.
For production, pin rather than float: latest-* tags are mutable and can silently move to a different image. Use a full release tag (nvidia/cuopt:<release>-cuda<cuda>-py<python>) or an immutable digest (nvidia/cuopt@sha256:<digest>). Check the nvidia/cuopt registry for available tags.
Verify
Confirm the server is up by requesting GET /cuopt/health on the local port (e.g. http://localhost:8000/cuopt/health) — a healthy server returns HTTP 200.
Instructions
- POST to
/cuopt/request→ getreqId - Poll
/cuopt/solution/{reqId}until solution ready - Parse response
Treat reqId as untrusted input: validate it (e.g. re.fullmatch(r"[A-Za-z0-9_-]{1,64}", req_id)) before interpolating it into the polling URL, and set an explicit timeout on every request.
Examples
import requests, time
SERVER = "http://localhost:8000"
HEADERS = {"Content-Type": "application/json", "CLIENT-VERSION": "custom"}
payload = {
"cost_matrix_data": {"data": {"0": [[0,10,15],[10,0,12],[15,12,0]]}},
"travel_time_matrix_data": {"data": {"0": [[0,10,15],[10,0,12],[15,12,0]]}},
"task_data": {"task_locations": [1, 2], "demand": [[10, 20]], "task_time_windows": [[0,100],[0,100]], "service_times": [5, 5]},
"fleet_data": {"vehicle_locations": [[0, 0]], "capacities": [[50]], "vehicle_time_windows": [[0, 200]]},
"solver_config": {"time_limit": 5}
}
r = requests.post(f"{SERVER}/cuopt/request", json=payload, headers=HEADERS, timeout=30)
req_id = r.json()["reqId"]
# Poll: GET /cuopt/solution/{req_id}
Terminology: REST vs Python API
| Python API | REST |
|---|---|
| order_locations | task_locations |
| set_order_time_windows() | task_time_windows |
| service_times | service_times |
Use travel_time_matrix_data (not transit_time_matrix_data). Capacities: [[50, 50]] not [[50], [50]].
Troubleshooting
| Error | Cause | Solution |
|---|---|---|
422 Unprocessable Entity | Field name not in the schema | Check names against the OpenAPI spec at /cuopt.yaml. Most common: transit_time_matrix_data → travel_time_matrix_data |
422 on fleet_data | Capacities nested per vehicle instead of per dimension | Use [[50, 50]] (one inner list per capacity dimension), not [[50], [50]] |
| Connection refused | Server not up, or bound to a different interface/port | curl http://localhost:8000/cuopt/health; start with --ip 0.0.0.0 --port 8000 |
| Docker container exits immediately | No GPU visible to the container | Run with --gpus all and confirm the NVIDIA Container Toolkit is installed |
| Polling never returns a solution | Solve exceeds the client's poll budget | Raise solver_config.time_limit and the poll loop count together |
Capture the reqId and the full response body for any failed request — both are needed to diagnose server-side rejections.
Limitations
- QP is not exposed over REST. Use the Python or C API for quadratic objectives.
- The server ships no authentication or TLS. Anything that can reach the port can submit jobs. Put it behind a gateway and treat
--server/base URLs as trusted-network endpoints only. - Solutions are retrieved by polling; there is no push/webhook delivery.
- One request is solved at a time per server process; concurrency requires multiple replicas.
Runnable assets
Run from each asset directory (server must be running; scripts exit 0 if server unreachable). All use Python requests and accept --server (default http://localhost:8000):
- assets/vrp_simple/ — Basic VRP (no time windows)
- assets/vrp_basic/ — VRP with time windows
- assets/pdp_basic/ — Pickup and delivery
- assets/lp_basic/ — LP via REST (CSR format)
- assets/milp_basic/ — MILP via REST
See assets/README.md for overview.
Escalate
For contribution or build-from-source, see the developer skill.
Related skills
More from nvidia/skills and the wider catalog.

cuopt-server-common
Understand cuOpt REST server concepts, request flow, and supported problem types.

cuopt-skill-evolution
Detect generalizable learnings from problem-solving and propose skill updates automatically.

cuopt-user-rules
Base rules for end users calling NVIDIA cuOpt (routing/LP/MILP/QP/install/server).

cupynumeric-hdf5
Read and write large cuPyNumeric arrays to HDF5 with parallel, distributed I/O via Legate.

cupynumeric-install
Install and verify cuPyNumeric for GPU-accelerated NumPy on Linux/WSL.

cupynumeric-migration-readiness
Pre-migration readiness assessor for porting NumPy code to cuPyNumeric GPU arrays.