maxOptimizationDuration for a bigger problem.
Batch order import
There’s no separate “batch” endpoint — a single plan already carries its fullorders array, so importing in bulk means submitting all of it in one PUT request rather than one order at a time. As shown in First API call, you can submit either:
- an inline JSON body (
-d) with the completeresources/ordersarrays, or - a file upload (
-F "file=@plan.json"), as JSON or as XLSX — column names in the spreadsheet match the JSON field names.
PUTs to the same plan id) is supported (see How the optimization engine works) but re-triggers optimization on every update, which is slower than one large submission for an initial import.
The maximum payload size accepted per request is not yet published in this documentation — see Limits and quotas. If you’re importing an unusually large order set, confirm the ceiling with support@kardinal.ai before building an automated pipeline around a single large request.
Paginating results
List endpoints such asGET /plans are unpaginated by default — every matching record is returned in one response. Pass page and/or itemsPerPage as query parameters to switch to paging:
itemsPerPage— records per page (default20, maximum100).page— 1-indexed page number (default1).
paging object (page, nextPage, previousPage, itemsPerPage) so you can walk forward without recomputing offsets yourself.
Sizing maxOptimizationDuration for a large problem
There’s no published lookup table mapping problem size to an exact optimization duration — how long a plan needs depends on more than just stop and resource counts (see the full list of drivers in How the optimization engine works): whether resources use withTraffic: true, and whether advanced constraints (AlternativesStop, removalStrategy: "lifo", overlappingCapacitiesByStopTag) are in play — any of these can switch the engine to a markedly slower algorithm regardless of raw problem size.
In practice, size maxOptimizationDuration empirically rather than guessing a fixed value up front:
- Start with the polling pattern (Kardinal’s recommended integration pattern) with a generous
maxOptimizationDurationceiling (e.g.PT1H) — the engine stops early on its own once it stops finding improvements, so an overly long ceiling costs you nothing but a slightly longer worst case. - Watch how long it actually takes to converge (successive polls stop showing objective improvements) for your real problem size and configuration.
- For recurring plans of similar shape (same rough stop/resource count, same constraint set), use that observed convergence time, with margin, as your steady-state
maxOptimizationDurationinstead of re-discovering it every time. - Re-run this calibration whenever problem size changes by an order of magnitude, or when you turn on
withTrafficor an advanced constraint for the first time — both are known to change convergence time independently of stop/resource count.
See also
- How the optimization engine works — objectives, the
maxOptimizationDurationtrade-off, and the three integration patterns (static, iterative, polling). - Limits and quotas — payload size, rate limits, and the waiting-room throughput mechanism.

