{
"code": "invalid_request",
"errors": [
{
"code": "out_of_range",
"message": "depot 'gent': service_duration_s must be >= 0, got -60",
"pointer": "/problem/depots/0/service_duration_s"
}
],
"message": "depot 'gent': service_duration_s must be >= 0, got -60",
"request_id": "req_7f3a2c90d1e4b5a6",
"status": "BAD_REQUEST"
}
{
"code": "feature_not_enabled",
"message": "travel.engine: 'tomtom_real_time' is not enabled for this account; use engine 'tomtom'",
"request_id": "req_7f3a2c90d1e4b5a6",
"status": "FORBIDDEN"
}
Scores plan against problem without running the optimizer: objective
totals, timing, loads and constraint violations. Tasks absent from every
route are reported as unassigned. A solve response's plan goes in as it
stands.
{
"code": "invalid_request",
"errors": [
{
"code": "out_of_range",
"message": "depot 'gent': service_duration_s must be >= 0, got -60",
"pointer": "/problem/depots/0/service_duration_s"
}
],
"message": "depot 'gent': service_duration_s must be >= 0, got -60",
"request_id": "req_7f3a2c90d1e4b5a6",
"status": "BAD_REQUEST"
}
{
"code": "feature_not_enabled",
"message": "travel.engine: 'tomtom_real_time' is not enabled for this account; use engine 'tomtom'",
"request_id": "req_7f3a2c90d1e4b5a6",
"status": "FORBIDDEN"
}
{
"code": "invalid_request",
"errors": [
{
"code": "out_of_range",
"message": "depot 'gent': service_duration_s must be >= 0, got -60",
"pointer": "/problem/depots/0/service_duration_s"
}
],
"message": "depot 'gent': service_duration_s must be >= 0, got -60",
"request_id": "req_7f3a2c90d1e4b5a6",
"status": "BAD_REQUEST"
}
{"docsConfig":{"theme":"maple","$schema":"https://mintlify.com/docs.json","name":"Solvice Docs","description":"Solvice API documentation for cloud-native optimization solvers. Build powerful route optimization, workforce scheduling, and resource allocation solutions with our VRP, shift planning, and clustering APIs.","colors":{"primary":"#0f62fe","light":"#0f62fe","dark":"#0f62fe"},"logo":{"light":"https://mintcdn.com/solvice-68592f22/1KJ_2AIotizI1Bng/logo/light.svg?fit=max\u0026auto=format\u0026n=1KJ_2AIotizI1Bng\u0026q=85\u0026s=e93560fee320491613107060a1afc094","dark":"https://mintcdn.com/solvice-68592f22/1KJ_2AIotizI1Bng/logo/dark.svg?fit=max\u0026auto=format\u0026n=1KJ_2AIotizI1Bng\u0026q=85\u0026s=1baeb15bf7826f571444a1d6a36fb31a"},"favicon":"https://mintcdn.com/solvice-68592f22/noMIHjSWP2Tg_tTz/favicon.png?fit=max\u0026auto=format\u0026n=noMIHjSWP2Tg_tTz\u0026q=85\u0026s=beff99df9d507e0794596b5437be687f","api":{"mdx":{"auth":{"method":"key","name":"Authorization"}}},"navbar":{"links":[{"href":"mailto:support@solvice.io","label":"Support"},{"href":"https://www.solvice.io","label":"Solvice website"}],"primary":{"type":"button","label":"Dashboard","href":"https://platform.solvice.io"}},"footer":{"socials":{"website":"https://www.solvice.io","x":"https://x.com/solvice_io","github":"https://github.com/solvice","linkedin":"https://linkedin.com/company/solvice"}},"seo":{"metatags":{"og:image":"link to your default meta tag image","charset":"UTF-8","viewport":"width=device-width, initial-scale=1.0","description":"Solvice API documentation for cloud-native optimization solvers. Build powerful route optimization, workforce scheduling, and resource allocation solutions with our VRP, shift planning, and clustering APIs.","keywords":"Route Optimization, Route API, Optimization API, Workforce Scheduling, Solvice","author":"Christophe Van Huele","robots":"index, follow","googlebot":"index, follow","google":"notranslate","google-site-verification":"verification_token"},"indexing":"all"},"integrations":{"ga4":{"measurementId":"G-2L8R78J6J9"}},"banner":{"content":"Solvice VRP API v3 is in beta. General availability (GA) is planned for January 2027.","dismissible":false},"contextual":{"options":["claude","copy"],"display":"header"},"styling":{"latex":true},"navigation":{"global":{"anchors":[{"anchor":"Dashboard","icon":"book-open-cover","href":"https://platform.solvice.io"},{"anchor":"Website","icon":"planet-ringed","href":"https://www.solvice.io"},{"anchor":"Blog","icon":"newspaper","href":"https://www.solvice.io/blog/news"}]},"pages":[]}},"deployment":{"deploymentMetadataValue":{"subdomain":"solvice-68592f22","hasAudioNarration":false,"actualSubdomain":"solvice-68592f22","customDomains":["docs.solvice.io"],"gitSource":{"type":"gitlab","owner":"solvice","repo":"solver2","projectId":44919668,"deployBranch":"main","contentDirectory":"mintlify","isPrivate":true,"mountPath":"","label":""},"chroma":{"liveDeploymentHistoryId":"6ad205466244a69b2931f7fb","collectionId":"8ef7747f-3efd-4d3f-b092-798010502a52","schemaVersion":"v3","latestBuiltDeploymentHistoryId":"6ad205466244a69b2931f7fb"},"feedback":{"thumbs":true},"entitlements":{"AI_CHAT":{"status":"DISABLED"},"REMOVE_BRANDING":{"status":"DISABLED"}},"buildId":"6ae30814d48146ed4e44ffe1","clientVersion":"0.0.4006","searchFilterCounts":[{"language":"default","tag":"Guides","count":81},{"language":"default","tag":"VRP API","count":49},{"language":"default","tag":"Features","count":32},{"language":"default","tag":"Routing API","count":28},{"language":"default","tag":"API Reference","count":26},{"language":"default","tag":"Fill API","count":20},{"language":"default","tag":"Platform","count":10},{"language":"default","tag":"Examples","count":9},{"language":"default","tag":"Concepts","count":9},{"language":"default","tag":"Info","count":6}]},"assistantConfig":{"deflection":{"enabled":true,"email":"support@solvice.io","showHelpButton":true}},"basePath":"","hasChatPermissions":false,"hasWebMcpPermissions":false,"toggles":[{"name":"kill-isr","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"agent-mintlify-slack","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"agent-integrations-settings","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automations-pr-grouping","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"custom-prefix","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"analytics-v7","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"user-flows-analytics","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"no-publish-flow","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-onboarding","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"llms-txt-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"pause-universal-search-reconcile","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"snapshot-serving-live","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"stripTemperatureMiddleware","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"per-site-search-delta","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"support-platform-pylon-zendesk","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"snapshot-serving","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"instant-rollback","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"granular-notifications-server","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"granular-notifications","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-private-page-search","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automations-fable","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"fixed-ai-action-pricing","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automation-resolve-merge-conflict","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"scoped-publishing","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"mintql","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"page-level-analytics","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-version-history-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"billing-page-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workspace-projects","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"assistant-v5","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"byok-sep-25","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"fork-pr-previews","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"revalidation-jwt","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"vite-origin","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"billing-updated-9-15","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-sso-scim","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"hobby-abuse-scan","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"dashboard-inbox","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-signup","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-enabled","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false}],"googleFontsInlined":false},"customCss":[],"page":{"pagePath":"api-reference/vrp/v3/validate-evaluate","slug":"/api-reference/vrp/v3/validate-evaluate","pageMetadata":{"title":"Validate evaluate","openapi":"vrp-v3 POST /v3/routing/validate/evaluate","description":"Check a evaluate request without running it","href":"/api-reference/vrp/v3/validate-evaluate"},"description":{"compiledSource":"\"use strict\";\nconst {jsx: _jsx} = arguments[0];\nconst {useMDXComponents: _provideComponents} = arguments[0];\nfunction _createMdxContent(props) {\n const _components = {\n p: \"p\",\n ..._provideComponents(),\n ...props.components\n };\n return _jsx(_components.p, {\n children: \"Check a evaluate request without running it\"\n });\n}\nfunction MDXContent(props = {}) {\n const {wrapper: MDXLayout} = {\n ..._provideComponents(),\n ...props.components\n };\n return MDXLayout ? _jsx(MDXLayout, {\n ...props,\n children: _jsx(_createMdxContent, {\n ...props\n })\n }) : _createMdxContent(props);\n}\nreturn {\n default: MDXContent\n};\n","frontmatter":{},"scope":{}},"pageType":"default","mdx":{"mdxSource":{"compiledSource":"\"use strict\";const{jsx:_jsx,jsxs:_jsxs}=arguments[0];const{useMDXComponents:_provideComponents}=arguments[0];function _createMdxContent(props){const _components={p:`p`,strong:`strong`,..._provideComponents(),...props.components},{Info}=_components;if(!Info)_missingMdxReference(`Info`,true);return _jsx(Info,{children:_jsxs(_components.p,{children:[_jsx(_components.strong,{children:`V3 is in beta.`}),` General availability (GA) is planned for January 2027.`]})})}function MDXContent(props={}){const{wrapper:MDXLayout}={..._provideComponents(),...props.components};return MDXLayout?_jsx(MDXLayout,{...props,children:_jsx(_createMdxContent,{...props})}):_createMdxContent(props)}return{default:MDXContent};function _missingMdxReference(id,component){throw new Error(`Expected `+(component?`component`:`object`)+\" `\"+id+\"` to be defined: you likely forgot to import, pass, or provide it.\")}","frontmatter":{},"scope":{"config":{},"pageMetadata":{"title":"Validate evaluate","openapi":"vrp-v3 POST /v3/routing/validate/evaluate","description":"Check a evaluate request without running it","href":"/api-reference/vrp/v3/validate-evaluate"}}},"mdxSourceWithNoJs":null},"mdxExtracts":{"tableOfContents":[],"codeExamples":{}},"jsLinks":[],"openApiReferenceData":{"operation":{"tags":["Routing"],"summary":"Check an evaluate request without running it","description":"Check a evaluate request without running it","operationId":"validate_evaluate","requestBody":"7aa4b06e-ace7-49ba-8f72-7906a3947806","responses":{"200":"c9a07169-5660-46a0-be7e-a5515b9e34ed","400":"ac24eec3-b632-4a58-9bc0-23ac25f6046a","401":"1ec46414-4ee4-4d34-a945-8d592f63407f","403":"270fd366-9898-44d8-bca2-de0186d11c49","413":"31071ba1-e707-4080-b5dd-1fd5ca2e59e9","415":"cc4252b9-ccaa-4394-ab60-4d5c8f7bc60b","429":"85e1633f-c6ff-46a5-95b5-3b957de6044a","500":"9bdde50b-2ab8-4535-9514-9d7f04d4275d"},"method":"post","type":"path","servers":["201228c4-350a-441d-b6ae-257ddac506eb"],"security":["9ccad23f-2998-47f5-b1b2-2885a0d8c12b"],"path":"/v3/routing/validate/evaluate","baseUrlOptions":["https://api.solvice.io"],"title":"Check an evaluate request without running it","codeSamples":[],"requiredOnlyExamples":false,"requestExampleType":"generated","responseExampleType":"generated"},"dependencies":{"parameters":{},"requestBody":{"content":{"application/json":{"schema":{"type":"object","description":"Request body for `POST /v3/routing/evaluate`.\n\nScores `plan` against `problem` without running the optimizer: objective\ntotals, timing, loads and constraint violations. Tasks absent from every\nroute are reported as unassigned. A solve response's `plan` goes in as it\nstands.","required":["problem","plan"],"properties":{"plan":{"type":"object","description":"The plan to score.","required":["routes"],"properties":{"routes":{"type":"array","items":{"type":"object","description":"One vehicle shift's route: every trip of the shift, split by `reload` stops.","required":["vehicle","shift","stops"],"properties":{"shift":{"type":"string","description":"Shift id, within that vehicle.","isRequired":true,"uniqueKey":"plan.routes.items.[INDEX].shift","typeLabel":"string"},"stops":{"type":"array","items":{"oneOf":[{"type":"object","title":"PlanStopJob","description":"One stop of a plan route. Start, end and breaks are placed by the solver\nand are not listed.","required":["id","type"],"example":{"id":"parts-9:pickup","type":"pickup"},"properties":{"id":{"type":"string","description":"Job id.","example":"boiler-17","isRequired":true,"uniqueKey":"plan.routes.items.[INDEX].stops.items.[INDEX].oneOf.0.id","typeLabel":"string"},"type":{"type":"string","description":"Discriminator: always `job`.","enum":["job"],"isRequired":true,"uniqueKey":"plan.routes.items.[INDEX].stops.items.[INDEX].oneOf.0.type","typeLabel":"enum\u003cstring>"}},"additionalProperties":false,"uniqueKey":"plan.routes.items.[INDEX].stops.items.[INDEX].oneOf.0","typeLabel":"PlanStopJob · object"},{"type":"object","title":"PlanStopPickup","description":"One stop of a plan route. Start, end and breaks are placed by the solver\nand are not listed.","required":["id","type"],"example":{"id":"parts-9:pickup","type":"pickup"},"properties":{"id":{"type":"string","description":"The leg's stop id: its own `id`, else `{shipment}:pickup`.","example":"parts-9:pickup","isRequired":true,"uniqueKey":"plan.routes.items.[INDEX].stops.items.[INDEX].oneOf.1.id","typeLabel":"string"},"type":{"type":"string","description":"Discriminator: always `pickup`.","enum":["pickup"],"isRequired":true,"uniqueKey":"plan.routes.items.[INDEX].stops.items.[INDEX].oneOf.1.type","typeLabel":"enum\u003cstring>"}},"additionalProperties":false,"uniqueKey":"plan.routes.items.[INDEX].stops.items.[INDEX].oneOf.1","typeLabel":"PlanStopPickup · object"},{"type":"object","title":"PlanStopDelivery","description":"One stop of a plan route. Start, end and breaks are placed by the solver\nand are not listed.","required":["id","type"],"example":{"id":"parts-9:pickup","type":"pickup"},"properties":{"id":{"type":"string","description":"The leg's stop id: its own `id`, else `{shipment}:delivery`.","example":"parts-9:delivery","isRequired":true,"uniqueKey":"plan.routes.items.[INDEX].stops.items.[INDEX].oneOf.2.id","typeLabel":"string"},"type":{"type":"string","description":"Discriminator: always `delivery`.","enum":["delivery"],"isRequired":true,"uniqueKey":"plan.routes.items.[INDEX].stops.items.[INDEX].oneOf.2.type","typeLabel":"enum\u003cstring>"}},"additionalProperties":false,"uniqueKey":"plan.routes.items.[INDEX].stops.items.[INDEX].oneOf.2","typeLabel":"PlanStopDelivery · object"},{"type":"object","title":"PlanStopReload","description":"One stop of a plan route. Start, end and breaks are placed by the solver\nand are not listed.","required":["depot","type"],"example":{"type":"pickup"},"properties":{"depot":{"type":"string","description":"A depot id from the shift's `reloads`.","example":"gent","isRequired":true,"uniqueKey":"plan.routes.items.[INDEX].stops.items.[INDEX].oneOf.3.depot","typeLabel":"string"},"type":{"type":"string","description":"Discriminator: always `reload`.","enum":["reload"],"isRequired":true,"uniqueKey":"plan.routes.items.[INDEX].stops.items.[INDEX].oneOf.3.type","typeLabel":"enum\u003cstring>"}},"additionalProperties":false,"uniqueKey":"plan.routes.items.[INDEX].stops.items.[INDEX].oneOf.3","typeLabel":"PlanStopReload · object"}],"uniqueKey":"plan.routes.items.[INDEX].stops.items.[INDEX]","typeLabel":"PlanStopJob · object | PlanStopPickup · object | PlanStopDelivery · object | PlanStopReload · object"},"description":"Stops in visiting order.","isRequired":true,"uniqueKey":"plan.routes.items.[INDEX].stops","typeLabel":"(PlanStopJob · object | PlanStopPickup · object | PlanStopDelivery · object | PlanStopReload · object)[]"},"vehicle":{"type":"string","description":"Vehicle id.","isRequired":true,"uniqueKey":"plan.routes.items.[INDEX].vehicle","typeLabel":"string"},"locked_count":{"oneOf":[{"type":"integer","format":"int32","description":"On solve, the first `locked_count` stops stay where they are (already\ndispatched). Counts every listed stop. Cannot be combined with a\n`reload` stop, and must not exceed the route's stop count — both are\nvalidated on every endpoint that takes a plan. Otherwise inert on\nevaluate. On suggest, no insertion lands before them.","example":1,"minimum":0,"uniqueKey":"plan.routes.items.[INDEX].locked_count.oneOf.0","typeLabel":"integer\u003cint32>"},{"type":"null","format":"int32","description":"On solve, the first `locked_count` stops stay where they are (already\ndispatched). Counts every listed stop. Cannot be combined with a\n`reload` stop, and must not exceed the route's stop count — both are\nvalidated on every endpoint that takes a plan. Otherwise inert on\nevaluate. On suggest, no insertion lands before them.","example":1,"minimum":0,"uniqueKey":"plan.routes.items.[INDEX].locked_count.oneOf.1","typeLabel":"null"}],"uniqueKey":"plan.routes.items.[INDEX].locked_count","typeLabel":"integer\u003cint32> | null"}},"additionalProperties":false,"example":{"shift":"mon","stops":[{"id":"boiler-17","type":"job"}],"vehicle":"van-3"},"uniqueKey":"plan.routes.items.[INDEX]","typeLabel":"object"},"description":"One entry per vehicle shift that serves something.","isRequired":true,"uniqueKey":"plan.routes","typeLabel":"object[]"}},"additionalProperties":false,"isRequired":true,"uniqueKey":"plan","typeLabel":"object"},"problem":{"type":"object","description":"Problem definition — identical to `POST /v3/routing/solve`.","required":["vehicles"],"properties":{"vehicles":{"type":"array","items":{"type":"object","description":"A vehicle type available to serve tasks.","required":["id","shifts"],"properties":{"id":{"type":"string","description":"Vehicle id: 1 to 128 characters, unique across `vehicles[]`; echoed as\n`routes[].vehicle`.","example":"v1","maxLength":128,"minLength":1,"isRequired":true,"uniqueKey":"problem.vehicles.items.[INDEX].id","typeLabel":"string"},"shifts":{"type":"array","items":{"type":"object","description":"One working shift for a vehicle.","required":["id","from","to"],"properties":{"from":{"type":"string","format":"date-time","description":"Shift start (RFC 3339 instant, UTC offset required).","example":"2026-07-01T08:00:00+02:00","isRequired":true,"uniqueKey":"problem.vehicles.items.[INDEX].shifts.items.[INDEX].from","typeLabel":"string\u003cdate-time>"},"id":{"type":"string","description":"Shift id: 1 to 128 characters, unique within this vehicle.","example":"mon","maxLength":128,"minLength":1,"isRequired":true,"uniqueKey":"problem.vehicles.items.[INDEX].shifts.items.[INDEX].id","typeLabel":"string"},"to":{"type":"string","format":"date-time","description":"Shift end (RFC 3339 instant, UTC offset required; hard unless `max_overtime_s` set). The\nroute must be finished by then, end-depot unload included.","example":"2026-07-01T17:00:00+02:00","isRequired":true,"uniqueKey":"problem.vehicles.items.[INDEX].shifts.items.[INDEX].to","typeLabel":"string\u003cdate-time>"},"breaks":{"oneOf":[{"type":"array","items":{"oneOf":[{"type":"object","title":"Windowed","description":"A scheduled break within a shift. Tagged by `type`:\n\n- `windowed`: a break of `duration_s` that starts inside its window.\n- `triggered`: a break of `duration_s` taken once drive or duty time\n passes `threshold_s` (the EU-561 mechanism).\n- `fixed`: a hard off-duty interval from `from` to `to`.\n\nBreaks are injected between stops and appear in the response as `break`\nstops, carrying the break's `id` when it has one.\n\nA `triggered` break always resets its accumulator after a qualifying break\nand is taken wherever the vehicle is: `resets_accumulator` and `location`\ndo not exist on it. A `windowed` break takes exactly one `time_window` and\nis also taken wherever the vehicle is: a `location` on it is HTTP 400\n`not_supported`.\n\nThere is no paid/unpaid cost accounting: a break's duration is never\nseparately priced, and no `paid` field exists on this schema — sending one\nis rejected as an unknown field (HTTP 400, `unknown_field`), like any other extra key.","required":["duration_s","time_window","type"],"example":{"duration_s":1800,"type":"triggered"},"properties":{"duration_s":{"type":"integer","format":"int32","description":"Break duration in seconds. Must be `> 0`.","minimum":1,"isRequired":true,"uniqueKey":"problem.vehicles.items.[INDEX].shifts.items.[INDEX].breaks.oneOf.0.items.[INDEX].oneOf.0.duration_s","typeLabel":"integer\u003cint32>"},"time_window":{"type":"object","description":"The window bounding the break's **start**.","required":["from","to"],"properties":{"from":{"type":"string","format":"date-time","description":"Earliest break start (RFC 3339 instant, UTC offset required).","isRequired":true,"uniqueKey":"problem.vehicles.items.[INDEX].shifts.items.[INDEX].breaks.oneOf.0.items.[INDEX].oneOf.0.time_window.from","typeLabel":"string\u003cdate-time>"},"to":{"type":"string","format":"date-time","description":"Latest break start (RFC 3339 instant, UTC offset required).","isRequired":true,"uniqueKey":"problem.vehicles.items.[INDEX].shifts.items.[INDEX].breaks.oneOf.0.items.[INDEX].oneOf.0.time_window.to","typeLabel":"string\u003cdate-time>"}},"additionalProperties":false,"example":{"from":"2026-07-01T12:00:00+02:00","to":"2026-07-01T13:30:00+02:00"},"isRequired":true,"uniqueKey":"problem.vehicles.items.[INDEX].shifts.items.[INDEX].breaks.oneOf.0.items.[INDEX].oneOf.0.time_window","typeLabel":"object"},"type":{"type":"string","description":"Discriminator: always `windowed`.","enum":["windowed"],"isRequired":true,"uniqueKey":"problem.vehicles.items.[INDEX].shifts.items.[INDEX].breaks.oneOf.0.items.[INDEX].oneOf.0.type","typeLabel":"enum\u003cstring>"},"id":{"oneOf":[{"type":"string","description":"Optional break id: 1 to 128 characters, unique within the shift.\nEchoed as `id` on the `break` stop that realises this break.","example":"lunch","maxLength":128,"minLength":1,"uniqueKey":"problem.vehicles.items.[INDEX].shifts.items.[INDEX].breaks.oneOf.0.items.[INDEX].oneOf.0.id.oneOf.0","typeLabel":"string"},{"type":"null","description":"Optional break id: 1 to 128 characters, unique within the shift.\nEchoed as `id` on the `break` stop that realises this break.","example":"lunch","maxLength":128,"minLength":1,"uniqueKey":"problem.vehicles.items.[INDEX].shifts.items.[INDEX].breaks.oneOf.0.items.[INDEX].oneOf.0.id.oneOf.1","typeLabel":"null"}],"uniqueKey":"problem.vehicles.items.[INDEX].shifts.items.[INDEX].breaks.oneOf.0.items.[INDEX].oneOf.0.id","typeLabel":"string | null"},"location":{"oneOf":[{"type":"null","description":"Not supported on V3: a windowed break is taken wherever the\nvehicle is when it starts, so a `location` here is rejected with\nHTTP 400 `not_supported`. Set only by the V2 compatibility mapper.","uniqueKey":"problem.vehicles.items.[INDEX].shifts.items.[INDEX].breaks.oneOf.0.items.[INDEX].oneOf.0.location.oneOf.0","typeLabel":"null"},{"type":"array","items":{"type":"number","format":"double","uniqueKey":"problem.vehicles.items.[INDEX].shifts.items.[INDEX].breaks.oneOf.0.items.[INDEX].oneOf.0.location.oneOf.1.items.[INDEX]","typeLabel":"number\u003cdouble>"},"description":"Not supported on V3: a windowed break is taken wherever the\nvehicle is when it starts, so a `location` here is rejected with\nHTTP 400 `not_supported`. Set only by the V2 compatibility mapper.","maxItems":2,"minItems":2,"example":[3.725,51.05],"uniqueKey":"problem.vehicles.items.[INDEX].shifts.items.[INDEX].breaks.oneOf.0.items.[INDEX].oneOf.0.location.oneOf.1","typeLabel":"number\u003cdouble>[]"}],"uniqueKey":"problem.vehicles.items.[INDEX].shifts.items.[INDEX].breaks.oneOf.0.items.[INDEX].oneOf.0.location","typeLabel":"null | number\u003cdouble>[]"}},"additionalProperties":false,"uniqueKey":"problem.vehicles.items.[INDEX].shifts.items.[INDEX].breaks.oneOf.0.items.[INDEX].oneOf.0","typeLabel":"Windowed · object"},{"type":"object","title":"Triggered","description":"A scheduled break within a shift. Tagged by `type`:\n\n- `windowed`: a break of `duration_s` that starts inside its window.\n- `triggered`: a break of `duration_s` taken once drive or duty time\n passes `threshold_s` (the EU-561 mechanism).\n- `fixed`: a hard off-duty interval from `from` to `to`.\n\nBreaks are injected between stops and appear in the response as `break`\nstops, carrying the break's `id` when it has one.\n\nA `triggered` break always resets its accumulator after a qualifying break\nand is taken wherever the vehicle is: `resets_accumulator` and `location`\ndo not exist on it. A `windowed` break takes exactly one `time_window` and\nis also taken wherever the vehicle is: a `location` on it is HTTP 400\n`not_supported`.\n\nThere is no paid/unpaid cost accounting: a break's duration is never\nseparately priced, and no `paid` field exists on this schema — sending one\nis rejected as an unknown field (HTTP 400, `unknown_field`), like any other extra key.","required":["duration_s","after","threshold_s","type"],"example":{"after":"drive","duration_s":1800,"threshold_s":14400,"type":"triggered"},"properties":{"after":{"type":"string","description":"What to accumulate: drive time or duty time.","enum":["drive","duty"],"example":"drive","isRequired":true,"uniqueKey":"problem.vehicles.items.[INDEX].shifts.items.[INDEX].breaks.oneOf.0.items.[INDEX].oneOf.1.after","typeLabel":"enum\u003cstring>"},"duration_s":{"type":"integer","format":"int32","description":"Break duration in seconds. Must be `> 0`.","minimum":1,"isRequired":true,"uniqueKey":"problem.vehicles.items.[INDEX].shifts.items.[INDEX].breaks.oneOf.0.items.[INDEX].oneOf.1.duration_s","typeLabel":"integer\u003cint32>"},"threshold_s":{"type":"integer","format":"int64","description":"Trigger threshold in seconds (strict `>` — the break fires when the\naccumulator exceeds this). EU 561/2006 drive rule: `16200` (4 h 30).\nMust be `> 0` and fit in 32 bits.","example":14400,"maximum":2147483647,"minimum":1,"isRequired":true,"uniqueKey":"problem.vehicles.items.[INDEX].shifts.items.[INDEX].breaks.oneOf.0.items.[INDEX].oneOf.1.threshold_s","typeLabel":"integer\u003cint64>"},"type":{"type":"string","description":"Discriminator: always `triggered`.","enum":["triggered"],"isRequired":true,"uniqueKey":"problem.vehicles.items.[INDEX].shifts.items.[INDEX].breaks.oneOf.0.items.[INDEX].oneOf.1.type","typeLabel":"enum\u003cstring>"},"id":{"oneOf":[{"type":"string","description":"Optional break id: 1 to 128 characters, unique within the shift.\nEchoed as `id` on the `break` stop that realises this break.","example":"lunch","maxLength":128,"minLength":1,"uniqueKey":"problem.vehicles.items.[INDEX].shifts.items.[INDEX].breaks.oneOf.0.items.[INDEX].oneOf.1.id.oneOf.0","typeLabel":"string"},{"type":"null","description":"Optional break id: 1 to 128 characters, unique within the shift.\nEchoed as `id` on the `break` stop that realises this break.","example":"lunch","maxLength":128,"minLength":1,"uniqueKey":"problem.vehicles.items.[INDEX].shifts.items.[INDEX].breaks.oneOf.0.items.[INDEX].oneOf.1.id.oneOf.1","typeLabel":"null"}],"uniqueKey":"problem.vehicles.items.[INDEX].shifts.items.[INDEX].breaks.oneOf.0.items.[INDEX].oneOf.1.id","typeLabel":"string | null"}},"additionalProperties":false,"uniqueKey":"problem.vehicles.items.[INDEX].shifts.items.[INDEX].breaks.oneOf.0.items.[INDEX].oneOf.1","typeLabel":"Triggered · object"},{"type":"object","title":"Fixed","description":"A scheduled break within a shift. Tagged by `type`:\n\n- `windowed`: a break of `duration_s` that starts inside its window.\n- `triggered`: a break of `duration_s` taken once drive or duty time\n passes `threshold_s` (the EU-561 mechanism).\n- `fixed`: a hard off-duty interval from `from` to `to`.\n\nBreaks are injected between stops and appear in the response as `break`\nstops, carrying the break's `id` when it has one.\n\nA `triggered` break always resets its accumulator after a qualifying break\nand is taken wherever the vehicle is: `resets_accumulator` and `location`\ndo not exist on it. A `windowed` break takes exactly one `time_window` and\nis also taken wherever the vehicle is: a `location` on it is HTTP 400\n`not_supported`.\n\nThere is no paid/unpaid cost accounting: a break's duration is never\nseparately priced, and no `paid` field exists on this schema — sending one\nis rejected as an unknown field (HTTP 400, `unknown_field`), like any other extra key.","required":["from","to","type"],"example":{"type":"triggered"},"properties":{"from":{"type":"string","format":"date-time","description":"Start of the break (RFC 3339 instant, UTC offset required).","isRequired":true,"uniqueKey":"problem.vehicles.items.[INDEX].shifts.items.[INDEX].breaks.oneOf.0.items.[INDEX].oneOf.2.from","typeLabel":"string\u003cdate-time>"},"to":{"type":"string","format":"date-time","description":"End of the break (RFC 3339 instant, UTC offset required).","isRequired":true,"uniqueKey":"problem.vehicles.items.[INDEX].shifts.items.[INDEX].breaks.oneOf.0.items.[INDEX].oneOf.2.to","typeLabel":"string\u003cdate-time>"},"type":{"type":"string","description":"Discriminator: always `fixed`.","enum":["fixed"],"isRequired":true,"uniqueKey":"problem.vehicles.items.[INDEX].shifts.items.[INDEX].breaks.oneOf.0.items.[INDEX].oneOf.2.type","typeLabel":"enum\u003cstring>"},"id":{"oneOf":[{"type":"string","description":"Optional break id: 1 to 128 characters, unique within the shift.\nEchoed as `id` on the `break` stop that realises this break.","example":"lunch","maxLength":128,"minLength":1,"uniqueKey":"problem.vehicles.items.[INDEX].shifts.items.[INDEX].breaks.oneOf.0.items.[INDEX].oneOf.2.id.oneOf.0","typeLabel":"string"},{"type":"null","description":"Optional break id: 1 to 128 characters, unique within the shift.\nEchoed as `id` on the `break` stop that realises this break.","example":"lunch","maxLength":128,"minLength":1,"uniqueKey":"problem.vehicles.items.[INDEX].shifts.items.[INDEX].breaks.oneOf.0.items.[INDEX].oneOf.2.id.oneOf.1","typeLabel":"null"}],"uniqueKey":"problem.vehicles.items.[INDEX].shifts.items.[INDEX].breaks.oneOf.0.items.[INDEX].oneOf.2.id","typeLabel":"string | null"}},"additionalProperties":false,"uniqueKey":"problem.vehicles.items.[INDEX].shifts.items.[INDEX].breaks.oneOf.0.items.[INDEX].oneOf.2","typeLabel":"Fixed · object"}],"uniqueKey":"problem.vehicles.items.[INDEX].shifts.items.[INDEX].breaks.oneOf.0.items.[INDEX]","typeLabel":"Windowed · object | Triggered · object | Fixed · object"},"description":"Scheduled driver breaks within this shift — see the `Break` schema for\nthe supported forms. Injected breaks appear as `break` stops in the\nresponse routes.","uniqueKey":"problem.vehicles.items.[INDEX].shifts.items.[INDEX].breaks.oneOf.0","typeLabel":"(Windowed · object | Triggered · object | Fixed · object)[]"},{"type":"null","items":{"oneOf":[{"type":"object","title":"Windowed","description":"A scheduled break within a shift. Tagged by `type`:\n\n- `windowed`: a break of `duration_s` that starts inside its window.\n- `triggered`: a break of `duration_s` taken once drive or duty time\n passes `threshold_s` (the EU-561 mechanism).\n- `fixed`: a hard off-duty interval from `from` to `to`.\n\nBreaks are injected between stops and appear in the response as `break`\nstops, carrying the break's `id` when it has one.\n\nA `triggered` break always resets its accumulator after a qualifying break\nand is taken wherever the vehicle is: `resets_accumulator` and `location`\ndo not exist on it. A `windowed` break takes exactly one `time_window` and\nis also taken wherever the vehicle is: a `location` on it is HTTP 400\n`not_supported`.\n\nThere is no paid/unpaid cost accounting: a break's duration is never\nseparately priced, and no `paid` field exists on this schema — sending one\nis rejected as an unknown field (HTTP 400, `unknown_field`), like any other extra key.","required":["duration_s","time_window","type"],"example":{"duration_s":1800,"type":"triggered"},"properties":{"duration_s":{"type":"integer","format":"int32","description":"Break duration in seconds. Must be `> 0`.","minimum":1},"id":{"oneOf":[{"type":"string","description":"Optional break id: 1 to 128 characters, unique within the shift.\nEchoed as `id` on the `break` stop that realises this break.","example":"lunch","maxLength":128,"minLength":1},{"type":"null","description":"Optional break id: 1 to 128 characters, unique within the shift.\nEchoed as `id` on the `break` stop that realises this break.","example":"lunch","maxLength":128,"minLength":1}]},"location":{"oneOf":[{"type":"null","description":"Not supported on V3: a windowed break is taken wherever the\nvehicle is when it starts, so a `location` here is rejected with\nHTTP 400 `not_supported`. Set only by the V2 compatibility mapper."},{"type":"array","items":{"type":"number","format":"double"},"description":"Not supported on V3: a windowed break is taken wherever the\nvehicle is when it starts, so a `location` here is rejected with\nHTTP 400 `not_supported`. Set only by the V2 compatibility mapper.","maxItems":2,"minItems":2,"example":[3.725,51.05]}]},"time_window":{"type":"object","description":"The window bounding the break's **start**.","required":["from","to"],"properties":{"from":{"type":"string","format":"date-time","description":"Earliest break start (RFC 3339 instant, UTC offset required)."},"to":{"type":"string","format":"date-time","description":"Latest break start (RFC 3339 instant, UTC offset required)."}},"additionalProperties":false,"example":{"from":"2026-07-01T12:00:00+02:00","to":"2026-07-01T13:30:00+02:00"}},"type":{"type":"string","description":"Discriminator: always `windowed`.","enum":["windowed"]}},"additionalProperties":false},{"type":"object","title":"Triggered","description":"A scheduled break within a shift. Tagged by `type`:\n\n- `windowed`: a break of `duration_s` that starts inside its window.\n- `triggered`: a break of `duration_s` taken once drive or duty time\n passes `threshold_s` (the EU-561 mechanism).\n- `fixed`: a hard off-duty interval from `from` to `to`.\n\nBreaks are injected between stops and appear in the response as `break`\nstops, carrying the break's `id` when it has one.\n\nA `triggered` break always resets its accumulator after a qualifying break\nand is taken wherever the vehicle is: `resets_accumulator` and `location`\ndo not exist on it. A `windowed` break takes exactly one `time_window` and\nis also taken wherever the vehicle is: a `location` on it is HTTP 400\n`not_supported`.\n\nThere is no paid/unpaid cost accounting: a break's duration is never\nseparately priced, and no `paid` field exists on this schema — sending one\nis rejected as an unknown field (HTTP 400, `unknown_field`), like any other extra key.","required":["duration_s","after","threshold_s","type"],"example":{"after":"drive","duration_s":1800,"threshold_s":14400,"type":"triggered"},"properties":{"after":{"type":"string","description":"What to accumulate: drive time or duty time.","enum":["drive","duty"],"example":"drive"},"duration_s":{"type":"integer","format":"int32","description":"Break duration in seconds. Must be `> 0`.","minimum":1},"id":{"oneOf":[{"type":"string","description":"Optional break id: 1 to 128 characters, unique within the shift.\nEchoed as `id` on the `break` stop that realises this break.","example":"lunch","maxLength":128,"minLength":1},{"type":"null","description":"Optional break id: 1 to 128 characters, unique within the shift.\nEchoed as `id` on the `break` stop that realises this break.","example":"lunch","maxLength":128,"minLength":1}]},"threshold_s":{"type":"integer","format":"int64","description":"Trigger threshold in seconds (strict `>` — the break fires when the\naccumulator exceeds this). EU 561/2006 drive rule: `16200` (4 h 30).\nMust be `> 0` and fit in 32 bits.","example":14400,"maximum":2147483647,"minimum":1},"type":{"type":"string","description":"Discriminator: always `triggered`.","enum":["triggered"]}},"additionalProperties":false},{"type":"object","title":"Fixed","description":"A scheduled break within a shift. Tagged by `type`:\n\n- `windowed`: a break of `duration_s` that starts inside its window.\n- `triggered`: a break of `duration_s` taken once drive or duty time\n passes `threshold_s` (the EU-561 mechanism).\n- `fixed`: a hard off-duty interval from `from` to `to`.\n\nBreaks are injected between stops and appear in the response as `break`\nstops, carrying the break's `id` when it has one.\n\nA `triggered` break always resets its accumulator after a qualifying break\nand is taken wherever the vehicle is: `resets_accumulator` and `location`\ndo not exist on it. A `windowed` break takes exactly one `time_window` and\nis also taken wherever the vehicle is: a `location` on it is HTTP 400\n`not_supported`.\n\nThere is no paid/unpaid cost accounting: a break's duration is never\nseparately priced, and no `paid` field exists on this schema — sending one\nis rejected as an unknown field (HTTP 400, `unknown_field`), like any other extra key.","required":["from","to","type"],"example":{"type":"triggered"},"properties":{"from":{"type":"string","format":"date-time","description":"Start of the break (RFC 3339 instant, UTC offset required)."},"id":{"oneOf":[{"type":"string","description":"Optional break id: 1 to 128 characters, unique within the shift.\nEchoed as `id` on the `break` stop that realises this break.","example":"lunch","maxLength":128,"minLength":1},{"type":"null","description":"Optional break id: 1 to 128 characters, unique within the shift.\nEchoed as `id` on the `break` stop that realises this break.","example":"lunch","maxLength":128,"minLength":1}]},"to":{"type":"string","format":"date-time","description":"End of the break (RFC 3339 instant, UTC offset required)."},"type":{"type":"string","description":"Discriminator: always `fixed`.","enum":["fixed"]}},"additionalProperties":false}]},"description":"Scheduled driver breaks within this shift — see the `Break` schema for\nthe supported forms. Injected breaks appear as `break` stops in the\nresponse routes.","uniqueKey":"problem.vehicles.items.[INDEX].shifts.items.[INDEX].breaks.oneOf.1","typeLabel":"null"}],"uniqueKey":"problem.vehicles.items.[INDEX].shifts.items.[INDEX].breaks","typeLabel":"(Windowed · object | Triggered · object | Fixed · object)[] | null"},"capacity":{"oneOf":[{"type":"null","description":"Capacity for this shift only. Each dimension named here replaces the\nvehicle's value for that dimension; dimensions not named keep the\nvehicle's `capacity`.","uniqueKey":"problem.vehicles.items.[INDEX].shifts.items.[INDEX].capacity.oneOf.0","typeLabel":"null"},{"type":"object","description":"Capacity for this shift only. Each dimension named here replaces the\nvehicle's value for that dimension; dimensions not named keep the\nvehicle's `capacity`.","example":{"volume":2,"weight":20},"additionalProperties":{"type":"integer","format":"int32","minimum":0,"uniqueKey":"problem.vehicles.items.[INDEX].shifts.items.[INDEX].capacity.oneOf.1.additionalProperties","typeLabel":"integer\u003cint32>"},"uniqueKey":"problem.vehicles.items.[INDEX].shifts.items.[INDEX].capacity.oneOf.1","typeLabel":"object"}],"uniqueKey":"problem.vehicles.items.[INDEX].shifts.items.[INDEX].capacity","typeLabel":"null | object"},"costs":{"oneOf":[{"type":"null","description":"Costs for this shift only. Each field set here replaces the same\nfield of the vehicle's `costs` (or, when the vehicle does not set it,\nof `objective.costs`) for this shift; fields not set keep that value.\n`per_used_vehicle` is not accepted here: it prices the vehicle, not a\nshift.","uniqueKey":"problem.vehicles.items.[INDEX].shifts.items.[INDEX].costs.oneOf.0","typeLabel":"null"},{"type":"object","description":"Costs for this shift only. Each field set here replaces the same\nfield of the vehicle's `costs` (or, when the vehicle does not set it,\nof `objective.costs`) for this shift; fields not set keep that value.\n`per_used_vehicle` is not accepted here: it prices the vehicle, not a\nshift.","example":{"per_route":50,"per_travel_km":0.3},"properties":{"per_overtime_hour":{"oneOf":[{"type":"number","format":"double","description":"Per hour this route finishes past the shift's `to`, as\n`Costs.per_overtime_hour`.","example":0,"minimum":0,"uniqueKey":"problem.vehicles.items.[INDEX].shifts.items.[INDEX].costs.oneOf.1.per_overtime_hour.oneOf.0","typeLabel":"number\u003cdouble>"},{"type":"null","format":"double","description":"Per hour this route finishes past the shift's `to`, as\n`Costs.per_overtime_hour`.","example":0,"minimum":0,"uniqueKey":"problem.vehicles.items.[INDEX].shifts.items.[INDEX].costs.oneOf.1.per_overtime_hour.oneOf.1","typeLabel":"null"}],"uniqueKey":"problem.vehicles.items.[INDEX].shifts.items.[INDEX].costs.oneOf.1.per_overtime_hour","typeLabel":"number\u003cdouble> | null"},"per_route":{"oneOf":[{"type":"number","format":"double","description":"Flat charge for this used shift, as `Costs.per_route`.","example":50,"maximum":1000000000,"minimum":0,"uniqueKey":"problem.vehicles.items.[INDEX].shifts.items.[INDEX].costs.oneOf.1.per_route.oneOf.0","typeLabel":"number\u003cdouble>"},{"type":"null","format":"double","description":"Flat charge for this used shift, as `Costs.per_route`.","example":50,"maximum":1000000000,"minimum":0,"uniqueKey":"problem.vehicles.items.[INDEX].shifts.items.[INDEX].costs.oneOf.1.per_route.oneOf.1","typeLabel":"null"}],"uniqueKey":"problem.vehicles.items.[INDEX].shifts.items.[INDEX].costs.oneOf.1.per_route","typeLabel":"number\u003cdouble> | null"},"per_route_hour":{"oneOf":[{"type":"number","format":"double","description":"Per hour of this route's wall-clock span, as `Costs.per_route_hour`.","example":35,"minimum":0,"uniqueKey":"problem.vehicles.items.[INDEX].shifts.items.[INDEX].costs.oneOf.1.per_route_hour.oneOf.0","typeLabel":"number\u003cdouble>"},{"type":"null","format":"double","description":"Per hour of this route's wall-clock span, as `Costs.per_route_hour`.","example":35,"minimum":0,"uniqueKey":"problem.vehicles.items.[INDEX].shifts.items.[INDEX].costs.oneOf.1.per_route_hour.oneOf.1","typeLabel":"null"}],"uniqueKey":"problem.vehicles.items.[INDEX].shifts.items.[INDEX].costs.oneOf.1.per_route_hour","typeLabel":"number\u003cdouble> | null"},"per_travel_km":{"oneOf":[{"type":"number","format":"double","description":"Per kilometre driven on this shift, as `Costs.per_travel_km`.","example":0.2,"minimum":0,"uniqueKey":"problem.vehicles.items.[INDEX].shifts.items.[INDEX].costs.oneOf.1.per_travel_km.oneOf.0","typeLabel":"number\u003cdouble>"},{"type":"null","format":"double","description":"Per kilometre driven on this shift, as `Costs.per_travel_km`.","example":0.2,"minimum":0,"uniqueKey":"problem.vehicles.items.[INDEX].shifts.items.[INDEX].costs.oneOf.1.per_travel_km.oneOf.1","typeLabel":"null"}],"uniqueKey":"problem.vehicles.items.[INDEX].shifts.items.[INDEX].costs.oneOf.1.per_travel_km","typeLabel":"number\u003cdouble> | null"},"per_wait_hour":{"oneOf":[{"type":"number","format":"double","description":"Per hour spent waiting for a time window to open on this shift, as\n`Costs.per_wait_hour`.","example":0,"minimum":0,"uniqueKey":"problem.vehicles.items.[INDEX].shifts.items.[INDEX].costs.oneOf.1.per_wait_hour.oneOf.0","typeLabel":"number\u003cdouble>"},{"type":"null","format":"double","description":"Per hour spent waiting for a time window to open on this shift, as\n`Costs.per_wait_hour`.","example":0,"minimum":0,"uniqueKey":"problem.vehicles.items.[INDEX].shifts.items.[INDEX].costs.oneOf.1.per_wait_hour.oneOf.1","typeLabel":"null"}],"uniqueKey":"problem.vehicles.items.[INDEX].shifts.items.[INDEX].costs.oneOf.1.per_wait_hour","typeLabel":"number\u003cdouble> | null"}},"additionalProperties":false,"uniqueKey":"problem.vehicles.items.[INDEX].shifts.items.[INDEX].costs.oneOf.1","typeLabel":"object"}],"uniqueKey":"problem.vehicles.items.[INDEX].shifts.items.[INDEX].costs","typeLabel":"null | object"},"end":{"oneOf":[{"type":"null","description":"Where the shift ends. Absent = open end.","uniqueKey":"problem.vehicles.items.[INDEX].shifts.items.[INDEX].end.oneOf.0","typeLabel":"null"},{"type":"object","description":"Where the shift ends. Absent = open end.","required":["location"],"example":{"depot":"gent"},"properties":{"location":{"oneOf":[{"type":"null","description":"An inline place. Excludes `depot`.","isRequired":true,"uniqueKey":"problem.vehicles.items.[INDEX].shifts.items.[INDEX].end.oneOf.1.location.oneOf.0","typeLabel":"null"},{"type":"array","items":{"type":"number","format":"double","uniqueKey":"problem.vehicles.items.[INDEX].shifts.items.[INDEX].end.oneOf.1.location.oneOf.1.items.[INDEX]","typeLabel":"number\u003cdouble>"},"description":"An inline place. Excludes `depot`.","maxItems":2,"minItems":2,"example":[3.725,51.05],"isRequired":true,"uniqueKey":"problem.vehicles.items.[INDEX].shifts.items.[INDEX].end.oneOf.1.location.oneOf.1","typeLabel":"number\u003cdouble>[]"}],"isRequired":true,"uniqueKey":"problem.vehicles.items.[INDEX].shifts.items.[INDEX].end.oneOf.1.location","typeLabel":"null | number\u003cdouble>[]"},"depot":{"oneOf":[{"type":"string","description":"A `depots[].id`. Excludes `location`.","example":"gent","uniqueKey":"problem.vehicles.items.[INDEX].shifts.items.[INDEX].end.oneOf.1.depot.oneOf.0","typeLabel":"string"},{"type":"null","description":"A `depots[].id`. Excludes `location`.","example":"gent","uniqueKey":"problem.vehicles.items.[INDEX].shifts.items.[INDEX].end.oneOf.1.depot.oneOf.1","typeLabel":"null"}],"uniqueKey":"problem.vehicles.items.[INDEX].shifts.items.[INDEX].end.oneOf.1.depot","typeLabel":"string | null"},"service_duration_s":{"oneOf":[{"type":"integer","format":"int32","description":"Handling time in seconds at this end: the morning load at `start`, the\nevening unload at `end`. Overrides the depot's `service_duration_s`;\ndefault: the depot's value, or 0 for a `location` end. Not applied on\nfree travel (`free_start_travel`/`free_end_travel`). Not scaled by\n`service_factor`.\n\nThe unload must finish by the shift's `to` (or `to + max_overtime_s`):\na route whose unload would run past it is infeasible. A shift whose\nload and unload alone exceed it is rejected with HTTP 400.","example":600,"minimum":0,"uniqueKey":"problem.vehicles.items.[INDEX].shifts.items.[INDEX].end.oneOf.1.service_duration_s.oneOf.0","typeLabel":"integer\u003cint32>"},{"type":"null","format":"int32","description":"Handling time in seconds at this end: the morning load at `start`, the\nevening unload at `end`. Overrides the depot's `service_duration_s`;\ndefault: the depot's value, or 0 for a `location` end. Not applied on\nfree travel (`free_start_travel`/`free_end_travel`). Not scaled by\n`service_factor`.\n\nThe unload must finish by the shift's `to` (or `to + max_overtime_s`):\na route whose unload would run past it is infeasible. A shift whose\nload and unload alone exceed it is rejected with HTTP 400.","example":600,"minimum":0,"uniqueKey":"problem.vehicles.items.[INDEX].shifts.items.[INDEX].end.oneOf.1.service_duration_s.oneOf.1","typeLabel":"null"}],"uniqueKey":"problem.vehicles.items.[INDEX].shifts.items.[INDEX].end.oneOf.1.service_duration_s","typeLabel":"integer\u003cint32> | null"}},"additionalProperties":false,"uniqueKey":"problem.vehicles.items.[INDEX].shifts.items.[INDEX].end.oneOf.1","typeLabel":"object"},{"type":"object","description":"Where the shift ends. Absent = open end.","required":["depot"],"example":{"depot":"gent"},"properties":{"depot":{"oneOf":[{"type":"string","description":"A `depots[].id`. Excludes `location`.","example":"gent","isRequired":true,"uniqueKey":"problem.vehicles.items.[INDEX].shifts.items.[INDEX].end.oneOf.2.depot.oneOf.0","typeLabel":"string"},{"type":"null","description":"A `depots[].id`. Excludes `location`.","example":"gent","isRequired":true,"uniqueKey":"problem.vehicles.items.[INDEX].shifts.items.[INDEX].end.oneOf.2.depot.oneOf.1","typeLabel":"null"}],"isRequired":true,"uniqueKey":"problem.vehicles.items.[INDEX].shifts.items.[INDEX].end.oneOf.2.depot","typeLabel":"string | null"},"location":{"oneOf":[{"type":"null","description":"An inline place. Excludes `depot`.","uniqueKey":"problem.vehicles.items.[INDEX].shifts.items.[INDEX].end.oneOf.2.location.oneOf.0","typeLabel":"null"},{"type":"array","items":{"type":"number","format":"double","uniqueKey":"problem.vehicles.items.[INDEX].shifts.items.[INDEX].end.oneOf.2.location.oneOf.1.items.[INDEX]","typeLabel":"number\u003cdouble>"},"description":"An inline place. Excludes `depot`.","maxItems":2,"minItems":2,"example":[3.725,51.05],"uniqueKey":"problem.vehicles.items.[INDEX].shifts.items.[INDEX].end.oneOf.2.location.oneOf.1","typeLabel":"number\u003cdouble>[]"}],"uniqueKey":"problem.vehicles.items.[INDEX].shifts.items.[INDEX].end.oneOf.2.location","typeLabel":"null | number\u003cdouble>[]"},"service_duration_s":{"oneOf":[{"type":"integer","format":"int32","description":"Handling time in seconds at this end: the morning load at `start`, the\nevening unload at `end`. Overrides the depot's `service_duration_s`;\ndefault: the depot's value, or 0 for a `location` end. Not applied on\nfree travel (`free_start_travel`/`free_end_travel`). Not scaled by\n`service_factor`.\n\nThe unload must finish by the shift's `to` (or `to + max_overtime_s`):\na route whose unload would run past it is infeasible. A shift whose\nload and unload alone exceed it is rejected with HTTP 400.","example":600,"minimum":0,"uniqueKey":"problem.vehicles.items.[INDEX].shifts.items.[INDEX].end.oneOf.2.service_duration_s.oneOf.0","typeLabel":"integer\u003cint32>"},{"type":"null","format":"int32","description":"Handling time in seconds at this end: the morning load at `start`, the\nevening unload at `end`. Overrides the depot's `service_duration_s`;\ndefault: the depot's value, or 0 for a `location` end. Not applied on\nfree travel (`free_start_travel`/`free_end_travel`). Not scaled by\n`service_factor`.\n\nThe unload must finish by the shift's `to` (or `to + max_overtime_s`):\na route whose unload would run past it is infeasible. A shift whose\nload and unload alone exceed it is rejected with HTTP 400.","example":600,"minimum":0,"uniqueKey":"problem.vehicles.items.[INDEX].shifts.items.[INDEX].end.oneOf.2.service_duration_s.oneOf.1","typeLabel":"null"}],"uniqueKey":"problem.vehicles.items.[INDEX].shifts.items.[INDEX].end.oneOf.2.service_duration_s","typeLabel":"integer\u003cint32> | null"}},"additionalProperties":false,"uniqueKey":"problem.vehicles.items.[INDEX].shifts.items.[INDEX].end.oneOf.2","typeLabel":"object"}],"uniqueKey":"problem.vehicles.items.[INDEX].shifts.items.[INDEX].end","typeLabel":"null · object · object"},"free_end_travel":{"oneOf":[{"type":"boolean","description":"Symmetric to `free_start_travel` for travel from the last task to\n`end`; `true` without `end` is a 400.","example":false,"uniqueKey":"problem.vehicles.items.[INDEX].shifts.items.[INDEX].free_end_travel.oneOf.0","typeLabel":"boolean"},{"type":"null","description":"Symmetric to `free_start_travel` for travel from the last task to\n`end`; `true` without `end` is a 400.","example":false,"uniqueKey":"problem.vehicles.items.[INDEX].shifts.items.[INDEX].free_end_travel.oneOf.1","typeLabel":"null"}],"uniqueKey":"problem.vehicles.items.[INDEX].shifts.items.[INDEX].free_end_travel","typeLabel":"boolean | null"},"free_start_travel":{"oneOf":[{"type":"boolean","description":"When `true`, travel from `start` to the first task is free: it takes\nno time and costs nothing, and is left out of the route's distance\nand duration. The depot is still reported (a real stop, snapped\ncoordinate, departure time). Distinct from omitting `start` (an open\nroute, which drops the depot entirely). `true` without `start` is\nrejected with HTTP 400 `conflicting_fields`. Default `false`.","example":false,"uniqueKey":"problem.vehicles.items.[INDEX].shifts.items.[INDEX].free_start_travel.oneOf.0","typeLabel":"boolean"},{"type":"null","description":"When `true`, travel from `start` to the first task is free: it takes\nno time and costs nothing, and is left out of the route's distance\nand duration. The depot is still reported (a real stop, snapped\ncoordinate, departure time). Distinct from omitting `start` (an open\nroute, which drops the depot entirely). `true` without `start` is\nrejected with HTTP 400 `conflicting_fields`. Default `false`.","example":false,"uniqueKey":"problem.vehicles.items.[INDEX].shifts.items.[INDEX].free_start_travel.oneOf.1","typeLabel":"null"}],"uniqueKey":"problem.vehicles.items.[INDEX].shifts.items.[INDEX].free_start_travel","typeLabel":"boolean | null"},"initial_load":{"oneOf":[{"type":"null","description":"Load already on the vehicle at shift start (pre-loaded), per\ndimension. Occupies capacity on the first trip only — flushed at the\nfirst reload — so it reduces first-trip room per dimension, enforced\nby the per-trip capacity constraint. Not validated against\n`capacity` at request time: a value at or beyond capacity is\naccepted and surfaces as a solve-time result (jobs left unassigned,\nor deferred until the vehicle's first reload flushes it), not an\nHTTP 400. A dimension named here but absent from `capacity` behaves\nthe same as capacity `0` in that dimension.","uniqueKey":"problem.vehicles.items.[INDEX].shifts.items.[INDEX].initial_load.oneOf.0","typeLabel":"null"},{"type":"object","description":"Load already on the vehicle at shift start (pre-loaded), per\ndimension. Occupies capacity on the first trip only — flushed at the\nfirst reload — so it reduces first-trip room per dimension, enforced\nby the per-trip capacity constraint. Not validated against\n`capacity` at request time: a value at or beyond capacity is\naccepted and surfaces as a solve-time result (jobs left unassigned,\nor deferred until the vehicle's first reload flushes it), not an\nHTTP 400. A dimension named here but absent from `capacity` behaves\nthe same as capacity `0` in that dimension.","example":{"volume":2,"weight":20},"additionalProperties":{"type":"integer","format":"int32","minimum":0,"uniqueKey":"problem.vehicles.items.[INDEX].shifts.items.[INDEX].initial_load.oneOf.1.additionalProperties","typeLabel":"integer\u003cint32>"},"uniqueKey":"problem.vehicles.items.[INDEX].shifts.items.[INDEX].initial_load.oneOf.1","typeLabel":"object"}],"uniqueKey":"problem.vehicles.items.[INDEX].shifts.items.[INDEX].initial_load","typeLabel":"null | object"},"limits":{"oneOf":[{"type":"null","description":"Limits for this shift only. Each field set here replaces the\nvehicle's `limits` value; fields not set keep it.","uniqueKey":"problem.vehicles.items.[INDEX].shifts.items.[INDEX].limits.oneOf.0","typeLabel":"null"},{"type":"object","description":"Limits for this shift only. Each field set here replaces the\nvehicle's `limits` value; fields not set keep it.","example":{"max_stops":12},"properties":{"max_distance_m":{"oneOf":[{"type":"integer","format":"int64","description":"Hard cap on this shift's route distance, in metres. `0` to\n`2147483647`, as on the vehicle.","example":200000,"maximum":2147483647,"minimum":0,"uniqueKey":"problem.vehicles.items.[INDEX].shifts.items.[INDEX].limits.oneOf.1.max_distance_m.oneOf.0","typeLabel":"integer\u003cint64>"},{"type":"null","format":"int64","description":"Hard cap on this shift's route distance, in metres. `0` to\n`2147483647`, as on the vehicle.","example":200000,"maximum":2147483647,"minimum":0,"uniqueKey":"problem.vehicles.items.[INDEX].shifts.items.[INDEX].limits.oneOf.1.max_distance_m.oneOf.1","typeLabel":"null"}],"uniqueKey":"problem.vehicles.items.[INDEX].shifts.items.[INDEX].limits.oneOf.1.max_distance_m","typeLabel":"integer\u003cint64> | null"},"max_route_duration_s":{"oneOf":[{"type":"integer","format":"int64","description":"Hard cap on this shift's route span, in seconds. `0` to\n`2147483647`, as on the vehicle.","example":32400,"maximum":2147483647,"minimum":0,"uniqueKey":"problem.vehicles.items.[INDEX].shifts.items.[INDEX].limits.oneOf.1.max_route_duration_s.oneOf.0","typeLabel":"integer\u003cint64>"},{"type":"null","format":"int64","description":"Hard cap on this shift's route span, in seconds. `0` to\n`2147483647`, as on the vehicle.","example":32400,"maximum":2147483647,"minimum":0,"uniqueKey":"problem.vehicles.items.[INDEX].shifts.items.[INDEX].limits.oneOf.1.max_route_duration_s.oneOf.1","typeLabel":"null"}],"uniqueKey":"problem.vehicles.items.[INDEX].shifts.items.[INDEX].limits.oneOf.1.max_route_duration_s","typeLabel":"integer\u003cint64> | null"},"max_stops":{"oneOf":[{"type":"integer","format":"int32","description":"Maximum stops served in this shift; a job counts as one stop.\nStart, end, break and reload stops in `routes[].stops` do not count; a\nshipment counts as two stops.","example":50,"minimum":0,"uniqueKey":"problem.vehicles.items.[INDEX].shifts.items.[INDEX].limits.oneOf.1.max_stops.oneOf.0","typeLabel":"integer\u003cint32>"},{"type":"null","format":"int32","description":"Maximum stops served in this shift; a job counts as one stop.\nStart, end, break and reload stops in `routes[].stops` do not count; a\nshipment counts as two stops.","example":50,"minimum":0,"uniqueKey":"problem.vehicles.items.[INDEX].shifts.items.[INDEX].limits.oneOf.1.max_stops.oneOf.1","typeLabel":"null"}],"uniqueKey":"problem.vehicles.items.[INDEX].shifts.items.[INDEX].limits.oneOf.1.max_stops","typeLabel":"integer\u003cint32> | null"}},"additionalProperties":false,"uniqueKey":"problem.vehicles.items.[INDEX].shifts.items.[INDEX].limits.oneOf.1","typeLabel":"object"}],"uniqueKey":"problem.vehicles.items.[INDEX].shifts.items.[INDEX].limits","typeLabel":"null | object"},"max_overtime_s":{"oneOf":[{"type":"integer","format":"int32","description":"Maximum allowed overtime beyond `to` in seconds. Overtime is reached\nby working late, never by waiting: a `synchronized` or `time_lag`\nhold stops at `to`. Default: none (`to` is hard). Must be `>= 0`.","example":1800,"minimum":0,"uniqueKey":"problem.vehicles.items.[INDEX].shifts.items.[INDEX].max_overtime_s.oneOf.0","typeLabel":"integer\u003cint32>"},{"type":"null","format":"int32","description":"Maximum allowed overtime beyond `to` in seconds. Overtime is reached\nby working late, never by waiting: a `synchronized` or `time_lag`\nhold stops at `to`. Default: none (`to` is hard). Must be `>= 0`.","example":1800,"minimum":0,"uniqueKey":"problem.vehicles.items.[INDEX].shifts.items.[INDEX].max_overtime_s.oneOf.1","typeLabel":"null"}],"uniqueKey":"problem.vehicles.items.[INDEX].shifts.items.[INDEX].max_overtime_s","typeLabel":"integer\u003cint32> | null"},"max_trips":{"oneOf":[{"type":"integer","format":"int32","description":"Maximum trips (depot legs) in this shift, across all reload depots.\nCounts trips, not reloads: `trips = reloads_used + 1`. `max_trips: 1`\nmeans a single trip — reloads are permitted in `reloads` but the cap\nprevents ever using one. `reloads` present with `max_trips` absent\nmeans unlimited trips. A single reload depot can only be\nrevisited up to 8 times per shift regardless of `max_trips`;\na `max_trips` beyond that against one depot\nis accepted but the extra headroom is unreachable — list more than\none reload depot to raise the practical ceiling. `0` is rejected with\nHTTP 400 (the first trip already counts as trip 1).","example":2,"minimum":1,"uniqueKey":"problem.vehicles.items.[INDEX].shifts.items.[INDEX].max_trips.oneOf.0","typeLabel":"integer\u003cint32>"},{"type":"null","format":"int32","description":"Maximum trips (depot legs) in this shift, across all reload depots.\nCounts trips, not reloads: `trips = reloads_used + 1`. `max_trips: 1`\nmeans a single trip — reloads are permitted in `reloads` but the cap\nprevents ever using one. `reloads` present with `max_trips` absent\nmeans unlimited trips. A single reload depot can only be\nrevisited up to 8 times per shift regardless of `max_trips`;\na `max_trips` beyond that against one depot\nis accepted but the extra headroom is unreachable — list more than\none reload depot to raise the practical ceiling. `0` is rejected with\nHTTP 400 (the first trip already counts as trip 1).","example":2,"minimum":1,"uniqueKey":"problem.vehicles.items.[INDEX].shifts.items.[INDEX].max_trips.oneOf.1","typeLabel":"null"}],"uniqueKey":"problem.vehicles.items.[INDEX].shifts.items.[INDEX].max_trips","typeLabel":"integer\u003cint32> | null"},"reloads":{"oneOf":[{"type":"array","items":{"type":"string","uniqueKey":"problem.vehicles.items.[INDEX].shifts.items.[INDEX].reloads.oneOf.0.items.[INDEX]","typeLabel":"string"},"description":"Depots (by `depots[].id`, each at most once) the vehicle may return to\nmid-shift to reload and start a fresh trip. Each visit takes that\ndepot's `service_duration_s` and `per_reload`. Cap trips with\n`max_trips`.","uniqueKey":"problem.vehicles.items.[INDEX].shifts.items.[INDEX].reloads.oneOf.0","typeLabel":"string[]"},{"type":"null","items":{"type":"string"},"description":"Depots (by `depots[].id`, each at most once) the vehicle may return to\nmid-shift to reload and start a fresh trip. Each visit takes that\ndepot's `service_duration_s` and `per_reload`. Cap trips with\n`max_trips`.","uniqueKey":"problem.vehicles.items.[INDEX].shifts.items.[INDEX].reloads.oneOf.1","typeLabel":"null"}],"uniqueKey":"problem.vehicles.items.[INDEX].shifts.items.[INDEX].reloads","typeLabel":"string[] | null"},"serves_tags":{"oneOf":[{"type":"array","items":{"type":"string","uniqueKey":"problem.vehicles.items.[INDEX].shifts.items.[INDEX].serves_tags.oneOf.0.items.[INDEX]","typeLabel":"string"},"description":"Hard tag scope: when set (non-empty), this shift\nserves only tasks carrying at least one of these tags. Untagged tasks\nremain serveable by every shift. Absent or empty = serves everything.","uniqueKey":"problem.vehicles.items.[INDEX].shifts.items.[INDEX].serves_tags.oneOf.0","typeLabel":"string[]"},{"type":"null","items":{"type":"string"},"description":"Hard tag scope: when set (non-empty), this shift\nserves only tasks carrying at least one of these tags. Untagged tasks\nremain serveable by every shift. Absent or empty = serves everything.","uniqueKey":"problem.vehicles.items.[INDEX].shifts.items.[INDEX].serves_tags.oneOf.1","typeLabel":"null"}],"uniqueKey":"problem.vehicles.items.[INDEX].shifts.items.[INDEX].serves_tags","typeLabel":"string[] | null"},"service_factor":{"oneOf":[{"type":"number","format":"double","description":"Work-rate factor for this shift only. It REPLACES\n`vehicles[].service_factor` for the shift when set (absent = inherit the\nvehicle's value, which itself defaults to 1.0); a task's\n`service_factors[].factor` for this vehicle multiplies it.\n\nSame meaning, direction, and `[0.001, 5]` range as the vehicle-level\nfield: service time is DIVIDED by it, effective service time =\n`service_duration_s / service_factor`, so above `1` is faster. Use it\nwhen the same driver works at a different rate on different days — a\nmeasured per-day efficiency, a trainee shift, a two-person crew on\nFridays — instead of collapsing those days into one vehicle-level mean.\n\nScope is identical to the vehicle-level field: task\n`service_duration_s` only, never `setup_duration_s`, depot handling\n(`depots[].service_duration_s`, `start`/`end.service_duration_s`),\nwaiting, or breaks.","maximum":5,"minimum":0.001,"uniqueKey":"problem.vehicles.items.[INDEX].shifts.items.[INDEX].service_factor.oneOf.0","typeLabel":"number\u003cdouble>"},{"type":"null","format":"double","description":"Work-rate factor for this shift only. It REPLACES\n`vehicles[].service_factor` for the shift when set (absent = inherit the\nvehicle's value, which itself defaults to 1.0); a task's\n`service_factors[].factor` for this vehicle multiplies it.\n\nSame meaning, direction, and `[0.001, 5]` range as the vehicle-level\nfield: service time is DIVIDED by it, effective service time =\n`service_duration_s / service_factor`, so above `1` is faster. Use it\nwhen the same driver works at a different rate on different days — a\nmeasured per-day efficiency, a trainee shift, a two-person crew on\nFridays — instead of collapsing those days into one vehicle-level mean.\n\nScope is identical to the vehicle-level field: task\n`service_duration_s` only, never `setup_duration_s`, depot handling\n(`depots[].service_duration_s`, `start`/`end.service_duration_s`),\nwaiting, or breaks.","maximum":5,"minimum":0.001,"uniqueKey":"problem.vehicles.items.[INDEX].shifts.items.[INDEX].service_factor.oneOf.1","typeLabel":"null"}],"uniqueKey":"problem.vehicles.items.[INDEX].shifts.items.[INDEX].service_factor","typeLabel":"number\u003cdouble> | null"},"skills":{"oneOf":[{"type":"array","items":{"type":"object","description":"A capability a vehicle or shift provides, at a proficiency level:\n`{ \"name\": \"gas\", \"level\": 3 }`. Always an object; a bare string is\nrejected at parse.","required":["name"],"properties":{"name":{"type":"string","description":"Skill name.","example":"gas","isRequired":true,"uniqueKey":"problem.vehicles.items.[INDEX].shifts.items.[INDEX].skills.oneOf.0.items.[INDEX].name","typeLabel":"string"},"level":{"oneOf":[{"type":"integer","format":"int32","description":"Proficiency level, `>= 1`; absent = 1. Satisfies every job\nrequirement of this skill whose `min_level` is at most this value.","example":3,"minimum":1,"uniqueKey":"problem.vehicles.items.[INDEX].shifts.items.[INDEX].skills.oneOf.0.items.[INDEX].level.oneOf.0","typeLabel":"integer\u003cint32>"},{"type":"null","format":"int32","description":"Proficiency level, `>= 1`; absent = 1. Satisfies every job\nrequirement of this skill whose `min_level` is at most this value.","example":3,"minimum":1,"uniqueKey":"problem.vehicles.items.[INDEX].shifts.items.[INDEX].skills.oneOf.0.items.[INDEX].level.oneOf.1","typeLabel":"null"}],"uniqueKey":"problem.vehicles.items.[INDEX].shifts.items.[INDEX].skills.oneOf.0.items.[INDEX].level","typeLabel":"integer\u003cint32> | null"}},"additionalProperties":false,"example":{"level":3,"name":"gas"},"uniqueKey":"problem.vehicles.items.[INDEX].shifts.items.[INDEX].skills.oneOf.0.items.[INDEX]","typeLabel":"object"},"description":"Capabilities this shift provides, replacing the vehicle's `skills`\nfor this shift only (a technician covering another region on one\nday, a crew that only carries a certification on some shifts). A\njob's `required_skills` must all appear in the skills of the shift that\nserves it, at a level of at least the job's `min_level`. Same entry\nshape as `vehicles[].skills`. Absent = the vehicle's `skills`; `[]` =\nthis shift provides none.","uniqueKey":"problem.vehicles.items.[INDEX].shifts.items.[INDEX].skills.oneOf.0","typeLabel":"object[]"},{"type":"null","items":{"type":"object","description":"A capability a vehicle or shift provides, at a proficiency level:\n`{ \"name\": \"gas\", \"level\": 3 }`. Always an object; a bare string is\nrejected at parse.","required":["name"],"properties":{"level":{"oneOf":[{"type":"integer","format":"int32","description":"Proficiency level, `>= 1`; absent = 1. Satisfies every job\nrequirement of this skill whose `min_level` is at most this value.","example":3,"minimum":1},{"type":"null","format":"int32","description":"Proficiency level, `>= 1`; absent = 1. Satisfies every job\nrequirement of this skill whose `min_level` is at most this value.","example":3,"minimum":1}]},"name":{"type":"string","description":"Skill name.","example":"gas"}},"additionalProperties":false,"example":{"level":3,"name":"gas"}},"description":"Capabilities this shift provides, replacing the vehicle's `skills`\nfor this shift only (a technician covering another region on one\nday, a crew that only carries a certification on some shifts). A\njob's `required_skills` must all appear in the skills of the shift that\nserves it, at a level of at least the job's `min_level`. Same entry\nshape as `vehicles[].skills`. Absent = the vehicle's `skills`; `[]` =\nthis shift provides none.","uniqueKey":"problem.vehicles.items.[INDEX].shifts.items.[INDEX].skills.oneOf.1","typeLabel":"null"}],"uniqueKey":"problem.vehicles.items.[INDEX].shifts.items.[INDEX].skills","typeLabel":"object[] | null"},"start":{"oneOf":[{"type":"null","description":"Where the shift starts. Absent = open start.","uniqueKey":"problem.vehicles.items.[INDEX].shifts.items.[INDEX].start.oneOf.0","typeLabel":"null"},{"type":"object","description":"Where the shift starts. Absent = open start.","required":["location"],"example":{"depot":"gent"},"properties":{"location":{"oneOf":[{"type":"null","description":"An inline place. Excludes `depot`.","isRequired":true,"uniqueKey":"problem.vehicles.items.[INDEX].shifts.items.[INDEX].start.oneOf.1.location.oneOf.0","typeLabel":"null"},{"type":"array","items":{"type":"number","format":"double","uniqueKey":"problem.vehicles.items.[INDEX].shifts.items.[INDEX].start.oneOf.1.location.oneOf.1.items.[INDEX]","typeLabel":"number\u003cdouble>"},"description":"An inline place. Excludes `depot`.","maxItems":2,"minItems":2,"example":[3.725,51.05],"isRequired":true,"uniqueKey":"problem.vehicles.items.[INDEX].shifts.items.[INDEX].start.oneOf.1.location.oneOf.1","typeLabel":"number\u003cdouble>[]"}],"isRequired":true,"uniqueKey":"problem.vehicles.items.[INDEX].shifts.items.[INDEX].start.oneOf.1.location","typeLabel":"null | number\u003cdouble>[]"},"depot":{"oneOf":[{"type":"string","description":"A `depots[].id`. Excludes `location`.","example":"gent","uniqueKey":"problem.vehicles.items.[INDEX].shifts.items.[INDEX].start.oneOf.1.depot.oneOf.0","typeLabel":"string"},{"type":"null","description":"A `depots[].id`. Excludes `location`.","example":"gent","uniqueKey":"problem.vehicles.items.[INDEX].shifts.items.[INDEX].start.oneOf.1.depot.oneOf.1","typeLabel":"null"}],"uniqueKey":"problem.vehicles.items.[INDEX].shifts.items.[INDEX].start.oneOf.1.depot","typeLabel":"string | null"},"service_duration_s":{"oneOf":[{"type":"integer","format":"int32","description":"Handling time in seconds at this end: the morning load at `start`, the\nevening unload at `end`. Overrides the depot's `service_duration_s`;\ndefault: the depot's value, or 0 for a `location` end. Not applied on\nfree travel (`free_start_travel`/`free_end_travel`). Not scaled by\n`service_factor`.\n\nThe unload must finish by the shift's `to` (or `to + max_overtime_s`):\na route whose unload would run past it is infeasible. A shift whose\nload and unload alone exceed it is rejected with HTTP 400.","example":600,"minimum":0,"uniqueKey":"problem.vehicles.items.[INDEX].shifts.items.[INDEX].start.oneOf.1.service_duration_s.oneOf.0","typeLabel":"integer\u003cint32>"},{"type":"null","format":"int32","description":"Handling time in seconds at this end: the morning load at `start`, the\nevening unload at `end`. Overrides the depot's `service_duration_s`;\ndefault: the depot's value, or 0 for a `location` end. Not applied on\nfree travel (`free_start_travel`/`free_end_travel`). Not scaled by\n`service_factor`.\n\nThe unload must finish by the shift's `to` (or `to + max_overtime_s`):\na route whose unload would run past it is infeasible. A shift whose\nload and unload alone exceed it is rejected with HTTP 400.","example":600,"minimum":0,"uniqueKey":"problem.vehicles.items.[INDEX].shifts.items.[INDEX].start.oneOf.1.service_duration_s.oneOf.1","typeLabel":"null"}],"uniqueKey":"problem.vehicles.items.[INDEX].shifts.items.[INDEX].start.oneOf.1.service_duration_s","typeLabel":"integer\u003cint32> | null"}},"additionalProperties":false,"uniqueKey":"problem.vehicles.items.[INDEX].shifts.items.[INDEX].start.oneOf.1","typeLabel":"object"},{"type":"object","description":"Where the shift starts. Absent = open start.","required":["depot"],"example":{"depot":"gent"},"properties":{"depot":{"oneOf":[{"type":"string","description":"A `depots[].id`. Excludes `location`.","example":"gent","isRequired":true,"uniqueKey":"problem.vehicles.items.[INDEX].shifts.items.[INDEX].start.oneOf.2.depot.oneOf.0","typeLabel":"string"},{"type":"null","description":"A `depots[].id`. Excludes `location`.","example":"gent","isRequired":true,"uniqueKey":"problem.vehicles.items.[INDEX].shifts.items.[INDEX].start.oneOf.2.depot.oneOf.1","typeLabel":"null"}],"isRequired":true,"uniqueKey":"problem.vehicles.items.[INDEX].shifts.items.[INDEX].start.oneOf.2.depot","typeLabel":"string | null"},"location":{"oneOf":[{"type":"null","description":"An inline place. Excludes `depot`.","uniqueKey":"problem.vehicles.items.[INDEX].shifts.items.[INDEX].start.oneOf.2.location.oneOf.0","typeLabel":"null"},{"type":"array","items":{"type":"number","format":"double","uniqueKey":"problem.vehicles.items.[INDEX].shifts.items.[INDEX].start.oneOf.2.location.oneOf.1.items.[INDEX]","typeLabel":"number\u003cdouble>"},"description":"An inline place. Excludes `depot`.","maxItems":2,"minItems":2,"example":[3.725,51.05],"uniqueKey":"problem.vehicles.items.[INDEX].shifts.items.[INDEX].start.oneOf.2.location.oneOf.1","typeLabel":"number\u003cdouble>[]"}],"uniqueKey":"problem.vehicles.items.[INDEX].shifts.items.[INDEX].start.oneOf.2.location","typeLabel":"null | number\u003cdouble>[]"},"service_duration_s":{"oneOf":[{"type":"integer","format":"int32","description":"Handling time in seconds at this end: the morning load at `start`, the\nevening unload at `end`. Overrides the depot's `service_duration_s`;\ndefault: the depot's value, or 0 for a `location` end. Not applied on\nfree travel (`free_start_travel`/`free_end_travel`). Not scaled by\n`service_factor`.\n\nThe unload must finish by the shift's `to` (or `to + max_overtime_s`):\na route whose unload would run past it is infeasible. A shift whose\nload and unload alone exceed it is rejected with HTTP 400.","example":600,"minimum":0,"uniqueKey":"problem.vehicles.items.[INDEX].shifts.items.[INDEX].start.oneOf.2.service_duration_s.oneOf.0","typeLabel":"integer\u003cint32>"},{"type":"null","format":"int32","description":"Handling time in seconds at this end: the morning load at `start`, the\nevening unload at `end`. Overrides the depot's `service_duration_s`;\ndefault: the depot's value, or 0 for a `location` end. Not applied on\nfree travel (`free_start_travel`/`free_end_travel`). Not scaled by\n`service_factor`.\n\nThe unload must finish by the shift's `to` (or `to + max_overtime_s`):\na route whose unload would run past it is infeasible. A shift whose\nload and unload alone exceed it is rejected with HTTP 400.","example":600,"minimum":0,"uniqueKey":"problem.vehicles.items.[INDEX].shifts.items.[INDEX].start.oneOf.2.service_duration_s.oneOf.1","typeLabel":"null"}],"uniqueKey":"problem.vehicles.items.[INDEX].shifts.items.[INDEX].start.oneOf.2.service_duration_s","typeLabel":"integer\u003cint32> | null"}},"additionalProperties":false,"uniqueKey":"problem.vehicles.items.[INDEX].shifts.items.[INDEX].start.oneOf.2","typeLabel":"object"}],"uniqueKey":"problem.vehicles.items.[INDEX].shifts.items.[INDEX].start","typeLabel":"null · object · object"}},"additionalProperties":false,"example":{"end":{"location":[3.7174,51.0543]},"from":"2026-07-01T08:00:00+02:00","id":"mon","start":{"location":[3.7174,51.0543]},"to":"2026-07-01T17:00:00+02:00"},"uniqueKey":"problem.vehicles.items.[INDEX].shifts.items.[INDEX]","typeLabel":"object"},"description":"One or more working shifts. A vehicle without shifts is rejected with\nHTTP 400.","minItems":1,"isRequired":true,"uniqueKey":"problem.vehicles.items.[INDEX].shifts","typeLabel":"object[]"},"capacity":{"oneOf":[{"type":"null","description":"Named capacity dimensions.","uniqueKey":"problem.vehicles.items.[INDEX].capacity.oneOf.0","typeLabel":"null"},{"type":"object","description":"Named capacity dimensions.","example":{"volume":2,"weight":20},"additionalProperties":{"type":"integer","format":"int32","minimum":0,"uniqueKey":"problem.vehicles.items.[INDEX].capacity.oneOf.1.additionalProperties","typeLabel":"integer\u003cint32>"},"uniqueKey":"problem.vehicles.items.[INDEX].capacity.oneOf.1","typeLabel":"object"}],"uniqueKey":"problem.vehicles.items.[INDEX].capacity","typeLabel":"null | object"},"compatible_with":{"oneOf":[{"type":"array","items":{"type":"string","uniqueKey":"problem.vehicles.items.[INDEX].compatible_with.oneOf.0.items.[INDEX]","typeLabel":"string"},"description":"Vehicles this one may serve a `compatible_vehicles` relation's tasks\ntogether with, by id. Absent: any vehicle. A list is a veto, so a\none-sided list still binds both vehicles: two vehicles may share a\nrelation only if neither's list excludes the other. A vehicle always\npairs with itself and all its shifts count as one vehicle; to pair a\nvehicle with no other, list only its own id. An empty list is rejected\nwith HTTP 400 (it would read as \"everyone\" in a client that drops empty\narrays), and so is an id that names no vehicle. Inert unless a\n`compatible_vehicles` relation names tasks.","example":["v2","v3"],"minItems":1,"uniqueKey":"problem.vehicles.items.[INDEX].compatible_with.oneOf.0","typeLabel":"string[]"},{"type":"null","items":{"type":"string"},"description":"Vehicles this one may serve a `compatible_vehicles` relation's tasks\ntogether with, by id. Absent: any vehicle. A list is a veto, so a\none-sided list still binds both vehicles: two vehicles may share a\nrelation only if neither's list excludes the other. A vehicle always\npairs with itself and all its shifts count as one vehicle; to pair a\nvehicle with no other, list only its own id. An empty list is rejected\nwith HTTP 400 (it would read as \"everyone\" in a client that drops empty\narrays), and so is an id that names no vehicle. Inert unless a\n`compatible_vehicles` relation names tasks.","example":["v2","v3"],"minItems":1,"uniqueKey":"problem.vehicles.items.[INDEX].compatible_with.oneOf.1","typeLabel":"null"}],"uniqueKey":"problem.vehicles.items.[INDEX].compatible_with","typeLabel":"string[] | null"},"costs":{"oneOf":[{"type":"null","description":"This vehicle's costs. Each field set here replaces the same field of\n`objective.costs` for this vehicle; fields not set keep the fleet\nvalue. A shift's own `costs` replace these per field in turn.","uniqueKey":"problem.vehicles.items.[INDEX].costs.oneOf.0","typeLabel":"null"},{"type":"object","description":"This vehicle's costs. Each field set here replaces the same field of\n`objective.costs` for this vehicle; fields not set keep the fleet\nvalue. A shift's own `costs` replace these per field in turn.","example":{"per_route":50,"per_route_hour":35,"per_travel_km":0.2},"properties":{"per_overtime_hour":{"oneOf":[{"type":"number","format":"double","description":"Per hour a route finishes past its shift's `to` (possible only with\n`max_overtime_s`), reported in `score.components.overtime`, on top of\n`per_route_hour`. Default `0`: overtime is unpriced.","example":0,"minimum":0,"uniqueKey":"problem.vehicles.items.[INDEX].costs.oneOf.1.per_overtime_hour.oneOf.0","typeLabel":"number\u003cdouble>"},{"type":"null","format":"double","description":"Per hour a route finishes past its shift's `to` (possible only with\n`max_overtime_s`), reported in `score.components.overtime`, on top of\n`per_route_hour`. Default `0`: overtime is unpriced.","example":0,"minimum":0,"uniqueKey":"problem.vehicles.items.[INDEX].costs.oneOf.1.per_overtime_hour.oneOf.1","typeLabel":"null"}],"uniqueKey":"problem.vehicles.items.[INDEX].costs.oneOf.1.per_overtime_hour","typeLabel":"number\u003cdouble> | null"},"per_route":{"oneOf":[{"type":"number","format":"double","description":"Flat charge for each used shift (a route with at least one task),\nreported in `score.components.routes`. Default `0`. The higher it is,\nthe more travel the solver accepts to avoid opening another route. It\ncounts shifts, not vehicles: a vehicle that works five days pays it five\ntimes, so it does not prefer one vehicle on two shifts over two vehicles\non one shift each; use `per_used_vehicle` for that.","example":50,"maximum":1000000000,"minimum":0,"uniqueKey":"problem.vehicles.items.[INDEX].costs.oneOf.1.per_route.oneOf.0","typeLabel":"number\u003cdouble>"},{"type":"null","format":"double","description":"Flat charge for each used shift (a route with at least one task),\nreported in `score.components.routes`. Default `0`. The higher it is,\nthe more travel the solver accepts to avoid opening another route. It\ncounts shifts, not vehicles: a vehicle that works five days pays it five\ntimes, so it does not prefer one vehicle on two shifts over two vehicles\non one shift each; use `per_used_vehicle` for that.","example":50,"maximum":1000000000,"minimum":0,"uniqueKey":"problem.vehicles.items.[INDEX].costs.oneOf.1.per_route.oneOf.1","typeLabel":"null"}],"uniqueKey":"problem.vehicles.items.[INDEX].costs.oneOf.1.per_route","typeLabel":"number\u003cdouble> | null"},"per_route_hour":{"oneOf":[{"type":"number","format":"double","description":"Per hour of each route's wall-clock span (travel, service, waiting\nand breaks), reported in `score.components.time`. Default **35** at objective\nlevel; a vehicle or shift value inherits the fleet value.","example":35,"minimum":0,"uniqueKey":"problem.vehicles.items.[INDEX].costs.oneOf.1.per_route_hour.oneOf.0","typeLabel":"number\u003cdouble>"},{"type":"null","format":"double","description":"Per hour of each route's wall-clock span (travel, service, waiting\nand breaks), reported in `score.components.time`. Default **35** at objective\nlevel; a vehicle or shift value inherits the fleet value.","example":35,"minimum":0,"uniqueKey":"problem.vehicles.items.[INDEX].costs.oneOf.1.per_route_hour.oneOf.1","typeLabel":"null"}],"uniqueKey":"problem.vehicles.items.[INDEX].costs.oneOf.1.per_route_hour","typeLabel":"number\u003cdouble> | null"},"per_travel_km":{"oneOf":[{"type":"number","format":"double","description":"Per kilometre driven, reported in `score.components.distance`.\nDefault **0.20** at objective level; a vehicle or shift value inherits the\nfleet value.","example":0.2,"minimum":0,"uniqueKey":"problem.vehicles.items.[INDEX].costs.oneOf.1.per_travel_km.oneOf.0","typeLabel":"number\u003cdouble>"},{"type":"null","format":"double","description":"Per kilometre driven, reported in `score.components.distance`.\nDefault **0.20** at objective level; a vehicle or shift value inherits the\nfleet value.","example":0.2,"minimum":0,"uniqueKey":"problem.vehicles.items.[INDEX].costs.oneOf.1.per_travel_km.oneOf.1","typeLabel":"null"}],"uniqueKey":"problem.vehicles.items.[INDEX].costs.oneOf.1.per_travel_km","typeLabel":"number\u003cdouble> | null"},"per_used_vehicle":{"oneOf":[{"type":"number","format":"double","description":"Flat charge once per vehicle that serves at least one task, however\nmany of its shifts it works. Reported in `score.components.vehicles`.\nAdds to `per_route`: the vehicle's first used shift pays both, later\nshifts only `per_route`. Default `0`. Use it to minimise distinct\nvehicles; use `per_route` to price each working day. Not accepted on\n`shifts[].costs`. When any vehicle has a non-zero rate and any vehicle\nhas several shifts, the problem solves without decomposition.","example":400,"maximum":1000000000,"minimum":0,"uniqueKey":"problem.vehicles.items.[INDEX].costs.oneOf.1.per_used_vehicle.oneOf.0","typeLabel":"number\u003cdouble>"},{"type":"null","format":"double","description":"Flat charge once per vehicle that serves at least one task, however\nmany of its shifts it works. Reported in `score.components.vehicles`.\nAdds to `per_route`: the vehicle's first used shift pays both, later\nshifts only `per_route`. Default `0`. Use it to minimise distinct\nvehicles; use `per_route` to price each working day. Not accepted on\n`shifts[].costs`. When any vehicle has a non-zero rate and any vehicle\nhas several shifts, the problem solves without decomposition.","example":400,"maximum":1000000000,"minimum":0,"uniqueKey":"problem.vehicles.items.[INDEX].costs.oneOf.1.per_used_vehicle.oneOf.1","typeLabel":"null"}],"uniqueKey":"problem.vehicles.items.[INDEX].costs.oneOf.1.per_used_vehicle","typeLabel":"number\u003cdouble> | null"},"per_wait_hour":{"oneOf":[{"type":"number","format":"double","description":"Per hour spent waiting for a time window to open, reported in\n`score.components.waiting`, on top of `per_route_hour` (the span\nincludes the wait). Idle before a windowed break's window opens is\nreported in `wait_s` but not charged here. Default `0`.","example":0,"minimum":0,"uniqueKey":"problem.vehicles.items.[INDEX].costs.oneOf.1.per_wait_hour.oneOf.0","typeLabel":"number\u003cdouble>"},{"type":"null","format":"double","description":"Per hour spent waiting for a time window to open, reported in\n`score.components.waiting`, on top of `per_route_hour` (the span\nincludes the wait). Idle before a windowed break's window opens is\nreported in `wait_s` but not charged here. Default `0`.","example":0,"minimum":0,"uniqueKey":"problem.vehicles.items.[INDEX].costs.oneOf.1.per_wait_hour.oneOf.1","typeLabel":"null"}],"uniqueKey":"problem.vehicles.items.[INDEX].costs.oneOf.1.per_wait_hour","typeLabel":"number\u003cdouble> | null"}},"additionalProperties":false,"uniqueKey":"problem.vehicles.items.[INDEX].costs.oneOf.1","typeLabel":"object"}],"uniqueKey":"problem.vehicles.items.[INDEX].costs","typeLabel":"null | object"},"limits":{"oneOf":[{"type":"null","description":"Hard operating limits.","uniqueKey":"problem.vehicles.items.[INDEX].limits.oneOf.0","typeLabel":"null"},{"type":"object","description":"Hard operating limits.","example":{"max_distance_m":200000,"max_route_duration_s":32400},"properties":{"max_distance_m":{"oneOf":[{"type":"integer","format":"int64","description":"Hard maximum distance in metres. `0` to `2147483647`; a value\noutside that range is rejected with HTTP 400 `out_of_range`.","example":200000,"maximum":2147483647,"minimum":0,"uniqueKey":"problem.vehicles.items.[INDEX].limits.oneOf.1.max_distance_m.oneOf.0","typeLabel":"integer\u003cint64>"},{"type":"null","format":"int64","description":"Hard maximum distance in metres. `0` to `2147483647`; a value\noutside that range is rejected with HTTP 400 `out_of_range`.","example":200000,"maximum":2147483647,"minimum":0,"uniqueKey":"problem.vehicles.items.[INDEX].limits.oneOf.1.max_distance_m.oneOf.1","typeLabel":"null"}],"uniqueKey":"problem.vehicles.items.[INDEX].limits.oneOf.1.max_distance_m","typeLabel":"integer\u003cint64> | null"},"max_leg_travel_s":{"oneOf":[{"type":"integer","format":"int64","description":"Hard cap in seconds on any single travel leg of this vehicle's routes:\nthe `travel_s` reported on each stop, start-to-first-task and\nlast-task-to-`end` included. Travel only: setup, service and wait do\nnot count, and `speed_factor` applies first. A leg made free by\n`free_start_travel`/`free_end_travel`, or absent on an open start or\nend, is exempt. Absent = no cap. Must be > 0: `0` would make every\nleg too long rather than mean \"no cap\", so it is rejected with HTTP\n400 `out_of_range`, as is a value that does not fit in 32 bits. A\nbreach is reported as `max_leg_travel`.","example":3600,"maximum":2147483647,"minimum":1,"uniqueKey":"problem.vehicles.items.[INDEX].limits.oneOf.1.max_leg_travel_s.oneOf.0","typeLabel":"integer\u003cint64>"},{"type":"null","format":"int64","description":"Hard cap in seconds on any single travel leg of this vehicle's routes:\nthe `travel_s` reported on each stop, start-to-first-task and\nlast-task-to-`end` included. Travel only: setup, service and wait do\nnot count, and `speed_factor` applies first. A leg made free by\n`free_start_travel`/`free_end_travel`, or absent on an open start or\nend, is exempt. Absent = no cap. Must be > 0: `0` would make every\nleg too long rather than mean \"no cap\", so it is rejected with HTTP\n400 `out_of_range`, as is a value that does not fit in 32 bits. A\nbreach is reported as `max_leg_travel`.","example":3600,"maximum":2147483647,"minimum":1,"uniqueKey":"problem.vehicles.items.[INDEX].limits.oneOf.1.max_leg_travel_s.oneOf.1","typeLabel":"null"}],"uniqueKey":"problem.vehicles.items.[INDEX].limits.oneOf.1.max_leg_travel_s","typeLabel":"integer\u003cint64> | null"},"max_route_duration_s":{"oneOf":[{"type":"integer","format":"int64","description":"Hard maximum route duration in seconds: the whole-route span —\ntravel, service, and wait all count, depot load and unload included.\nThe same quantity as the response's `routes[].time.span_s`. `0` to\n`2147483647`; a value outside that range is rejected with HTTP 400\n`out_of_range`.","example":32400,"maximum":2147483647,"minimum":0,"uniqueKey":"problem.vehicles.items.[INDEX].limits.oneOf.1.max_route_duration_s.oneOf.0","typeLabel":"integer\u003cint64>"},{"type":"null","format":"int64","description":"Hard maximum route duration in seconds: the whole-route span —\ntravel, service, and wait all count, depot load and unload included.\nThe same quantity as the response's `routes[].time.span_s`. `0` to\n`2147483647`; a value outside that range is rejected with HTTP 400\n`out_of_range`.","example":32400,"maximum":2147483647,"minimum":0,"uniqueKey":"problem.vehicles.items.[INDEX].limits.oneOf.1.max_route_duration_s.oneOf.1","typeLabel":"null"}],"uniqueKey":"problem.vehicles.items.[INDEX].limits.oneOf.1.max_route_duration_s","typeLabel":"integer\u003cint64> | null"},"max_stops":{"oneOf":[{"type":"integer","format":"int32","description":"Maximum stops served per shift; a job counts as one stop.\nStart, end, break and reload stops in `routes[].stops` do not count; a\nshipment counts as two stops.","example":50,"minimum":0,"uniqueKey":"problem.vehicles.items.[INDEX].limits.oneOf.1.max_stops.oneOf.0","typeLabel":"integer\u003cint32>"},{"type":"null","format":"int32","description":"Maximum stops served per shift; a job counts as one stop.\nStart, end, break and reload stops in `routes[].stops` do not count; a\nshipment counts as two stops.","example":50,"minimum":0,"uniqueKey":"problem.vehicles.items.[INDEX].limits.oneOf.1.max_stops.oneOf.1","typeLabel":"null"}],"uniqueKey":"problem.vehicles.items.[INDEX].limits.oneOf.1.max_stops","typeLabel":"integer\u003cint32> | null"},"periods":{"type":"array","items":{"oneOf":[{"type":"object","description":"A cap on a vehicle's totals across every shift that starts in one period.\nSet exactly one of `every`, or `from` and `to`; and at least one maximum.","required":["every"],"example":{"every":"week","max_route_duration_s":144000,"max_stops":40},"properties":{"every":{"oneOf":[{"type":"null","description":"A recurring period: every `day`, or every `week` (weeks start Monday).","isRequired":true,"uniqueKey":"problem.vehicles.items.[INDEX].limits.oneOf.1.periods.items.[INDEX].oneOf.0.every.oneOf.0","typeLabel":"null"},{"type":"string","description":"A recurring period: every `day`, or every `week` (weeks start Monday).","enum":["day","week"],"isRequired":true,"uniqueKey":"problem.vehicles.items.[INDEX].limits.oneOf.1.periods.items.[INDEX].oneOf.0.every.oneOf.1","typeLabel":"enum\u003cstring>"}],"isRequired":true,"uniqueKey":"problem.vehicles.items.[INDEX].limits.oneOf.1.periods.items.[INDEX].oneOf.0.every","typeLabel":"null | enum\u003cstring>"},"from":{"oneOf":[{"type":"string","format":"date-time","description":"Start of one explicit period (RFC 3339, UTC offset required), with `to`. The window must\nhold at least one of the vehicle's shift starts; a period inside one\nshift is not supported.","example":"2026-10-05T00:00:00+02:00","uniqueKey":"problem.vehicles.items.[INDEX].limits.oneOf.1.periods.items.[INDEX].oneOf.0.from.oneOf.0","typeLabel":"string\u003cdate-time>"},{"type":"null","format":"date-time","description":"Start of one explicit period (RFC 3339, UTC offset required), with `to`. The window must\nhold at least one of the vehicle's shift starts; a period inside one\nshift is not supported.","example":"2026-10-05T00:00:00+02:00","uniqueKey":"problem.vehicles.items.[INDEX].limits.oneOf.1.periods.items.[INDEX].oneOf.0.from.oneOf.1","typeLabel":"null"}],"uniqueKey":"problem.vehicles.items.[INDEX].limits.oneOf.1.periods.items.[INDEX].oneOf.0.from","typeLabel":"string\u003cdate-time> | null"},"max_distance_m":{"oneOf":[{"type":"integer","format":"int64","description":"Hard cap on the summed distance driven, in metres. Must be `>= 0`.","example":900000,"minimum":0,"uniqueKey":"problem.vehicles.items.[INDEX].limits.oneOf.1.periods.items.[INDEX].oneOf.0.max_distance_m.oneOf.0","typeLabel":"integer\u003cint64>"},{"type":"null","format":"int64","description":"Hard cap on the summed distance driven, in metres. Must be `>= 0`.","example":900000,"minimum":0,"uniqueKey":"problem.vehicles.items.[INDEX].limits.oneOf.1.periods.items.[INDEX].oneOf.0.max_distance_m.oneOf.1","typeLabel":"null"}],"uniqueKey":"problem.vehicles.items.[INDEX].limits.oneOf.1.periods.items.[INDEX].oneOf.0.max_distance_m","typeLabel":"integer\u003cint64> | null"},"max_route_duration_s":{"oneOf":[{"type":"integer","format":"int64","description":"Hard cap on the summed route span of the period's shifts, measured as a\nshift's `max_route_duration_s` is, in seconds. An unused shift adds\nnothing. Must be `>= 0`.","example":144000,"minimum":0,"uniqueKey":"problem.vehicles.items.[INDEX].limits.oneOf.1.periods.items.[INDEX].oneOf.0.max_route_duration_s.oneOf.0","typeLabel":"integer\u003cint64>"},{"type":"null","format":"int64","description":"Hard cap on the summed route span of the period's shifts, measured as a\nshift's `max_route_duration_s` is, in seconds. An unused shift adds\nnothing. Must be `>= 0`.","example":144000,"minimum":0,"uniqueKey":"problem.vehicles.items.[INDEX].limits.oneOf.1.periods.items.[INDEX].oneOf.0.max_route_duration_s.oneOf.1","typeLabel":"null"}],"uniqueKey":"problem.vehicles.items.[INDEX].limits.oneOf.1.periods.items.[INDEX].oneOf.0.max_route_duration_s","typeLabel":"integer\u003cint64> | null"},"max_stops":{"oneOf":[{"type":"integer","format":"int32","description":"Hard cap on served stops across the period's shifts; a job counts as\none stop. Start, end, break and reload stops in `routes[].stops` do not\ncount; a shipment counts as two stops.","example":40,"minimum":0,"uniqueKey":"problem.vehicles.items.[INDEX].limits.oneOf.1.periods.items.[INDEX].oneOf.0.max_stops.oneOf.0","typeLabel":"integer\u003cint32>"},{"type":"null","format":"int32","description":"Hard cap on served stops across the period's shifts; a job counts as\none stop. Start, end, break and reload stops in `routes[].stops` do not\ncount; a shipment counts as two stops.","example":40,"minimum":0,"uniqueKey":"problem.vehicles.items.[INDEX].limits.oneOf.1.periods.items.[INDEX].oneOf.0.max_stops.oneOf.1","typeLabel":"null"}],"uniqueKey":"problem.vehicles.items.[INDEX].limits.oneOf.1.periods.items.[INDEX].oneOf.0.max_stops","typeLabel":"integer\u003cint32> | null"},"to":{"oneOf":[{"type":"string","format":"date-time","description":"End of one explicit period (RFC 3339, UTC offset required, exclusive), with `from`.","example":"2026-10-12T00:00:00+02:00","uniqueKey":"problem.vehicles.items.[INDEX].limits.oneOf.1.periods.items.[INDEX].oneOf.0.to.oneOf.0","typeLabel":"string\u003cdate-time>"},{"type":"null","format":"date-time","description":"End of one explicit period (RFC 3339, UTC offset required, exclusive), with `from`.","example":"2026-10-12T00:00:00+02:00","uniqueKey":"problem.vehicles.items.[INDEX].limits.oneOf.1.periods.items.[INDEX].oneOf.0.to.oneOf.1","typeLabel":"null"}],"uniqueKey":"problem.vehicles.items.[INDEX].limits.oneOf.1.periods.items.[INDEX].oneOf.0.to","typeLabel":"string\u003cdate-time> | null"}},"additionalProperties":false,"uniqueKey":"problem.vehicles.items.[INDEX].limits.oneOf.1.periods.items.[INDEX].oneOf.0","typeLabel":"object"},{"type":"object","description":"A cap on a vehicle's totals across every shift that starts in one period.\nSet exactly one of `every`, or `from` and `to`; and at least one maximum.","required":["from","to"],"example":{"every":"week","max_route_duration_s":144000,"max_stops":40},"properties":{"from":{"oneOf":[{"type":"string","format":"date-time","description":"Start of one explicit period (RFC 3339, UTC offset required), with `to`. The window must\nhold at least one of the vehicle's shift starts; a period inside one\nshift is not supported.","example":"2026-10-05T00:00:00+02:00","isRequired":true,"uniqueKey":"problem.vehicles.items.[INDEX].limits.oneOf.1.periods.items.[INDEX].oneOf.1.from.oneOf.0","typeLabel":"string\u003cdate-time>"},{"type":"null","format":"date-time","description":"Start of one explicit period (RFC 3339, UTC offset required), with `to`. The window must\nhold at least one of the vehicle's shift starts; a period inside one\nshift is not supported.","example":"2026-10-05T00:00:00+02:00","isRequired":true,"uniqueKey":"problem.vehicles.items.[INDEX].limits.oneOf.1.periods.items.[INDEX].oneOf.1.from.oneOf.1","typeLabel":"null"}],"isRequired":true,"uniqueKey":"problem.vehicles.items.[INDEX].limits.oneOf.1.periods.items.[INDEX].oneOf.1.from","typeLabel":"string\u003cdate-time> | null"},"to":{"oneOf":[{"type":"string","format":"date-time","description":"End of one explicit period (RFC 3339, UTC offset required, exclusive), with `from`.","example":"2026-10-12T00:00:00+02:00","isRequired":true,"uniqueKey":"problem.vehicles.items.[INDEX].limits.oneOf.1.periods.items.[INDEX].oneOf.1.to.oneOf.0","typeLabel":"string\u003cdate-time>"},{"type":"null","format":"date-time","description":"End of one explicit period (RFC 3339, UTC offset required, exclusive), with `from`.","example":"2026-10-12T00:00:00+02:00","isRequired":true,"uniqueKey":"problem.vehicles.items.[INDEX].limits.oneOf.1.periods.items.[INDEX].oneOf.1.to.oneOf.1","typeLabel":"null"}],"isRequired":true,"uniqueKey":"problem.vehicles.items.[INDEX].limits.oneOf.1.periods.items.[INDEX].oneOf.1.to","typeLabel":"string\u003cdate-time> | null"},"every":{"oneOf":[{"type":"null","description":"A recurring period: every `day`, or every `week` (weeks start Monday).","uniqueKey":"problem.vehicles.items.[INDEX].limits.oneOf.1.periods.items.[INDEX].oneOf.1.every.oneOf.0","typeLabel":"null"},{"type":"string","description":"A recurring period: every `day`, or every `week` (weeks start Monday).","enum":["day","week"],"uniqueKey":"problem.vehicles.items.[INDEX].limits.oneOf.1.periods.items.[INDEX].oneOf.1.every.oneOf.1","typeLabel":"enum\u003cstring>"}],"uniqueKey":"problem.vehicles.items.[INDEX].limits.oneOf.1.periods.items.[INDEX].oneOf.1.every","typeLabel":"null | enum\u003cstring>"},"max_distance_m":{"oneOf":[{"type":"integer","format":"int64","description":"Hard cap on the summed distance driven, in metres. Must be `>= 0`.","example":900000,"minimum":0,"uniqueKey":"problem.vehicles.items.[INDEX].limits.oneOf.1.periods.items.[INDEX].oneOf.1.max_distance_m.oneOf.0","typeLabel":"integer\u003cint64>"},{"type":"null","format":"int64","description":"Hard cap on the summed distance driven, in metres. Must be `>= 0`.","example":900000,"minimum":0,"uniqueKey":"problem.vehicles.items.[INDEX].limits.oneOf.1.periods.items.[INDEX].oneOf.1.max_distance_m.oneOf.1","typeLabel":"null"}],"uniqueKey":"problem.vehicles.items.[INDEX].limits.oneOf.1.periods.items.[INDEX].oneOf.1.max_distance_m","typeLabel":"integer\u003cint64> | null"},"max_route_duration_s":{"oneOf":[{"type":"integer","format":"int64","description":"Hard cap on the summed route span of the period's shifts, measured as a\nshift's `max_route_duration_s` is, in seconds. An unused shift adds\nnothing. Must be `>= 0`.","example":144000,"minimum":0,"uniqueKey":"problem.vehicles.items.[INDEX].limits.oneOf.1.periods.items.[INDEX].oneOf.1.max_route_duration_s.oneOf.0","typeLabel":"integer\u003cint64>"},{"type":"null","format":"int64","description":"Hard cap on the summed route span of the period's shifts, measured as a\nshift's `max_route_duration_s` is, in seconds. An unused shift adds\nnothing. Must be `>= 0`.","example":144000,"minimum":0,"uniqueKey":"problem.vehicles.items.[INDEX].limits.oneOf.1.periods.items.[INDEX].oneOf.1.max_route_duration_s.oneOf.1","typeLabel":"null"}],"uniqueKey":"problem.vehicles.items.[INDEX].limits.oneOf.1.periods.items.[INDEX].oneOf.1.max_route_duration_s","typeLabel":"integer\u003cint64> | null"},"max_stops":{"oneOf":[{"type":"integer","format":"int32","description":"Hard cap on served stops across the period's shifts; a job counts as\none stop. Start, end, break and reload stops in `routes[].stops` do not\ncount; a shipment counts as two stops.","example":40,"minimum":0,"uniqueKey":"problem.vehicles.items.[INDEX].limits.oneOf.1.periods.items.[INDEX].oneOf.1.max_stops.oneOf.0","typeLabel":"integer\u003cint32>"},{"type":"null","format":"int32","description":"Hard cap on served stops across the period's shifts; a job counts as\none stop. Start, end, break and reload stops in `routes[].stops` do not\ncount; a shipment counts as two stops.","example":40,"minimum":0,"uniqueKey":"problem.vehicles.items.[INDEX].limits.oneOf.1.periods.items.[INDEX].oneOf.1.max_stops.oneOf.1","typeLabel":"null"}],"uniqueKey":"problem.vehicles.items.[INDEX].limits.oneOf.1.periods.items.[INDEX].oneOf.1.max_stops","typeLabel":"integer\u003cint32> | null"}},"additionalProperties":false,"uniqueKey":"problem.vehicles.items.[INDEX].limits.oneOf.1.periods.items.[INDEX].oneOf.1","typeLabel":"object"}],"uniqueKey":"problem.vehicles.items.[INDEX].limits.oneOf.1.periods.items.[INDEX]","typeLabel":"object"},"description":"Hard caps on this vehicle's totals across all of its shifts in a day,\na week or an explicit window. Each shift counts toward the one\nperiod that contains its `from`, read in that shift's own UTC offset.\nA recurring period with none of the vehicle's shifts is skipped; an\nexplicit window with no shift start is a 400.","uniqueKey":"problem.vehicles.items.[INDEX].limits.oneOf.1.periods","typeLabel":"object[]"}},"additionalProperties":false,"uniqueKey":"problem.vehicles.items.[INDEX].limits.oneOf.1","typeLabel":"object"}],"uniqueKey":"problem.vehicles.items.[INDEX].limits","typeLabel":"null | object"},"preferred_tags":{"oneOf":[{"type":"array","items":{"type":"object","description":"A soft tag preference, priced.","required":["tag","violation_cost"],"properties":{"tag":{"type":"string","description":"Preferred tag.","example":"north","isRequired":true,"uniqueKey":"problem.vehicles.items.[INDEX].preferred_tags.oneOf.0.items.[INDEX].tag","typeLabel":"string"},"violation_cost":{"type":"number","format":"double","description":"Cost, in the objective's currency, incurred when a task without this\ntag is served. Must be finite and `>= 0`, and one vehicle's entries\nmust sum to at most 21474.83647 (a task lacking every tag pays them all).","example":25,"maximum":21474.83647,"minimum":0,"isRequired":true,"uniqueKey":"problem.vehicles.items.[INDEX].preferred_tags.oneOf.0.items.[INDEX].violation_cost","typeLabel":"number\u003cdouble>"}},"additionalProperties":false,"example":{"tag":"north","violation_cost":25},"uniqueKey":"problem.vehicles.items.[INDEX].preferred_tags.oneOf.0.items.[INDEX]","typeLabel":"object"},"description":"Soft tag preferences. Serving a task that does not\ncarry a preferred tag incurs that entry's `violation_cost`. Entries\napply independently: a task lacking several preferred tags incurs each\ncost.","uniqueKey":"problem.vehicles.items.[INDEX].preferred_tags.oneOf.0","typeLabel":"object[]"},{"type":"null","items":{"type":"object","description":"A soft tag preference, priced.","required":["tag","violation_cost"],"properties":{"tag":{"type":"string","description":"Preferred tag.","example":"north"},"violation_cost":{"type":"number","format":"double","description":"Cost, in the objective's currency, incurred when a task without this\ntag is served. Must be finite and `>= 0`, and one vehicle's entries\nmust sum to at most 21474.83647 (a task lacking every tag pays them all).","example":25,"maximum":21474.83647,"minimum":0}},"additionalProperties":false,"example":{"tag":"north","violation_cost":25}},"description":"Soft tag preferences. Serving a task that does not\ncarry a preferred tag incurs that entry's `violation_cost`. Entries\napply independently: a task lacking several preferred tags incurs each\ncost.","uniqueKey":"problem.vehicles.items.[INDEX].preferred_tags.oneOf.1","typeLabel":"null"}],"uniqueKey":"problem.vehicles.items.[INDEX].preferred_tags","typeLabel":"object[] | null"},"profile":{"oneOf":[{"type":"null","description":"Routing profile: `car` (default), `truck` or `bike` — selects the road\nnetwork and speeds behind this vehicle's travel times and distances.\nAny other value is rejected with HTTP 400.","uniqueKey":"problem.vehicles.items.[INDEX].profile.oneOf.0","typeLabel":"null"},{"type":"string","description":"Routing profile: `car` (default), `truck` or `bike` — selects the road\nnetwork and speeds behind this vehicle's travel times and distances.\nAny other value is rejected with HTTP 400.","enum":["car","truck","bike"],"example":"car","uniqueKey":"problem.vehicles.items.[INDEX].profile.oneOf.1","typeLabel":"enum\u003cstring>"}],"uniqueKey":"problem.vehicles.items.[INDEX].profile","typeLabel":"null | enum\u003cstring>"},"service_factor":{"oneOf":[{"type":"number","format":"double","description":"Work-rate multiplier for service time at stops (1.0 = base rate).\n\nSame direction as `speed_factor`: effective service time =\n`service_duration_s / service_factor`, so values > 1.0 model a driver who\nworks FASTER and spends less time at each stop, and \u003c 1.0 one who is\nslower. Use it for crew size, equipment, or experience — how quickly the\nwork gets done, as distinct from how fast the vehicle drives.\n\nApplies to job/stop `service_duration_s` only. Deliberately NOT applied\nto `setup_duration_s` (fixed arrival overhead such as parking),\ndepot handling (`depots[].service_duration_s`,\n`start`/`end.service_duration_s`), waiting time, or break durations.\n\nMust be in `[0.001, 5]`. Default 1.0. A shift's own `service_factor`\nreplaces it for that shift; a task's `service_factors[].factor` for\nthis vehicle multiplies whichever applies: effective service time =\n`service_duration_s / (shift_or_vehicle_factor * task_factor)`.\n\nV2's `durationModifier` went the other way (it MULTIPLIED duration,\n`0.8` = 20% faster); the V2 compatibility layer inverts it and sends it\nas the task's `service_factors[].factor = 1 / durationModifier`.","default":1,"maximum":5,"minimum":0.001,"uniqueKey":"problem.vehicles.items.[INDEX].service_factor.oneOf.0","typeLabel":"number\u003cdouble>"},{"type":"null","format":"double","description":"Work-rate multiplier for service time at stops (1.0 = base rate).\n\nSame direction as `speed_factor`: effective service time =\n`service_duration_s / service_factor`, so values > 1.0 model a driver who\nworks FASTER and spends less time at each stop, and \u003c 1.0 one who is\nslower. Use it for crew size, equipment, or experience — how quickly the\nwork gets done, as distinct from how fast the vehicle drives.\n\nApplies to job/stop `service_duration_s` only. Deliberately NOT applied\nto `setup_duration_s` (fixed arrival overhead such as parking),\ndepot handling (`depots[].service_duration_s`,\n`start`/`end.service_duration_s`), waiting time, or break durations.\n\nMust be in `[0.001, 5]`. Default 1.0. A shift's own `service_factor`\nreplaces it for that shift; a task's `service_factors[].factor` for\nthis vehicle multiplies whichever applies: effective service time =\n`service_duration_s / (shift_or_vehicle_factor * task_factor)`.\n\nV2's `durationModifier` went the other way (it MULTIPLIED duration,\n`0.8` = 20% faster); the V2 compatibility layer inverts it and sends it\nas the task's `service_factors[].factor = 1 / durationModifier`.","default":1,"maximum":5,"minimum":0.001,"uniqueKey":"problem.vehicles.items.[INDEX].service_factor.oneOf.1","typeLabel":"null"}],"uniqueKey":"problem.vehicles.items.[INDEX].service_factor","typeLabel":"number\u003cdouble> | null"},"skills":{"oneOf":[{"type":"array","items":{"type":"object","description":"A capability a vehicle or shift provides, at a proficiency level:\n`{ \"name\": \"gas\", \"level\": 3 }`. Always an object; a bare string is\nrejected at parse.","required":["name"],"properties":{"name":{"type":"string","description":"Skill name.","example":"gas","isRequired":true,"uniqueKey":"problem.vehicles.items.[INDEX].skills.oneOf.0.items.[INDEX].name","typeLabel":"string"},"level":{"oneOf":[{"type":"integer","format":"int32","description":"Proficiency level, `>= 1`; absent = 1. Satisfies every job\nrequirement of this skill whose `min_level` is at most this value.","example":3,"minimum":1,"uniqueKey":"problem.vehicles.items.[INDEX].skills.oneOf.0.items.[INDEX].level.oneOf.0","typeLabel":"integer\u003cint32>"},{"type":"null","format":"int32","description":"Proficiency level, `>= 1`; absent = 1. Satisfies every job\nrequirement of this skill whose `min_level` is at most this value.","example":3,"minimum":1,"uniqueKey":"problem.vehicles.items.[INDEX].skills.oneOf.0.items.[INDEX].level.oneOf.1","typeLabel":"null"}],"uniqueKey":"problem.vehicles.items.[INDEX].skills.oneOf.0.items.[INDEX].level","typeLabel":"integer\u003cint32> | null"}},"additionalProperties":false,"example":{"level":3,"name":"gas"},"uniqueKey":"problem.vehicles.items.[INDEX].skills.oneOf.0.items.[INDEX]","typeLabel":"object"},"description":"Capabilities the vehicle provides. A job's `required_skills` must all appear\nhere at a level of at least the job's `min_level`. Each entry is an\nobject `{ \"name\": ..., \"level\": N }` (`level` optional, default 1);\na bare string is rejected. A skill may appear once per list. Omitting\nthe field is the same as `[]`: the vehicle can only serve jobs that\nrequire no skills.","uniqueKey":"problem.vehicles.items.[INDEX].skills.oneOf.0","typeLabel":"object[]"},{"type":"null","items":{"type":"object","description":"A capability a vehicle or shift provides, at a proficiency level:\n`{ \"name\": \"gas\", \"level\": 3 }`. Always an object; a bare string is\nrejected at parse.","required":["name"],"properties":{"level":{"oneOf":[{"type":"integer","format":"int32","description":"Proficiency level, `>= 1`; absent = 1. Satisfies every job\nrequirement of this skill whose `min_level` is at most this value.","example":3,"minimum":1},{"type":"null","format":"int32","description":"Proficiency level, `>= 1`; absent = 1. Satisfies every job\nrequirement of this skill whose `min_level` is at most this value.","example":3,"minimum":1}]},"name":{"type":"string","description":"Skill name.","example":"gas"}},"additionalProperties":false,"example":{"level":3,"name":"gas"}},"description":"Capabilities the vehicle provides. A job's `required_skills` must all appear\nhere at a level of at least the job's `min_level`. Each entry is an\nobject `{ \"name\": ..., \"level\": N }` (`level` optional, default 1);\na bare string is rejected. A skill may appear once per list. Omitting\nthe field is the same as `[]`: the vehicle can only serve jobs that\nrequire no skills.","uniqueKey":"problem.vehicles.items.[INDEX].skills.oneOf.1","typeLabel":"null"}],"uniqueKey":"problem.vehicles.items.[INDEX].skills","typeLabel":"object[] | null"},"speed_factor":{"oneOf":[{"type":"number","format":"double","description":"Travel-speed multiplier (1.0 = base speed). Effective travel time =\n`base travel time / speed_factor`, so values > 1.0 model a faster\nvehicle and \u003c 1.0 a slower one. Must be in `[0.001, 5]`. Default 1.0.\n\nCovers driving only. Its companion `service_factor` scales the\nwork done at stops; the two are independent and share this direction and\nrange.","default":1,"maximum":5,"minimum":0.001,"uniqueKey":"problem.vehicles.items.[INDEX].speed_factor.oneOf.0","typeLabel":"number\u003cdouble>"},{"type":"null","format":"double","description":"Travel-speed multiplier (1.0 = base speed). Effective travel time =\n`base travel time / speed_factor`, so values > 1.0 model a faster\nvehicle and \u003c 1.0 a slower one. Must be in `[0.001, 5]`. Default 1.0.\n\nCovers driving only. Its companion `service_factor` scales the\nwork done at stops; the two are independent and share this direction and\nrange.","default":1,"maximum":5,"minimum":0.001,"uniqueKey":"problem.vehicles.items.[INDEX].speed_factor.oneOf.1","typeLabel":"null"}],"uniqueKey":"problem.vehicles.items.[INDEX].speed_factor","typeLabel":"number\u003cdouble> | null"},"workload_weight":{"oneOf":[{"type":"number","format":"double","description":"Share of the work this vehicle carries under `objective.workload_share`,\nrelative to the other vehicles. Default `1`; `0.5` carries half as much;\n`0` leaves the vehicle out of the balancing. `0` to `1000000`\n(HTTP 400 `out_of_range` outside that). Ignored when\n`objective.workload_share` is not set.","example":0.5,"maximum":1000000,"minimum":0,"uniqueKey":"problem.vehicles.items.[INDEX].workload_weight.oneOf.0","typeLabel":"number\u003cdouble>"},{"type":"null","format":"double","description":"Share of the work this vehicle carries under `objective.workload_share`,\nrelative to the other vehicles. Default `1`; `0.5` carries half as much;\n`0` leaves the vehicle out of the balancing. `0` to `1000000`\n(HTTP 400 `out_of_range` outside that). Ignored when\n`objective.workload_share` is not set.","example":0.5,"maximum":1000000,"minimum":0,"uniqueKey":"problem.vehicles.items.[INDEX].workload_weight.oneOf.1","typeLabel":"null"}],"uniqueKey":"problem.vehicles.items.[INDEX].workload_weight","typeLabel":"number\u003cdouble> | null"}},"additionalProperties":false,"example":{"capacity":{"volume":20,"weight":500},"id":"v1","profile":"car","shifts":[{"end":{"location":[3.7174,51.0543]},"from":"2026-07-01T08:00:00+02:00","id":"mon","start":{"location":[3.7174,51.0543]},"to":"2026-07-01T17:00:00+02:00"}],"skills":[{"name":"fridge"}]},"uniqueKey":"problem.vehicles.items.[INDEX]","typeLabel":"object"},"description":"Available vehicles: 1 to 2,000 (HTTP 400 otherwise).","maxItems":2000,"minItems":1,"isRequired":true,"uniqueKey":"problem.vehicles","typeLabel":"object[]"},"depots":{"type":"array","items":{"type":"object","description":"A depot: a place a shift starts from, ends at, or reloads at mid-shift,\nreferenced by `id` from `shifts[].start`, `shifts[].end` and\n`shifts[].reloads`. Each depot keeps its own handling time and reload cost.","required":["id","location"],"properties":{"id":{"type":"string","description":"Depot id: 1 to 128 characters, unique across `depots[]`.","example":"gent","maxLength":128,"minLength":1,"isRequired":true,"uniqueKey":"problem.depots.items.[INDEX].id","typeLabel":"string"},"location":{"type":"array","items":{"type":"number","format":"double","uniqueKey":"problem.depots.items.[INDEX].location.items.[INDEX]","typeLabel":"number\u003cdouble>"},"description":"Where the depot is.","examples":[[3.725,51.05]],"maxItems":2,"minItems":2,"isRequired":true,"uniqueKey":"problem.depots.items.[INDEX].location","typeLabel":"number\u003cdouble>[]"},"per_reload":{"oneOf":[{"type":"number","format":"double","description":"Money charged once per reload visit, in the objective's currency.\nDefault 0; at most `1e9`. A shift that only starts or ends here is not\ncharged.\n\nSet this when a reload has a real per-reload price the travel terms\ncannot see — typically the driver labour for the unload itself\n(`service_duration_s` × the hourly rate). Without it, a reload that\nconsumes only *slack* is free in the objective: it adds no route\nduration, so the solver will happily insert one to displace time that\n`objective.costs.per_wait_hour` would otherwise charge as idle, parking\nthe vehicle at a depot for no capacity benefit.","example":38.66,"maximum":1000000000,"minimum":0,"uniqueKey":"problem.depots.items.[INDEX].per_reload.oneOf.0","typeLabel":"number\u003cdouble>"},{"type":"null","format":"double","description":"Money charged once per reload visit, in the objective's currency.\nDefault 0; at most `1e9`. A shift that only starts or ends here is not\ncharged.\n\nSet this when a reload has a real per-reload price the travel terms\ncannot see — typically the driver labour for the unload itself\n(`service_duration_s` × the hourly rate). Without it, a reload that\nconsumes only *slack* is free in the objective: it adds no route\nduration, so the solver will happily insert one to displace time that\n`objective.costs.per_wait_hour` would otherwise charge as idle, parking\nthe vehicle at a depot for no capacity benefit.","example":38.66,"maximum":1000000000,"minimum":0,"uniqueKey":"problem.depots.items.[INDEX].per_reload.oneOf.1","typeLabel":"null"}],"uniqueKey":"problem.depots.items.[INDEX].per_reload","typeLabel":"number\u003cdouble> | null"},"service_duration_s":{"oneOf":[{"type":"integer","format":"int32","description":"Handling time in seconds per visit: the load before a shift that starts\nhere, the unload after a shift that ends here, and each reload. A shift\nend's own `service_duration_s` overrides it for that end. Default 0.\nThe unload after a shift must finish by that shift's `to` (or\n`to + max_overtime_s`). Not scaled by `service_factor`: this is\ndepot-side handling, not the driver's on-site work rate.","example":900,"minimum":0,"uniqueKey":"problem.depots.items.[INDEX].service_duration_s.oneOf.0","typeLabel":"integer\u003cint32>"},{"type":"null","format":"int32","description":"Handling time in seconds per visit: the load before a shift that starts\nhere, the unload after a shift that ends here, and each reload. A shift\nend's own `service_duration_s` overrides it for that end. Default 0.\nThe unload after a shift must finish by that shift's `to` (or\n`to + max_overtime_s`). Not scaled by `service_factor`: this is\ndepot-side handling, not the driver's on-site work rate.","example":900,"minimum":0,"uniqueKey":"problem.depots.items.[INDEX].service_duration_s.oneOf.1","typeLabel":"null"}],"uniqueKey":"problem.depots.items.[INDEX].service_duration_s","typeLabel":"integer\u003cint32> | null"}},"additionalProperties":false,"example":{"id":"gent","location":[3.7174,51.0543],"service_duration_s":900},"uniqueKey":"problem.depots.items.[INDEX]","typeLabel":"object"},"description":"Depots that shifts start from, end at, or reload at, by id.","uniqueKey":"problem.depots","typeLabel":"object[]"},"jobs":{"type":"array","items":{"type":"object","description":"A single-stop visit: one location served once (the `jobs[]` entry type).\nFor a pickup bound to a delivery on the same vehicle, use `shipments[]`.","required":["id"],"properties":{"id":{"type":"string","description":"Job id: 1 to 128 characters, unique across `jobs` + `shipments`.","example":"job-1","maxLength":128,"minLength":1,"isRequired":true,"uniqueKey":"problem.jobs.items.[INDEX].id","typeLabel":"string"},"assignment_costs":{"oneOf":[{"type":"array","items":{"type":"object","description":"Absolute price of serving one task on one vehicle.","required":["vehicle","cost"],"properties":{"cost":{"type":"number","format":"double","description":"Cost, in the objective's currency, incurred when this vehicle serves\nthe task. Must be finite and `>= 0`. A vehicle not listed costs `0`.","example":12.5,"maximum":21474.83647,"minimum":0,"isRequired":true,"uniqueKey":"problem.jobs.items.[INDEX].assignment_costs.oneOf.0.items.[INDEX].cost","typeLabel":"number\u003cdouble>"},"vehicle":{"type":"string","description":"Vehicle id; applies to every shift of that vehicle. An id that matches\nno vehicle, or a vehicle listed twice in one task's\n`assignment_costs`, is rejected with HTTP 400.","example":"v1","isRequired":true,"uniqueKey":"problem.jobs.items.[INDEX].assignment_costs.oneOf.0.items.[INDEX].vehicle","typeLabel":"string"}},"additionalProperties":false,"example":{"cost":12.5,"vehicle":"v1"},"uniqueKey":"problem.jobs.items.[INDEX].assignment_costs.oneOf.0.items.[INDEX]","typeLabel":"object"},"description":"Absolute price of serving this task on a given vehicle, in the\nobjective's currency. Charged once, when that vehicle (on any of its\nshifts) serves the task; unlisted vehicles cost nothing. Unlike\n`preferences`, which charges the vehicles that did NOT get the task,\nthis prices the vehicle that did, so a task rated badly everywhere is\nthe first one dropped when capacity runs out. It lives in the cost tier,\nbelow `priority`, and adds to `preferences`, `drop_cost` and travel.\nNot applied by decomposition: a problem that sets it solves monolithically.","uniqueKey":"problem.jobs.items.[INDEX].assignment_costs.oneOf.0","typeLabel":"object[]"},{"type":"null","items":{"type":"object","description":"Absolute price of serving one task on one vehicle.","required":["vehicle","cost"],"properties":{"cost":{"type":"number","format":"double","description":"Cost, in the objective's currency, incurred when this vehicle serves\nthe task. Must be finite and `>= 0`. A vehicle not listed costs `0`.","example":12.5,"maximum":21474.83647,"minimum":0},"vehicle":{"type":"string","description":"Vehicle id; applies to every shift of that vehicle. An id that matches\nno vehicle, or a vehicle listed twice in one task's\n`assignment_costs`, is rejected with HTTP 400.","example":"v1"}},"additionalProperties":false,"example":{"cost":12.5,"vehicle":"v1"}},"description":"Absolute price of serving this task on a given vehicle, in the\nobjective's currency. Charged once, when that vehicle (on any of its\nshifts) serves the task; unlisted vehicles cost nothing. Unlike\n`preferences`, which charges the vehicles that did NOT get the task,\nthis prices the vehicle that did, so a task rated badly everywhere is\nthe first one dropped when capacity runs out. It lives in the cost tier,\nbelow `priority`, and adds to `preferences`, `drop_cost` and travel.\nNot applied by decomposition: a problem that sets it solves monolithically.","uniqueKey":"problem.jobs.items.[INDEX].assignment_costs.oneOf.1","typeLabel":"null"}],"uniqueKey":"problem.jobs.items.[INDEX].assignment_costs","typeLabel":"object[] | null"},"break_interruptible":{"oneOf":[{"type":"boolean","description":"Whether a break may pause this job's service. With `true`, a `fixed`\nbreak, a `windowed` break or a duty-`triggered` break that falls\ninside the service pauses it: the work resumes when the break ends,\nthe job departs the break's length later, and the stop reports the\npaused seconds in `break_s`. A drive-`triggered` break never pauses a\njob (it counts driving time only). Default `false`: the whole service\nmoves after the break, or the break is taken before the job starts.","example":true,"uniqueKey":"problem.jobs.items.[INDEX].break_interruptible.oneOf.0","typeLabel":"boolean"},{"type":"null","description":"Whether a break may pause this job's service. With `true`, a `fixed`\nbreak, a `windowed` break or a duty-`triggered` break that falls\ninside the service pauses it: the work resumes when the break ends,\nthe job departs the break's length later, and the stop reports the\npaused seconds in `break_s`. A drive-`triggered` break never pauses a\njob (it counts driving time only). Default `false`: the whole service\nmoves after the break, or the break is taken before the job starts.","example":true,"uniqueKey":"problem.jobs.items.[INDEX].break_interruptible.oneOf.1","typeLabel":"null"}],"uniqueKey":"problem.jobs.items.[INDEX].break_interruptible","typeLabel":"boolean | null"},"delivery_load":{"oneOf":[{"type":"null","description":"Quantity delivered at this visit: comes off the vehicle here, having\nbeen loaded at a depot. Direction is carried by the field itself, never\nby sign — `delivery_load` values are non-negative magnitudes, like `pickup_load`.\n\nUnlike a shipment, nothing is picked up for it at another stop: the\ngoods are assumed already aboard from a depot, so the vehicle departs\nits trip carrying the sum of the trip's `delivery_load` quantities.\n\nAbsent or empty means no delivery at this visit.","uniqueKey":"problem.jobs.items.[INDEX].delivery_load.oneOf.0","typeLabel":"null"},{"type":"object","description":"Quantity delivered at this visit: comes off the vehicle here, having\nbeen loaded at a depot. Direction is carried by the field itself, never\nby sign — `delivery_load` values are non-negative magnitudes, like `pickup_load`.\n\nUnlike a shipment, nothing is picked up for it at another stop: the\ngoods are assumed already aboard from a depot, so the vehicle departs\nits trip carrying the sum of the trip's `delivery_load` quantities.\n\nAbsent or empty means no delivery at this visit.","example":{"volume":2,"weight":20},"additionalProperties":{"type":"integer","format":"int32","minimum":0,"uniqueKey":"problem.jobs.items.[INDEX].delivery_load.oneOf.1.additionalProperties","typeLabel":"integer\u003cint32>"},"uniqueKey":"problem.jobs.items.[INDEX].delivery_load.oneOf.1","typeLabel":"object"}],"uniqueKey":"problem.jobs.items.[INDEX].delivery_load","typeLabel":"null | object"},"drop_cost":{"oneOf":[{"type":"number","format":"double","description":"Drop **price** — what leaving this task unserved costs you, in the same\ncurrency as `objective.costs`, and the only way to make a task\ndroppable. Tasks without a `drop_cost` must be served.\n\nThis is money, not a priority: it enters the same cost the solver\nminimises, so the task is served only while serving it costs less than\ndropping it. Drop costs the plan chose to pay are reported in\n`score.components.drop_costs` and summed into `score.cost`.\n\nOn a shipment the drop cost applies to the pair, charged once.\n\nMust be finite, `>= 0` and at most `1e9`; combined with `priority` it\nis rejected with HTTP 400 (`conflicting_fields`). Also rejected with\nHTTP 400 (`not_supported`) while a positive `objective.per_delay_workday` is set,\nsince a droppable task could be dropped to avoid its delay charge.","example":25,"maximum":1000000000,"minimum":0,"uniqueKey":"problem.jobs.items.[INDEX].drop_cost.oneOf.0","typeLabel":"number\u003cdouble>"},{"type":"null","format":"double","description":"Drop **price** — what leaving this task unserved costs you, in the same\ncurrency as `objective.costs`, and the only way to make a task\ndroppable. Tasks without a `drop_cost` must be served.\n\nThis is money, not a priority: it enters the same cost the solver\nminimises, so the task is served only while serving it costs less than\ndropping it. Drop costs the plan chose to pay are reported in\n`score.components.drop_costs` and summed into `score.cost`.\n\nOn a shipment the drop cost applies to the pair, charged once.\n\nMust be finite, `>= 0` and at most `1e9`; combined with `priority` it\nis rejected with HTTP 400 (`conflicting_fields`). Also rejected with\nHTTP 400 (`not_supported`) while a positive `objective.per_delay_workday` is set,\nsince a droppable task could be dropped to avoid its delay charge.","example":25,"maximum":1000000000,"minimum":0,"uniqueKey":"problem.jobs.items.[INDEX].drop_cost.oneOf.1","typeLabel":"null"}],"uniqueKey":"problem.jobs.items.[INDEX].drop_cost","typeLabel":"number\u003cdouble> | null"},"eligible_vehicles":{"oneOf":[{"type":"null","description":"Hard vehicle allow/exclude. A request may use at most 256 distinct\npermitted-vehicle sets (after resolving `allowed`/`excluded`) across\nall jobs and shipments (HTTP 400 `limit_exceeded` beyond that).","uniqueKey":"problem.jobs.items.[INDEX].eligible_vehicles.oneOf.0","typeLabel":"null"},{"type":"object","description":"Hard vehicle allow/exclude. A request may use at most 256 distinct\npermitted-vehicle sets (after resolving `allowed`/`excluded`) across\nall jobs and shipments (HTTP 400 `limit_exceeded` beyond that).","example":{"allowed":["v1","v2"]},"properties":{"allowed":{"oneOf":[{"type":"array","items":{"type":"string","uniqueKey":"problem.jobs.items.[INDEX].eligible_vehicles.oneOf.1.allowed.oneOf.0.items.[INDEX]","typeLabel":"string"},"description":"Hard whitelist of vehicle ids. Omit = all vehicles allowed. An empty\nlist, or an id that names no vehicle, is rejected with HTTP 400.","minItems":1,"uniqueKey":"problem.jobs.items.[INDEX].eligible_vehicles.oneOf.1.allowed.oneOf.0","typeLabel":"string[]"},{"type":"null","items":{"type":"string"},"description":"Hard whitelist of vehicle ids. Omit = all vehicles allowed. An empty\nlist, or an id that names no vehicle, is rejected with HTTP 400.","minItems":1,"uniqueKey":"problem.jobs.items.[INDEX].eligible_vehicles.oneOf.1.allowed.oneOf.1","typeLabel":"null"}],"uniqueKey":"problem.jobs.items.[INDEX].eligible_vehicles.oneOf.1.allowed","typeLabel":"string[] | null"},"excluded":{"oneOf":[{"type":"array","items":{"type":"string","uniqueKey":"problem.jobs.items.[INDEX].eligible_vehicles.oneOf.1.excluded.oneOf.0.items.[INDEX]","typeLabel":"string"},"description":"Hard blacklist of vehicle ids. Mutually exclusive with `allowed`. An\nid that names no vehicle is rejected with HTTP 400.","uniqueKey":"problem.jobs.items.[INDEX].eligible_vehicles.oneOf.1.excluded.oneOf.0","typeLabel":"string[]"},{"type":"null","items":{"type":"string"},"description":"Hard blacklist of vehicle ids. Mutually exclusive with `allowed`. An\nid that names no vehicle is rejected with HTTP 400.","uniqueKey":"problem.jobs.items.[INDEX].eligible_vehicles.oneOf.1.excluded.oneOf.1","typeLabel":"null"}],"uniqueKey":"problem.jobs.items.[INDEX].eligible_vehicles.oneOf.1.excluded","typeLabel":"string[] | null"}},"additionalProperties":false,"uniqueKey":"problem.jobs.items.[INDEX].eligible_vehicles.oneOf.1","typeLabel":"object"}],"uniqueKey":"problem.jobs.items.[INDEX].eligible_vehicles","typeLabel":"null | object"},"location":{"oneOf":[{"type":"null","description":"Where this visit happens. Omit for a \"virtual\" (location-less) job:\nit still has service duration, time windows, load, and skills, but\nrequires no travel — the vehicle's position doesn't change when it\nserves one. Virtual and located jobs may be mixed freely in the same\nrequest and route. A virtual job's stop in the solution response\nreports the resolved location of its nearest real (located)\nneighbor in the route — the predecessor when there is one, otherwise\nthe successor — so it is `null` only on a route that has no located\nstop at all (an all-virtual route on an open-start/open-end shift).\nA shipment's legs still require a `location`.","uniqueKey":"problem.jobs.items.[INDEX].location.oneOf.0","typeLabel":"null"},{"type":"array","items":{"type":"number","format":"double","uniqueKey":"problem.jobs.items.[INDEX].location.oneOf.1.items.[INDEX]","typeLabel":"number\u003cdouble>"},"description":"Where this visit happens. Omit for a \"virtual\" (location-less) job:\nit still has service duration, time windows, load, and skills, but\nrequires no travel — the vehicle's position doesn't change when it\nserves one. Virtual and located jobs may be mixed freely in the same\nrequest and route. A virtual job's stop in the solution response\nreports the resolved location of its nearest real (located)\nneighbor in the route — the predecessor when there is one, otherwise\nthe successor — so it is `null` only on a route that has no located\nstop at all (an all-virtual route on an open-start/open-end shift).\nA shipment's legs still require a `location`.","maxItems":2,"minItems":2,"example":[3.725,51.05],"uniqueKey":"problem.jobs.items.[INDEX].location.oneOf.1","typeLabel":"number\u003cdouble>[]"}],"uniqueKey":"problem.jobs.items.[INDEX].location","typeLabel":"null | number\u003cdouble>[]"},"pickup_load":{"oneOf":[{"type":"null","description":"Quantity picked up at this visit: goes onto the vehicle here and stays\naboard until the route ends or reloads. Non-negative magnitudes per\nnamed dimension. A swap that collects one quantity and drops off\nanother at the same address is one job with both `pickup_load` and\n`delivery_load`.","uniqueKey":"problem.jobs.items.[INDEX].pickup_load.oneOf.0","typeLabel":"null"},{"type":"object","description":"Quantity picked up at this visit: goes onto the vehicle here and stays\naboard until the route ends or reloads. Non-negative magnitudes per\nnamed dimension. A swap that collects one quantity and drops off\nanother at the same address is one job with both `pickup_load` and\n`delivery_load`.","example":{"volume":2,"weight":20},"additionalProperties":{"type":"integer","format":"int32","minimum":0,"uniqueKey":"problem.jobs.items.[INDEX].pickup_load.oneOf.1.additionalProperties","typeLabel":"integer\u003cint32>"},"uniqueKey":"problem.jobs.items.[INDEX].pickup_load.oneOf.1","typeLabel":"object"}],"uniqueKey":"problem.jobs.items.[INDEX].pickup_load","typeLabel":"null | object"},"preferences":{"oneOf":[{"type":"array","items":{"type":"object","description":"A soft vehicle affinity preference, priced.","required":["vehicle","violation_cost"],"properties":{"vehicle":{"type":"string","description":"Preferred vehicle id. An id that names no vehicle, or a vehicle listed\ntwice in one task's `preferences`, is rejected with HTTP 400.","example":"v1","isRequired":true,"uniqueKey":"problem.jobs.items.[INDEX].preferences.oneOf.0.items.[INDEX].vehicle","typeLabel":"string"},"violation_cost":{"type":"number","format":"double","description":"Cost, in the objective's currency, incurred when a different vehicle\nserves the job. Must be finite and `>= 0`.","example":50,"maximum":21474.83647,"minimum":0,"isRequired":true,"uniqueKey":"problem.jobs.items.[INDEX].preferences.oneOf.0.items.[INDEX].violation_cost","typeLabel":"number\u003cdouble>"}},"additionalProperties":false,"example":{"vehicle":"v1","violation_cost":50},"uniqueKey":"problem.jobs.items.[INDEX].preferences.oneOf.0.items.[INDEX]","typeLabel":"object"},"description":"Soft vehicle affinity preferences, priced. Each entry is independent:\na job listing several preferred vehicles it doesn't get pays each\none's `violation_cost` (compounding, the same rule as a vehicle's\n`preferred_tags`).","uniqueKey":"problem.jobs.items.[INDEX].preferences.oneOf.0","typeLabel":"object[]"},{"type":"null","items":{"type":"object","description":"A soft vehicle affinity preference, priced.","required":["vehicle","violation_cost"],"properties":{"vehicle":{"type":"string","description":"Preferred vehicle id. An id that names no vehicle, or a vehicle listed\ntwice in one task's `preferences`, is rejected with HTTP 400.","example":"v1"},"violation_cost":{"type":"number","format":"double","description":"Cost, in the objective's currency, incurred when a different vehicle\nserves the job. Must be finite and `>= 0`.","example":50,"maximum":21474.83647,"minimum":0}},"additionalProperties":false,"example":{"vehicle":"v1","violation_cost":50}},"description":"Soft vehicle affinity preferences, priced. Each entry is independent:\na job listing several preferred vehicles it doesn't get pays each\none's `violation_cost` (compounding, the same rule as a vehicle's\n`preferred_tags`).","uniqueKey":"problem.jobs.items.[INDEX].preferences.oneOf.1","typeLabel":"null"}],"uniqueKey":"problem.jobs.items.[INDEX].preferences","typeLabel":"object[] | null"},"priority":{"oneOf":[{"type":"integer","format":"int32","description":"Importance of a must-serve task when not all of them fit: the solver\nmaximises the summed `priority` of served tasks before any cost. `>= 1`,\ndefault `1` (maximise the count). A rank, not money — it never makes a\ntask droppable; use `drop_cost` for that. Both set is a 400.","example":3,"minimum":1,"uniqueKey":"problem.jobs.items.[INDEX].priority.oneOf.0","typeLabel":"integer\u003cint32>"},{"type":"null","format":"int32","description":"Importance of a must-serve task when not all of them fit: the solver\nmaximises the summed `priority` of served tasks before any cost. `>= 1`,\ndefault `1` (maximise the count). A rank, not money — it never makes a\ntask droppable; use `drop_cost` for that. Both set is a 400.","example":3,"minimum":1,"uniqueKey":"problem.jobs.items.[INDEX].priority.oneOf.1","typeLabel":"null"}],"uniqueKey":"problem.jobs.items.[INDEX].priority","typeLabel":"integer\u003cint32> | null"},"required_skills":{"oneOf":[{"type":"array","items":{"type":"object","description":"A hard skill requirement — the assigned vehicle must provide it.","required":["name"],"properties":{"name":{"type":"string","description":"Skill name the assigned vehicle must provide.","example":"fridge","isRequired":true,"uniqueKey":"problem.jobs.items.[INDEX].required_skills.oneOf.0.items.[INDEX].name","typeLabel":"string"},"min_level":{"oneOf":[{"type":"integer","format":"int32","description":"Minimum level the serving vehicle must hold for this skill (`>= 1`).\nAbsent = 1. A vehicle skill with no `level` holds level 1.","example":2,"minimum":1,"uniqueKey":"problem.jobs.items.[INDEX].required_skills.oneOf.0.items.[INDEX].min_level.oneOf.0","typeLabel":"integer\u003cint32>"},{"type":"null","format":"int32","description":"Minimum level the serving vehicle must hold for this skill (`>= 1`).\nAbsent = 1. A vehicle skill with no `level` holds level 1.","example":2,"minimum":1,"uniqueKey":"problem.jobs.items.[INDEX].required_skills.oneOf.0.items.[INDEX].min_level.oneOf.1","typeLabel":"null"}],"uniqueKey":"problem.jobs.items.[INDEX].required_skills.oneOf.0.items.[INDEX].min_level","typeLabel":"integer\u003cint32> | null"}},"additionalProperties":false,"example":{"name":"fridge"},"uniqueKey":"problem.jobs.items.[INDEX].required_skills.oneOf.0.items.[INDEX]","typeLabel":"object"},"description":"Hard skill requirements — the assigned vehicle must provide every one,\nat or above each requirement's `min_level`. A request may use at most\n256 distinct `(name, min_level)` pairs across all jobs and shipments\n(HTTP 400 `limit_exceeded` beyond that).","uniqueKey":"problem.jobs.items.[INDEX].required_skills.oneOf.0","typeLabel":"object[]"},{"type":"null","items":{"type":"object","description":"A hard skill requirement — the assigned vehicle must provide it.","required":["name"],"properties":{"min_level":{"oneOf":[{"type":"integer","format":"int32","description":"Minimum level the serving vehicle must hold for this skill (`>= 1`).\nAbsent = 1. A vehicle skill with no `level` holds level 1.","example":2,"minimum":1},{"type":"null","format":"int32","description":"Minimum level the serving vehicle must hold for this skill (`>= 1`).\nAbsent = 1. A vehicle skill with no `level` holds level 1.","example":2,"minimum":1}]},"name":{"type":"string","description":"Skill name the assigned vehicle must provide.","example":"fridge"}},"additionalProperties":false,"example":{"name":"fridge"}},"description":"Hard skill requirements — the assigned vehicle must provide every one,\nat or above each requirement's `min_level`. A request may use at most\n256 distinct `(name, min_level)` pairs across all jobs and shipments\n(HTTP 400 `limit_exceeded` beyond that).","uniqueKey":"problem.jobs.items.[INDEX].required_skills.oneOf.1","typeLabel":"null"}],"uniqueKey":"problem.jobs.items.[INDEX].required_skills","typeLabel":"object[] | null"},"service_duration_s":{"oneOf":[{"type":"integer","format":"int32","description":"On-site service time paid per job (seconds).\n\nThis is the nominal figure. The serving vehicle's `service_factor`\nscales it — the time actually scheduled is\n`service_duration_s / service_factor` — so the solution's\n`stops[].service_s` may differ from what you sent here. Default `0`;\na negative value is rejected with HTTP 400.","example":300,"minimum":0,"uniqueKey":"problem.jobs.items.[INDEX].service_duration_s.oneOf.0","typeLabel":"integer\u003cint32>"},{"type":"null","format":"int32","description":"On-site service time paid per job (seconds).\n\nThis is the nominal figure. The serving vehicle's `service_factor`\nscales it — the time actually scheduled is\n`service_duration_s / service_factor` — so the solution's\n`stops[].service_s` may differ from what you sent here. Default `0`;\na negative value is rejected with HTTP 400.","example":300,"minimum":0,"uniqueKey":"problem.jobs.items.[INDEX].service_duration_s.oneOf.1","typeLabel":"null"}],"uniqueKey":"problem.jobs.items.[INDEX].service_duration_s","typeLabel":"integer\u003cint32> | null"},"service_factors":{"oneOf":[{"type":"array","items":{"type":"object","description":"Per-vehicle work-rate override for one task's `service_duration_s`.","required":["vehicle","factor"],"properties":{"factor":{"type":"number","format":"double","description":"Work-rate factor of `vehicle` on this task. Service time is DIVIDED by\nit: above `1` the vehicle works faster here, below `1` slower; `1.0` is a\nno-op. It multiplies the vehicle's own rate (the shift's\n`service_factor` if set, else the vehicle's): effective service time =\n`service_duration_s / (shift_or_vehicle_factor * factor)`. Same\ndirection and `[0.001, 5]` range as `vehicles[].service_factor`. V2's\n`proficiency.durationModifier` multiplied duration instead; the V2\ncompatibility layer sends its inverse (`1 / durationModifier`) here.","example":1.25,"maximum":5,"minimum":0.001,"isRequired":true,"uniqueKey":"problem.jobs.items.[INDEX].service_factors.oneOf.0.items.[INDEX].factor","typeLabel":"number\u003cdouble>"},"vehicle":{"type":"string","description":"Vehicle id; applies to every shift of that vehicle.","example":"v1","isRequired":true,"uniqueKey":"problem.jobs.items.[INDEX].service_factors.oneOf.0.items.[INDEX].vehicle","typeLabel":"string"}},"additionalProperties":false,"example":{"factor":1.25,"vehicle":"v1"},"uniqueKey":"problem.jobs.items.[INDEX].service_factors.oneOf.0.items.[INDEX]","typeLabel":"object"},"description":"Per-vehicle work-rate factors for this task's `service_duration_s`,\nwhich is DIVIDED by the factor (above `1` = faster). Each multiplies\nthe serving vehicle's rate (the shift's `service_factor` if set, else\nthe vehicle's): effective service time = `service_duration_s /\n(shift_or_vehicle_factor * factor)`. On a shipment the factor scales\nboth legs. A vehicle not listed works at its own rate.","uniqueKey":"problem.jobs.items.[INDEX].service_factors.oneOf.0","typeLabel":"object[]"},{"type":"null","items":{"type":"object","description":"Per-vehicle work-rate override for one task's `service_duration_s`.","required":["vehicle","factor"],"properties":{"factor":{"type":"number","format":"double","description":"Work-rate factor of `vehicle` on this task. Service time is DIVIDED by\nit: above `1` the vehicle works faster here, below `1` slower; `1.0` is a\nno-op. It multiplies the vehicle's own rate (the shift's\n`service_factor` if set, else the vehicle's): effective service time =\n`service_duration_s / (shift_or_vehicle_factor * factor)`. Same\ndirection and `[0.001, 5]` range as `vehicles[].service_factor`. V2's\n`proficiency.durationModifier` multiplied duration instead; the V2\ncompatibility layer sends its inverse (`1 / durationModifier`) here.","example":1.25,"maximum":5,"minimum":0.001},"vehicle":{"type":"string","description":"Vehicle id; applies to every shift of that vehicle.","example":"v1"}},"additionalProperties":false,"example":{"factor":1.25,"vehicle":"v1"}},"description":"Per-vehicle work-rate factors for this task's `service_duration_s`,\nwhich is DIVIDED by the factor (above `1` = faster). Each multiplies\nthe serving vehicle's rate (the shift's `service_factor` if set, else\nthe vehicle's): effective service time = `service_duration_s /\n(shift_or_vehicle_factor * factor)`. On a shipment the factor scales\nboth legs. A vehicle not listed works at its own rate.","uniqueKey":"problem.jobs.items.[INDEX].service_factors.oneOf.1","typeLabel":"null"}],"uniqueKey":"problem.jobs.items.[INDEX].service_factors","typeLabel":"object[] | null"},"setup_duration_s":{"oneOf":[{"type":"integer","format":"int32","description":"Setup time paid once on arrival at a new location (seconds),\ndistinct from `service_duration_s`. Skipped when the immediate real\npredecessor in the route already sits at this location — co-located\nstops share one setup.\n\nNot scaled by the vehicle's `service_factor`: setup is fixed arrival\noverhead (parking, walking to the door), not the work itself.\nDefault `0`; a negative value is rejected with HTTP 400.","example":60,"minimum":0,"uniqueKey":"problem.jobs.items.[INDEX].setup_duration_s.oneOf.0","typeLabel":"integer\u003cint32>"},{"type":"null","format":"int32","description":"Setup time paid once on arrival at a new location (seconds),\ndistinct from `service_duration_s`. Skipped when the immediate real\npredecessor in the route already sits at this location — co-located\nstops share one setup.\n\nNot scaled by the vehicle's `service_factor`: setup is fixed arrival\noverhead (parking, walking to the door), not the work itself.\nDefault `0`; a negative value is rejected with HTTP 400.","example":60,"minimum":0,"uniqueKey":"problem.jobs.items.[INDEX].setup_duration_s.oneOf.1","typeLabel":"null"}],"uniqueKey":"problem.jobs.items.[INDEX].setup_duration_s","typeLabel":"integer\u003cint32> | null"},"tags":{"oneOf":[{"type":"array","items":{"type":"string","uniqueKey":"problem.jobs.items.[INDEX].tags.oneOf.0.items.[INDEX]","typeLabel":"string"},"description":"Free-form task labels (zones/territories, relation labels).\nUsed for `tag`/relation resolution and, when a shift scopes itself via\n`serves_tags` (hard ANY-overlap) or a vehicle prices them via\n`preferred_tags` (soft), for tag matching. ANY-overlap — contrast with\n`required_skills`, which requires ALL. Not capability matching on its own.\nA request may carry at most 256 distinct tags across all jobs and\nshipments (HTTP 400 `limit_exceeded` beyond that); vehicle-side tag\nlists do not count.","uniqueKey":"problem.jobs.items.[INDEX].tags.oneOf.0","typeLabel":"string[]"},{"type":"null","items":{"type":"string"},"description":"Free-form task labels (zones/territories, relation labels).\nUsed for `tag`/relation resolution and, when a shift scopes itself via\n`serves_tags` (hard ANY-overlap) or a vehicle prices them via\n`preferred_tags` (soft), for tag matching. ANY-overlap — contrast with\n`required_skills`, which requires ALL. Not capability matching on its own.\nA request may carry at most 256 distinct tags across all jobs and\nshipments (HTTP 400 `limit_exceeded` beyond that); vehicle-side tag\nlists do not count.","uniqueKey":"problem.jobs.items.[INDEX].tags.oneOf.1","typeLabel":"null"}],"uniqueKey":"problem.jobs.items.[INDEX].tags","typeLabel":"string[] | null"},"target":{"oneOf":[{"type":"null","description":"Soft target for this task, measured at its arrival (default) or\ndeparture. On a shipment it is measured on the **delivery** leg.","uniqueKey":"problem.jobs.items.[INDEX].target.oneOf.0","typeLabel":"null"},{"type":"object","description":"Soft target for this task, measured at its arrival (default) or\ndeparture. On a shipment it is measured on the **delivery** leg.","required":["at","per_late_hour"],"example":{"at":"2026-07-01T10:00:00+02:00","on":"arrival","per_late_hour":60},"properties":{"at":{"type":"string","format":"date-time","description":"Target instant (RFC 3339, UTC offset required) the `on` instant is measured against.","example":"2026-07-01T10:00:00+02:00","isRequired":true,"uniqueKey":"problem.jobs.items.[INDEX].target.oneOf.1.at","typeLabel":"string\u003cdate-time>"},"per_late_hour":{"type":"number","format":"double","description":"Cost, in the objective's currency, per hour of `on` beyond `at`\n(linear, prorated per second). Must be `> 0`; independent of\n`objective.per_late_hour` (which prices *time-window* lateness,\nnot a target point).","example":60,"maximum":21474.83647,"minimum":0.00001,"isRequired":true,"uniqueKey":"problem.jobs.items.[INDEX].target.oneOf.1.per_late_hour","typeLabel":"number\u003cdouble>"},"on":{"oneOf":[{"type":"null","description":"Which instant of the task is compared to `at`: `arrival` (default) or\n`departure`, the stop fields of the same names.","default":"arrival","uniqueKey":"problem.jobs.items.[INDEX].target.oneOf.1.on.oneOf.0","typeLabel":"null"},{"type":"string","description":"Which instant of the task is compared to `at`: `arrival` (default) or\n`departure`, the stop fields of the same names.","default":"arrival","enum":["arrival","departure"],"uniqueKey":"problem.jobs.items.[INDEX].target.oneOf.1.on.oneOf.1","typeLabel":"enum\u003cstring>"}],"uniqueKey":"problem.jobs.items.[INDEX].target.oneOf.1.on","typeLabel":"null | enum\u003cstring>"}},"additionalProperties":false,"uniqueKey":"problem.jobs.items.[INDEX].target.oneOf.1","typeLabel":"object"}],"uniqueKey":"problem.jobs.items.[INDEX].target","typeLabel":"null | object"},"time_windows":{"oneOf":[{"type":"array","items":{"type":"object","description":"A time window. Hard unless it (or `objective.per_late_hour`, for\nevery window) prices lateness.","required":["from","to"],"properties":{"from":{"type":"string","format":"date-time","description":"Earliest allowed start of service (RFC 3339 instant, UTC offset\nrequired). A vehicle that arrives earlier waits.","example":"2026-07-01T09:00:00+02:00","isRequired":true,"uniqueKey":"problem.jobs.items.[INDEX].time_windows.oneOf.0.items.[INDEX].from","typeLabel":"string\u003cdate-time>"},"to":{"type":"string","format":"date-time","description":"Latest allowed start of service (RFC 3339 instant, UTC offset\nrequired), measured from arrival plus any windowed break taken first\n(#1750 D1). Hard unless `per_late_hour` prices lateness.","example":"2026-07-01T12:00:00+02:00","isRequired":true,"uniqueKey":"problem.jobs.items.[INDEX].time_windows.oneOf.0.items.[INDEX].to","typeLabel":"string\u003cdate-time>"},"choice_cost":{"oneOf":[{"type":"number","format":"double","description":"Optional flat cost, in the objective's currency, added when this\njob/stop is served within THIS window rather than a free/cheaper\nalternative window on the same task. Absent = 0 (no charge). Every\nwindow in the list remains individually hard — a job must still land\nin *some* window — this only grades preference among the hard\nalternatives; it does not soften time-window feasibility. Must be\nfinite and `>= 0`, and requires at least 2 windows on the task. Once\nany window on the task carries a *nonzero* cost, that task's windows\nmust also be pairwise non-overlapping, and windows that only touch\ncount as overlapping (a task whose costs are all\n`0`/absent has its overlapping windows merged).\n\n**Cannot be combined with `objective.per_late_hour > 0`** — a\nnonzero `choice_cost` anywhere in the request alongside priced lateness\nis rejected with HTTP 400 (the two read opposite ways about which\nwindow was paid for). Choose one: priced alternative windows, or priced\nlateness.","maximum":21474.83647,"minimum":0,"uniqueKey":"problem.jobs.items.[INDEX].time_windows.oneOf.0.items.[INDEX].choice_cost.oneOf.0","typeLabel":"number\u003cdouble>"},{"type":"null","format":"double","description":"Optional flat cost, in the objective's currency, added when this\njob/stop is served within THIS window rather than a free/cheaper\nalternative window on the same task. Absent = 0 (no charge). Every\nwindow in the list remains individually hard — a job must still land\nin *some* window — this only grades preference among the hard\nalternatives; it does not soften time-window feasibility. Must be\nfinite and `>= 0`, and requires at least 2 windows on the task. Once\nany window on the task carries a *nonzero* cost, that task's windows\nmust also be pairwise non-overlapping, and windows that only touch\ncount as overlapping (a task whose costs are all\n`0`/absent has its overlapping windows merged).\n\n**Cannot be combined with `objective.per_late_hour > 0`** — a\nnonzero `choice_cost` anywhere in the request alongside priced lateness\nis rejected with HTTP 400 (the two read opposite ways about which\nwindow was paid for). Choose one: priced alternative windows, or priced\nlateness.","maximum":21474.83647,"minimum":0,"uniqueKey":"problem.jobs.items.[INDEX].time_windows.oneOf.0.items.[INDEX].choice_cost.oneOf.1","typeLabel":"null"}],"uniqueKey":"problem.jobs.items.[INDEX].time_windows.oneOf.0.items.[INDEX].choice_cost","typeLabel":"number\u003cdouble> | null"},"per_late_hour":{"oneOf":[{"type":"number","format":"double","description":"Makes this window soft on its late side: arriving after `to` is\nallowed and priced at this rate, in the objective's currency per hour\nlate, in place of `objective.per_late_hour` (and whether or not\nthat is set, so hard and soft windows can share one request). Must be\n`> 0`; omit it for a hard window. Only on a\ntask with exactly one window. Arriving early still waits for `from`.","example":60,"minimum":0.0006,"uniqueKey":"problem.jobs.items.[INDEX].time_windows.oneOf.0.items.[INDEX].per_late_hour.oneOf.0","typeLabel":"number\u003cdouble>"},{"type":"null","format":"double","description":"Makes this window soft on its late side: arriving after `to` is\nallowed and priced at this rate, in the objective's currency per hour\nlate, in place of `objective.per_late_hour` (and whether or not\nthat is set, so hard and soft windows can share one request). Must be\n`> 0`; omit it for a hard window. Only on a\ntask with exactly one window. Arriving early still waits for `from`.","example":60,"minimum":0.0006,"uniqueKey":"problem.jobs.items.[INDEX].time_windows.oneOf.0.items.[INDEX].per_late_hour.oneOf.1","typeLabel":"null"}],"uniqueKey":"problem.jobs.items.[INDEX].time_windows.oneOf.0.items.[INDEX].per_late_hour","typeLabel":"number\u003cdouble> | null"}},"additionalProperties":false,"example":{"choice_cost":15,"from":"2026-07-01T09:00:00+02:00","to":"2026-07-01T12:00:00+02:00"},"uniqueKey":"problem.jobs.items.[INDEX].time_windows.oneOf.0.items.[INDEX]","typeLabel":"object"},"description":"Time windows for this visit.","uniqueKey":"problem.jobs.items.[INDEX].time_windows.oneOf.0","typeLabel":"object[]"},{"type":"null","items":{"type":"object","description":"A time window. Hard unless it (or `objective.per_late_hour`, for\nevery window) prices lateness.","required":["from","to"],"properties":{"choice_cost":{"oneOf":[{"type":"number","format":"double","description":"Optional flat cost, in the objective's currency, added when this\njob/stop is served within THIS window rather than a free/cheaper\nalternative window on the same task. Absent = 0 (no charge). Every\nwindow in the list remains individually hard — a job must still land\nin *some* window — this only grades preference among the hard\nalternatives; it does not soften time-window feasibility. Must be\nfinite and `>= 0`, and requires at least 2 windows on the task. Once\nany window on the task carries a *nonzero* cost, that task's windows\nmust also be pairwise non-overlapping, and windows that only touch\ncount as overlapping (a task whose costs are all\n`0`/absent has its overlapping windows merged).\n\n**Cannot be combined with `objective.per_late_hour > 0`** — a\nnonzero `choice_cost` anywhere in the request alongside priced lateness\nis rejected with HTTP 400 (the two read opposite ways about which\nwindow was paid for). Choose one: priced alternative windows, or priced\nlateness.","maximum":21474.83647,"minimum":0},{"type":"null","format":"double","description":"Optional flat cost, in the objective's currency, added when this\njob/stop is served within THIS window rather than a free/cheaper\nalternative window on the same task. Absent = 0 (no charge). Every\nwindow in the list remains individually hard — a job must still land\nin *some* window — this only grades preference among the hard\nalternatives; it does not soften time-window feasibility. Must be\nfinite and `>= 0`, and requires at least 2 windows on the task. Once\nany window on the task carries a *nonzero* cost, that task's windows\nmust also be pairwise non-overlapping, and windows that only touch\ncount as overlapping (a task whose costs are all\n`0`/absent has its overlapping windows merged).\n\n**Cannot be combined with `objective.per_late_hour > 0`** — a\nnonzero `choice_cost` anywhere in the request alongside priced lateness\nis rejected with HTTP 400 (the two read opposite ways about which\nwindow was paid for). Choose one: priced alternative windows, or priced\nlateness.","maximum":21474.83647,"minimum":0}]},"from":{"type":"string","format":"date-time","description":"Earliest allowed start of service (RFC 3339 instant, UTC offset\nrequired). A vehicle that arrives earlier waits.","example":"2026-07-01T09:00:00+02:00"},"per_late_hour":{"oneOf":[{"type":"number","format":"double","description":"Makes this window soft on its late side: arriving after `to` is\nallowed and priced at this rate, in the objective's currency per hour\nlate, in place of `objective.per_late_hour` (and whether or not\nthat is set, so hard and soft windows can share one request). Must be\n`> 0`; omit it for a hard window. Only on a\ntask with exactly one window. Arriving early still waits for `from`.","example":60,"minimum":0.0006},{"type":"null","format":"double","description":"Makes this window soft on its late side: arriving after `to` is\nallowed and priced at this rate, in the objective's currency per hour\nlate, in place of `objective.per_late_hour` (and whether or not\nthat is set, so hard and soft windows can share one request). Must be\n`> 0`; omit it for a hard window. Only on a\ntask with exactly one window. Arriving early still waits for `from`.","example":60,"minimum":0.0006}]},"to":{"type":"string","format":"date-time","description":"Latest allowed start of service (RFC 3339 instant, UTC offset\nrequired), measured from arrival plus any windowed break taken first\n(#1750 D1). Hard unless `per_late_hour` prices lateness.","example":"2026-07-01T12:00:00+02:00"}},"additionalProperties":false,"example":{"choice_cost":15,"from":"2026-07-01T09:00:00+02:00","to":"2026-07-01T12:00:00+02:00"}},"description":"Time windows for this visit.","uniqueKey":"problem.jobs.items.[INDEX].time_windows.oneOf.1","typeLabel":"null"}],"uniqueKey":"problem.jobs.items.[INDEX].time_windows","typeLabel":"object[] | null"}},"additionalProperties":false,"example":{"id":"job-1","location":[3.725,51.05],"pickup_load":{"weight":20},"required_skills":[{"name":"fridge"}],"service_duration_s":300,"time_windows":[{"from":"2026-07-01T09:00:00+02:00","to":"2026-07-01T12:00:00+02:00"}]},"uniqueKey":"problem.jobs.items.[INDEX]","typeLabel":"object"},"description":"Single-stop visits to serve. At most 10,000 tasks per request, `jobs`\nand `shipments` combined (HTTP 400 `limit_exceeded` beyond that).","maxItems":10000,"uniqueKey":"problem.jobs","typeLabel":"object[]"},"objective":{"oneOf":[{"type":"null","description":"Objective configuration.","uniqueKey":"problem.objective.oneOf.0","typeLabel":"null"},{"type":"object","description":"Objective configuration.","example":{"costs":{"per_route_hour":35,"per_travel_km":0.2},"currency":"EUR"},"properties":{"costs":{"oneOf":[{"type":"null","description":"Fleet cost rates: the default for every vehicle and shift that does\nnot set its own. See the `Costs` schema.","uniqueKey":"problem.objective.oneOf.1.costs.oneOf.0","typeLabel":"null"},{"type":"object","description":"Fleet cost rates: the default for every vehicle and shift that does\nnot set its own. See the `Costs` schema.","example":{"per_route":50,"per_route_hour":35,"per_travel_km":0.2},"properties":{"per_overtime_hour":{"oneOf":[{"type":"number","format":"double","description":"Per hour a route finishes past its shift's `to` (possible only with\n`max_overtime_s`), reported in `score.components.overtime`, on top of\n`per_route_hour`. Default `0`: overtime is unpriced.","example":0,"minimum":0,"uniqueKey":"problem.objective.oneOf.1.costs.oneOf.1.per_overtime_hour.oneOf.0","typeLabel":"number\u003cdouble>"},{"type":"null","format":"double","description":"Per hour a route finishes past its shift's `to` (possible only with\n`max_overtime_s`), reported in `score.components.overtime`, on top of\n`per_route_hour`. Default `0`: overtime is unpriced.","example":0,"minimum":0,"uniqueKey":"problem.objective.oneOf.1.costs.oneOf.1.per_overtime_hour.oneOf.1","typeLabel":"null"}],"uniqueKey":"problem.objective.oneOf.1.costs.oneOf.1.per_overtime_hour","typeLabel":"number\u003cdouble> | null"},"per_route":{"oneOf":[{"type":"number","format":"double","description":"Flat charge for each used shift (a route with at least one task),\nreported in `score.components.routes`. Default `0`. The higher it is,\nthe more travel the solver accepts to avoid opening another route. It\ncounts shifts, not vehicles: a vehicle that works five days pays it five\ntimes, so it does not prefer one vehicle on two shifts over two vehicles\non one shift each; use `per_used_vehicle` for that.","example":50,"maximum":1000000000,"minimum":0,"uniqueKey":"problem.objective.oneOf.1.costs.oneOf.1.per_route.oneOf.0","typeLabel":"number\u003cdouble>"},{"type":"null","format":"double","description":"Flat charge for each used shift (a route with at least one task),\nreported in `score.components.routes`. Default `0`. The higher it is,\nthe more travel the solver accepts to avoid opening another route. It\ncounts shifts, not vehicles: a vehicle that works five days pays it five\ntimes, so it does not prefer one vehicle on two shifts over two vehicles\non one shift each; use `per_used_vehicle` for that.","example":50,"maximum":1000000000,"minimum":0,"uniqueKey":"problem.objective.oneOf.1.costs.oneOf.1.per_route.oneOf.1","typeLabel":"null"}],"uniqueKey":"problem.objective.oneOf.1.costs.oneOf.1.per_route","typeLabel":"number\u003cdouble> | null"},"per_route_hour":{"oneOf":[{"type":"number","format":"double","description":"Per hour of each route's wall-clock span (travel, service, waiting\nand breaks), reported in `score.components.time`. Default **35** at objective\nlevel; a vehicle or shift value inherits the fleet value.","example":35,"minimum":0,"uniqueKey":"problem.objective.oneOf.1.costs.oneOf.1.per_route_hour.oneOf.0","typeLabel":"number\u003cdouble>"},{"type":"null","format":"double","description":"Per hour of each route's wall-clock span (travel, service, waiting\nand breaks), reported in `score.components.time`. Default **35** at objective\nlevel; a vehicle or shift value inherits the fleet value.","example":35,"minimum":0,"uniqueKey":"problem.objective.oneOf.1.costs.oneOf.1.per_route_hour.oneOf.1","typeLabel":"null"}],"uniqueKey":"problem.objective.oneOf.1.costs.oneOf.1.per_route_hour","typeLabel":"number\u003cdouble> | null"},"per_travel_km":{"oneOf":[{"type":"number","format":"double","description":"Per kilometre driven, reported in `score.components.distance`.\nDefault **0.20** at objective level; a vehicle or shift value inherits the\nfleet value.","example":0.2,"minimum":0,"uniqueKey":"problem.objective.oneOf.1.costs.oneOf.1.per_travel_km.oneOf.0","typeLabel":"number\u003cdouble>"},{"type":"null","format":"double","description":"Per kilometre driven, reported in `score.components.distance`.\nDefault **0.20** at objective level; a vehicle or shift value inherits the\nfleet value.","example":0.2,"minimum":0,"uniqueKey":"problem.objective.oneOf.1.costs.oneOf.1.per_travel_km.oneOf.1","typeLabel":"null"}],"uniqueKey":"problem.objective.oneOf.1.costs.oneOf.1.per_travel_km","typeLabel":"number\u003cdouble> | null"},"per_used_vehicle":{"oneOf":[{"type":"number","format":"double","description":"Flat charge once per vehicle that serves at least one task, however\nmany of its shifts it works. Reported in `score.components.vehicles`.\nAdds to `per_route`: the vehicle's first used shift pays both, later\nshifts only `per_route`. Default `0`. Use it to minimise distinct\nvehicles; use `per_route` to price each working day. Not accepted on\n`shifts[].costs`. When any vehicle has a non-zero rate and any vehicle\nhas several shifts, the problem solves without decomposition.","example":400,"maximum":1000000000,"minimum":0,"uniqueKey":"problem.objective.oneOf.1.costs.oneOf.1.per_used_vehicle.oneOf.0","typeLabel":"number\u003cdouble>"},{"type":"null","format":"double","description":"Flat charge once per vehicle that serves at least one task, however\nmany of its shifts it works. Reported in `score.components.vehicles`.\nAdds to `per_route`: the vehicle's first used shift pays both, later\nshifts only `per_route`. Default `0`. Use it to minimise distinct\nvehicles; use `per_route` to price each working day. Not accepted on\n`shifts[].costs`. When any vehicle has a non-zero rate and any vehicle\nhas several shifts, the problem solves without decomposition.","example":400,"maximum":1000000000,"minimum":0,"uniqueKey":"problem.objective.oneOf.1.costs.oneOf.1.per_used_vehicle.oneOf.1","typeLabel":"null"}],"uniqueKey":"problem.objective.oneOf.1.costs.oneOf.1.per_used_vehicle","typeLabel":"number\u003cdouble> | null"},"per_wait_hour":{"oneOf":[{"type":"number","format":"double","description":"Per hour spent waiting for a time window to open, reported in\n`score.components.waiting`, on top of `per_route_hour` (the span\nincludes the wait). Idle before a windowed break's window opens is\nreported in `wait_s` but not charged here. Default `0`.","example":0,"minimum":0,"uniqueKey":"problem.objective.oneOf.1.costs.oneOf.1.per_wait_hour.oneOf.0","typeLabel":"number\u003cdouble>"},{"type":"null","format":"double","description":"Per hour spent waiting for a time window to open, reported in\n`score.components.waiting`, on top of `per_route_hour` (the span\nincludes the wait). Idle before a windowed break's window opens is\nreported in `wait_s` but not charged here. Default `0`.","example":0,"minimum":0,"uniqueKey":"problem.objective.oneOf.1.costs.oneOf.1.per_wait_hour.oneOf.1","typeLabel":"null"}],"uniqueKey":"problem.objective.oneOf.1.costs.oneOf.1.per_wait_hour","typeLabel":"number\u003cdouble> | null"}},"additionalProperties":false,"uniqueKey":"problem.objective.oneOf.1.costs.oneOf.1","typeLabel":"object"}],"uniqueKey":"problem.objective.oneOf.1.costs","typeLabel":"null | object"},"currency":{"oneOf":[{"type":"string","description":"Currency label (ISO 4217, e.g. `EUR`) for every amount in the request\nand in `score`. Informational: echoed as `score.currency`, it never\nconverts anything.","example":"EUR","uniqueKey":"problem.objective.oneOf.1.currency.oneOf.0","typeLabel":"string"},{"type":"null","description":"Currency label (ISO 4217, e.g. `EUR`) for every amount in the request\nand in `score`. Informational: echoed as `score.currency`, it never\nconverts anything.","example":"EUR","uniqueKey":"problem.objective.oneOf.1.currency.oneOf.1","typeLabel":"null"}],"uniqueKey":"problem.objective.oneOf.1.currency","typeLabel":"string | null"},"grouping":{"oneOf":[{"type":"null","description":"Job-proximity cluster cohesion. See the `Grouping` schema.","uniqueKey":"problem.objective.oneOf.1.grouping.oneOf.0","typeLabel":"null"},{"type":"object","description":"Job-proximity cluster cohesion. See the `Grouping` schema.","required":["per_entry"],"example":{"distance_metric":"straight_line","per_entry":0.5,"radius_m":180},"properties":{"per_entry":{"type":"number","format":"double","description":"Cost added to the objective on every entry into a group from a job\noutside it (a job that is not within `radius_m` of the entered one),\nthe first entry included, in the objective's currency. Entry from the\nshift's start or from a reload is free. At most 1000 currency units: a\nlarger value is rejected with HTTP 400. Higher keeps clusters together\nmore aggressively at the expense of total travel.","example":0.5,"maximum":1000,"minimum":0,"isRequired":true,"uniqueKey":"problem.objective.oneOf.1.grouping.oneOf.1.per_entry","typeLabel":"number\u003cdouble>"},"distance_metric":{"oneOf":[{"type":"null","description":"How neighbour distance is measured. Default `\"straight_line\"`.","default":"straight_line","uniqueKey":"problem.objective.oneOf.1.grouping.oneOf.1.distance_metric.oneOf.0","typeLabel":"null"},{"type":"string","description":"How neighbour distance is measured. Default `\"straight_line\"`.","default":"straight_line","enum":["straight_line","road"],"example":"straight_line","uniqueKey":"problem.objective.oneOf.1.grouping.oneOf.1.distance_metric.oneOf.1","typeLabel":"enum\u003cstring>"}],"uniqueKey":"problem.objective.oneOf.1.grouping.oneOf.1.distance_metric","typeLabel":"null | enum\u003cstring>"},"radius_m":{"oneOf":[{"type":"integer","format":"int32","description":"Radius defining a group, in metres. Default `180`. Must be `> 0`.","default":180,"example":180,"minimum":1,"uniqueKey":"problem.objective.oneOf.1.grouping.oneOf.1.radius_m.oneOf.0","typeLabel":"integer\u003cint32>"},{"type":"null","format":"int32","description":"Radius defining a group, in metres. Default `180`. Must be `> 0`.","default":180,"example":180,"minimum":1,"uniqueKey":"problem.objective.oneOf.1.grouping.oneOf.1.radius_m.oneOf.1","typeLabel":"null"}],"uniqueKey":"problem.objective.oneOf.1.grouping.oneOf.1.radius_m","typeLabel":"integer\u003cint32> | null"}},"additionalProperties":false,"uniqueKey":"problem.objective.oneOf.1.grouping.oneOf.1","typeLabel":"object"}],"uniqueKey":"problem.objective.oneOf.1.grouping","typeLabel":"null | object"},"per_delay_workday":{"oneOf":[{"type":"number","format":"double","description":"ASAP scheduling: money charged for each served task per workday its\nshift lies after the earliest workday in the request, in the request's\ncurrency. A workday is a distinct calendar date, in the shift's own UTC\noffset, on which at least one shift starts; shifts on one date share a\nrank, and a date with no shift adds none. Unserved tasks pay nothing;\nthe charge never outranks `priority` and cannot be combined with\n`drop_cost`. Absent or `0` = off; a single-date request is charged\nnothing. A problem that sets it, even on one date, solves without\ndecomposition, like `assignment_costs`. Reported as `score.components.delay`. A positive\nrate below `0.00001` is rejected, as is a rate whose total over the\nlater workdays exceeds `21474.83647` (`out_of_range`).","example":5,"minimum":0,"uniqueKey":"problem.objective.oneOf.1.per_delay_workday.oneOf.0","typeLabel":"number\u003cdouble>"},{"type":"null","format":"double","description":"ASAP scheduling: money charged for each served task per workday its\nshift lies after the earliest workday in the request, in the request's\ncurrency. A workday is a distinct calendar date, in the shift's own UTC\noffset, on which at least one shift starts; shifts on one date share a\nrank, and a date with no shift adds none. Unserved tasks pay nothing;\nthe charge never outranks `priority` and cannot be combined with\n`drop_cost`. Absent or `0` = off; a single-date request is charged\nnothing. A problem that sets it, even on one date, solves without\ndecomposition, like `assignment_costs`. Reported as `score.components.delay`. A positive\nrate below `0.00001` is rejected, as is a rate whose total over the\nlater workdays exceeds `21474.83647` (`out_of_range`).","example":5,"minimum":0,"uniqueKey":"problem.objective.oneOf.1.per_delay_workday.oneOf.1","typeLabel":"null"}],"uniqueKey":"problem.objective.oneOf.1.per_delay_workday","typeLabel":"number\u003cdouble> | null"},"per_late_hour":{"oneOf":[{"type":"number","format":"double","description":"Cost per hour of lateness: the default rate for every task window\nthat does not carry its own `time_windows[].per_late_hour`. Omit for\nhard windows. An explicit `0.0` is rejected as ambiguous (free\nlateness and hard windows read opposite ways, and lateness is never\nfree). There is no earliness rate. It prices task windows only: a\nshift's `to` (plus `max_overtime_s` when set) stays a hard limit.\nSetting it `> 0` alongside a nonzero `time_windows[].choice_cost` anywhere in\nthe request is rejected with HTTP 400.","example":60,"minimum":0.0006,"uniqueKey":"problem.objective.oneOf.1.per_late_hour.oneOf.0","typeLabel":"number\u003cdouble>"},{"type":"null","format":"double","description":"Cost per hour of lateness: the default rate for every task window\nthat does not carry its own `time_windows[].per_late_hour`. Omit for\nhard windows. An explicit `0.0` is rejected as ambiguous (free\nlateness and hard windows read opposite ways, and lateness is never\nfree). There is no earliness rate. It prices task windows only: a\nshift's `to` (plus `max_overtime_s` when set) stays a hard limit.\nSetting it `> 0` alongside a nonzero `time_windows[].choice_cost` anywhere in\nthe request is rejected with HTTP 400.","example":60,"minimum":0.0006,"uniqueKey":"problem.objective.oneOf.1.per_late_hour.oneOf.1","typeLabel":"null"}],"uniqueKey":"problem.objective.oneOf.1.per_late_hour","typeLabel":"number\u003cdouble> | null"},"workload_share":{"oneOf":[{"type":"null","description":"Spreads work across vehicles. See the `WorkloadShare` schema.","uniqueKey":"problem.objective.oneOf.1.workload_share.oneOf.0","typeLabel":"null"},{"type":"object","description":"Spreads work across vehicles. See the `WorkloadShare` schema.","required":["per_imbalance_hour"],"properties":{"per_imbalance_hour":{"type":"number","format":"double","description":"Money per hour a vehicle's service time is outside the band, in the\nrequest's currency. Greater than 0 and at least 0.036 (the internal\nresolution); omit `workload_share` to switch the term off.","example":35,"exclusiveMinimum":0,"isRequired":true,"uniqueKey":"problem.objective.oneOf.1.workload_share.oneOf.1.per_imbalance_hour","typeLabel":"number\u003cdouble>"},"tolerance":{"oneOf":[{"type":"number","format":"double","description":"Half-width of the band as a fraction of the vehicle's share, `0` up to\nbut not including `1`. Default `0.1`: a vehicle within 10% of its share\nis not charged. The charge grows from the band edge.","example":0.1,"minimum":0,"exclusiveMaximum":1,"uniqueKey":"problem.objective.oneOf.1.workload_share.oneOf.1.tolerance.oneOf.0","typeLabel":"number\u003cdouble>"},{"type":"null","format":"double","description":"Half-width of the band as a fraction of the vehicle's share, `0` up to\nbut not including `1`. Default `0.1`: a vehicle within 10% of its share\nis not charged. The charge grows from the band edge.","example":0.1,"minimum":0,"exclusiveMaximum":1,"uniqueKey":"problem.objective.oneOf.1.workload_share.oneOf.1.tolerance.oneOf.1","typeLabel":"null"}],"uniqueKey":"problem.objective.oneOf.1.workload_share.oneOf.1.tolerance","typeLabel":"number\u003cdouble> | null"}},"additionalProperties":false,"uniqueKey":"problem.objective.oneOf.1.workload_share.oneOf.1","typeLabel":"object"}],"uniqueKey":"problem.objective.oneOf.1.workload_share","typeLabel":"null | object"}},"additionalProperties":false,"uniqueKey":"problem.objective.oneOf.1","typeLabel":"object"}],"uniqueKey":"problem.objective","typeLabel":"null | object"},"quotas":{"type":"array","items":{"type":"object","description":"A hard cap on how many stops of `tasks` the `vehicles` serve together\nin a window. A stop counts when its service starts in `[from, to)`\n(`arrival + wait_s` in the response when no windowed break is taken on\narrival there); without a window every stop counts.\nStops count as `max_stops` counts them: a job one, a shipment two. An\nover-cap job is left unassigned. Unlike `limits.periods[]`, which counts a\nshift by its start, a quota has no `every` recurrence and caps only stop\ncounts.","required":["id","vehicles","tasks","max_stops"],"properties":{"id":{"type":"string","description":"Quota id: 1 to 128 characters, unique among `quotas`; named in the\n`/evaluate` `quota` violation.","maxLength":128,"minLength":1,"isRequired":true,"uniqueKey":"problem.quotas.items.[INDEX].id","typeLabel":"string"},"max_stops":{"type":"integer","format":"int32","description":"The cap on counted stops; a job counts as one stop.\nStart, end, break and reload stops in `routes[].stops` do not count; a\nshipment counts as two stops.","minimum":0,"isRequired":true,"uniqueKey":"problem.quotas.items.[INDEX].max_stops","typeLabel":"integer\u003cint32>"},"tasks":{"type":"array","items":{"type":"string","uniqueKey":"problem.quotas.items.[INDEX].tasks.items.[INDEX]","typeLabel":"string"},"description":"Job or shipment ids whose stops count, each at most once. At least\none; an id that names no job or shipment is rejected with HTTP 400.","minItems":1,"isRequired":true,"uniqueKey":"problem.quotas.items.[INDEX].tasks","typeLabel":"string[]"},"vehicles":{"type":"array","items":{"type":"string","uniqueKey":"problem.quotas.items.[INDEX].vehicles.items.[INDEX]","typeLabel":"string"},"description":"Vehicle ids that share the cap, each at most once. At least one; an id\nthat names no vehicle is rejected with HTTP 400.","minItems":1,"isRequired":true,"uniqueKey":"problem.quotas.items.[INDEX].vehicles","typeLabel":"string[]"},"from":{"oneOf":[{"type":"string","format":"date-time","description":"Window start (RFC 3339, UTC offset required), with `to`. The window\nmust overlap a shift of one of `vehicles` (counting its\n`max_overtime_s`), else the request is rejected with HTTP 400.","example":"2026-10-05T00:00:00+02:00","uniqueKey":"problem.quotas.items.[INDEX].from.oneOf.0","typeLabel":"string\u003cdate-time>"},{"type":"null","format":"date-time","description":"Window start (RFC 3339, UTC offset required), with `to`. The window\nmust overlap a shift of one of `vehicles` (counting its\n`max_overtime_s`), else the request is rejected with HTTP 400.","example":"2026-10-05T00:00:00+02:00","uniqueKey":"problem.quotas.items.[INDEX].from.oneOf.1","typeLabel":"null"}],"uniqueKey":"problem.quotas.items.[INDEX].from","typeLabel":"string\u003cdate-time> | null"},"to":{"oneOf":[{"type":"string","format":"date-time","description":"Window end (RFC 3339, UTC offset required, exclusive), with `from`.","example":"2026-10-06T00:00:00+02:00","uniqueKey":"problem.quotas.items.[INDEX].to.oneOf.0","typeLabel":"string\u003cdate-time>"},{"type":"null","format":"date-time","description":"Window end (RFC 3339, UTC offset required, exclusive), with `from`.","example":"2026-10-06T00:00:00+02:00","uniqueKey":"problem.quotas.items.[INDEX].to.oneOf.1","typeLabel":"null"}],"uniqueKey":"problem.quotas.items.[INDEX].to","typeLabel":"string\u003cdate-time> | null"}},"additionalProperties":false,"example":{"id":"pool-install","max_stops":2,"tasks":["j1","j2","j3"],"vehicles":["c0","c1"]},"uniqueKey":"problem.quotas.items.[INDEX]","typeLabel":"object"},"description":"Stop caps shared by a set of vehicles. At most 65,535.","maxItems":65535,"uniqueKey":"problem.quotas","typeLabel":"object[]"},"relations":{"oneOf":[{"type":"array","items":{"oneOf":[{"type":"object","title":"Sequence","description":"A hard constraint between tasks, selected by `type`: `sequence`,\n`tag_order`, `same_vehicle`, `same_day`, `same_route`, `synchronized`,\n`time_lag`, `compatible_vehicles` or `all_or_none`.\nEach type carries only its own fields; any other `type` is rejected with\nHTTP 400.\n\nMembers are named by `stops` (job ids, or shipment-leg stop ids where\nthe type accepts them, see below). `same_vehicle`, `same_day` and\n`same_route` take **either** `stops` **or** a `tag`, not both. Every\nrelation is hard.\n\nA shipment takes part through its legs: `sequence`, `same_vehicle`,\n`same_day` and `same_route` accept a leg's stop id (`pickup.id` /\n`delivery.id`, by default `\"{shipment}:pickup\"` / `\":delivery\"`) and bind\nthat leg like a job. A leg coupled to other tasks by a `synchronized` or\n`time_lag` relation (directly, or through a `sequence` with a member that\nis) is rejected with HTTP 400, as is a `sequence` putting a delivery before\nits pickup. A shipment's own id in `stops`, or a shipment carrying the\n`tag` of a `same_vehicle` or `same_day` relation, is rejected with HTTP 400\n`not_supported`: relations never silently skip a member. `same_route`,\n`time_lag`, `compatible_vehicles`, `all_or_none` and `tag_order` reject a\nshipment with HTTP 400 as well.","required":["stops","type"],"example":{"stops":["job-1","job-2"],"type":"sequence"},"properties":{"stops":{"type":"array","items":{"type":"string","uniqueKey":"problem.relations.oneOf.0.items.[INDEX].oneOf.0.stops.items.[INDEX]","typeLabel":"string"},"description":"Job ids or shipment-leg stop ids (`pickup.id` / `delivery.id`, by\ndefault `\"{shipment}:pickup\"` / `\"{shipment}:delivery\"`), in the\norder they must be served. A shipment's own id is\nrejected with HTTP 400 `not_supported`.","isRequired":true,"uniqueKey":"problem.relations.oneOf.0.items.[INDEX].oneOf.0.stops","typeLabel":"string[]"},"type":{"type":"string","description":"Discriminator: always `sequence`.","enum":["sequence"],"isRequired":true,"uniqueKey":"problem.relations.oneOf.0.items.[INDEX].oneOf.0.type","typeLabel":"enum\u003cstring>"}},"additionalProperties":false,"uniqueKey":"problem.relations.oneOf.0.items.[INDEX].oneOf.0","typeLabel":"Sequence · object"},{"type":"object","title":"Consecutive","description":"A hard constraint between tasks, selected by `type`: `sequence`,\n`tag_order`, `same_vehicle`, `same_day`, `same_route`, `synchronized`,\n`time_lag`, `compatible_vehicles` or `all_or_none`.\nEach type carries only its own fields; any other `type` is rejected with\nHTTP 400.\n\nMembers are named by `stops` (job ids, or shipment-leg stop ids where\nthe type accepts them, see below). `same_vehicle`, `same_day` and\n`same_route` take **either** `stops` **or** a `tag`, not both. Every\nrelation is hard.\n\nA shipment takes part through its legs: `sequence`, `same_vehicle`,\n`same_day` and `same_route` accept a leg's stop id (`pickup.id` /\n`delivery.id`, by default `\"{shipment}:pickup\"` / `\":delivery\"`) and bind\nthat leg like a job. A leg coupled to other tasks by a `synchronized` or\n`time_lag` relation (directly, or through a `sequence` with a member that\nis) is rejected with HTTP 400, as is a `sequence` putting a delivery before\nits pickup. A shipment's own id in `stops`, or a shipment carrying the\n`tag` of a `same_vehicle` or `same_day` relation, is rejected with HTTP 400\n`not_supported`: relations never silently skip a member. `same_route`,\n`time_lag`, `compatible_vehicles`, `all_or_none` and `tag_order` reject a\nshipment with HTTP 400 as well.","required":["stops","type"],"example":{"stops":["job-1","job-2"],"type":"sequence"},"properties":{"stops":{"type":"array","items":{"type":"string","uniqueKey":"problem.relations.oneOf.0.items.[INDEX].oneOf.1.stops.items.[INDEX]","typeLabel":"string"},"description":"Job ids or shipment-leg stop ids, in the order they must be served\nback to back. At least 2. A stop has one successor and one predecessor\nacross all `consecutive` relations, so `[a, b]` and `[b, c]` may\noverlap but `[a, b]` and `[a, c]` may not. A shipment's own id is rejected with HTTP\n400 `not_supported`.","minItems":2,"isRequired":true,"uniqueKey":"problem.relations.oneOf.0.items.[INDEX].oneOf.1.stops","typeLabel":"string[]"},"type":{"type":"string","description":"Discriminator: always `consecutive`.","enum":["consecutive"],"isRequired":true,"uniqueKey":"problem.relations.oneOf.0.items.[INDEX].oneOf.1.type","typeLabel":"enum\u003cstring>"}},"additionalProperties":false,"uniqueKey":"problem.relations.oneOf.0.items.[INDEX].oneOf.1","typeLabel":"Consecutive · object"},{"type":"object","title":"Tag order","description":"A hard constraint between tasks, selected by `type`: `sequence`,\n`tag_order`, `same_vehicle`, `same_day`, `same_route`, `synchronized`,\n`time_lag`, `compatible_vehicles` or `all_or_none`.\nEach type carries only its own fields; any other `type` is rejected with\nHTTP 400.\n\nMembers are named by `stops` (job ids, or shipment-leg stop ids where\nthe type accepts them, see below). `same_vehicle`, `same_day` and\n`same_route` take **either** `stops` **or** a `tag`, not both. Every\nrelation is hard.\n\nA shipment takes part through its legs: `sequence`, `same_vehicle`,\n`same_day` and `same_route` accept a leg's stop id (`pickup.id` /\n`delivery.id`, by default `\"{shipment}:pickup\"` / `\":delivery\"`) and bind\nthat leg like a job. A leg coupled to other tasks by a `synchronized` or\n`time_lag` relation (directly, or through a `sequence` with a member that\nis) is rejected with HTTP 400, as is a `sequence` putting a delivery before\nits pickup. A shipment's own id in `stops`, or a shipment carrying the\n`tag` of a `same_vehicle` or `same_day` relation, is rejected with HTTP 400\n`not_supported`: relations never silently skip a member. `same_route`,\n`time_lag`, `compatible_vehicles`, `all_or_none` and `tag_order` reject a\nshipment with HTTP 400 as well.","required":["tags","type"],"example":{"type":"sequence"},"properties":{"tags":{"type":"array","items":{"type":"string","uniqueKey":"problem.relations.oneOf.0.items.[INDEX].oneOf.2.tags.items.[INDEX]","typeLabel":"string"},"description":"Tag labels in precedence order. Requires at least 2 entries.","minItems":2,"isRequired":true,"uniqueKey":"problem.relations.oneOf.0.items.[INDEX].oneOf.2.tags","typeLabel":"string[]"},"type":{"type":"string","description":"Discriminator: always `tag_order`.","enum":["tag_order"],"isRequired":true,"uniqueKey":"problem.relations.oneOf.0.items.[INDEX].oneOf.2.type","typeLabel":"enum\u003cstring>"}},"additionalProperties":false,"uniqueKey":"problem.relations.oneOf.0.items.[INDEX].oneOf.2","typeLabel":"Tag order · object"},{"type":"object","title":"Same vehicle","description":"A hard constraint between tasks, selected by `type`: `sequence`,\n`tag_order`, `same_vehicle`, `same_day`, `same_route`, `synchronized`,\n`time_lag`, `compatible_vehicles` or `all_or_none`.\nEach type carries only its own fields; any other `type` is rejected with\nHTTP 400.\n\nMembers are named by `stops` (job ids, or shipment-leg stop ids where\nthe type accepts them, see below). `same_vehicle`, `same_day` and\n`same_route` take **either** `stops` **or** a `tag`, not both. Every\nrelation is hard.\n\nA shipment takes part through its legs: `sequence`, `same_vehicle`,\n`same_day` and `same_route` accept a leg's stop id (`pickup.id` /\n`delivery.id`, by default `\"{shipment}:pickup\"` / `\":delivery\"`) and bind\nthat leg like a job. A leg coupled to other tasks by a `synchronized` or\n`time_lag` relation (directly, or through a `sequence` with a member that\nis) is rejected with HTTP 400, as is a `sequence` putting a delivery before\nits pickup. A shipment's own id in `stops`, or a shipment carrying the\n`tag` of a `same_vehicle` or `same_day` relation, is rejected with HTTP 400\n`not_supported`: relations never silently skip a member. `same_route`,\n`time_lag`, `compatible_vehicles`, `all_or_none` and `tag_order` reject a\nshipment with HTTP 400 as well.","required":["type","stops"],"example":{"stops":["job-1","job-2"],"type":"sequence"},"properties":{"stops":{"oneOf":[{"type":"array","items":{"type":"string","uniqueKey":"problem.relations.oneOf.0.items.[INDEX].oneOf.3.stops.oneOf.0.items.[INDEX]","typeLabel":"string"},"description":"Job ids or shipment-leg stop ids in the relation (mutually\nexclusive with `tag`). A shipment's own id is rejected with\nHTTP 400 `not_supported`.","isRequired":true,"uniqueKey":"problem.relations.oneOf.0.items.[INDEX].oneOf.3.stops.oneOf.0","typeLabel":"string[]"},{"type":"null","items":{"type":"string"},"description":"Job ids or shipment-leg stop ids in the relation (mutually\nexclusive with `tag`). A shipment's own id is rejected with\nHTTP 400 `not_supported`.","isRequired":true,"uniqueKey":"problem.relations.oneOf.0.items.[INDEX].oneOf.3.stops.oneOf.1","typeLabel":"null"}],"isRequired":true,"uniqueKey":"problem.relations.oneOf.0.items.[INDEX].oneOf.3.stops","typeLabel":"string[] | null"},"type":{"type":"string","description":"Discriminator: always `same_vehicle`.","enum":["same_vehicle"],"isRequired":true,"uniqueKey":"problem.relations.oneOf.0.items.[INDEX].oneOf.3.type","typeLabel":"enum\u003cstring>"},"tag":{"oneOf":[{"type":"string","description":"Tag selecting the relation members (mutually exclusive with `stops`).","uniqueKey":"problem.relations.oneOf.0.items.[INDEX].oneOf.3.tag.oneOf.0","typeLabel":"string"},{"type":"null","description":"Tag selecting the relation members (mutually exclusive with `stops`).","uniqueKey":"problem.relations.oneOf.0.items.[INDEX].oneOf.3.tag.oneOf.1","typeLabel":"null"}],"uniqueKey":"problem.relations.oneOf.0.items.[INDEX].oneOf.3.tag","typeLabel":"string | null"}},"additionalProperties":false,"uniqueKey":"problem.relations.oneOf.0.items.[INDEX].oneOf.3","typeLabel":"Same vehicle · object"},{"type":"object","title":"Same vehicle","description":"A hard constraint between tasks, selected by `type`: `sequence`,\n`tag_order`, `same_vehicle`, `same_day`, `same_route`, `synchronized`,\n`time_lag`, `compatible_vehicles` or `all_or_none`.\nEach type carries only its own fields; any other `type` is rejected with\nHTTP 400.\n\nMembers are named by `stops` (job ids, or shipment-leg stop ids where\nthe type accepts them, see below). `same_vehicle`, `same_day` and\n`same_route` take **either** `stops` **or** a `tag`, not both. Every\nrelation is hard.\n\nA shipment takes part through its legs: `sequence`, `same_vehicle`,\n`same_day` and `same_route` accept a leg's stop id (`pickup.id` /\n`delivery.id`, by default `\"{shipment}:pickup\"` / `\":delivery\"`) and bind\nthat leg like a job. A leg coupled to other tasks by a `synchronized` or\n`time_lag` relation (directly, or through a `sequence` with a member that\nis) is rejected with HTTP 400, as is a `sequence` putting a delivery before\nits pickup. A shipment's own id in `stops`, or a shipment carrying the\n`tag` of a `same_vehicle` or `same_day` relation, is rejected with HTTP 400\n`not_supported`: relations never silently skip a member. `same_route`,\n`time_lag`, `compatible_vehicles`, `all_or_none` and `tag_order` reject a\nshipment with HTTP 400 as well.","required":["type","tag"],"example":{"stops":["job-1","job-2"],"type":"sequence"},"properties":{"tag":{"oneOf":[{"type":"string","description":"Tag selecting the relation members (mutually exclusive with `stops`).","isRequired":true,"uniqueKey":"problem.relations.oneOf.0.items.[INDEX].oneOf.4.tag.oneOf.0","typeLabel":"string"},{"type":"null","description":"Tag selecting the relation members (mutually exclusive with `stops`).","isRequired":true,"uniqueKey":"problem.relations.oneOf.0.items.[INDEX].oneOf.4.tag.oneOf.1","typeLabel":"null"}],"isRequired":true,"uniqueKey":"problem.relations.oneOf.0.items.[INDEX].oneOf.4.tag","typeLabel":"string | null"},"type":{"type":"string","description":"Discriminator: always `same_vehicle`.","enum":["same_vehicle"],"isRequired":true,"uniqueKey":"problem.relations.oneOf.0.items.[INDEX].oneOf.4.type","typeLabel":"enum\u003cstring>"},"stops":{"oneOf":[{"type":"array","items":{"type":"string","uniqueKey":"problem.relations.oneOf.0.items.[INDEX].oneOf.4.stops.oneOf.0.items.[INDEX]","typeLabel":"string"},"description":"Job ids or shipment-leg stop ids in the relation (mutually\nexclusive with `tag`). A shipment's own id is rejected with\nHTTP 400 `not_supported`.","uniqueKey":"problem.relations.oneOf.0.items.[INDEX].oneOf.4.stops.oneOf.0","typeLabel":"string[]"},{"type":"null","items":{"type":"string"},"description":"Job ids or shipment-leg stop ids in the relation (mutually\nexclusive with `tag`). A shipment's own id is rejected with\nHTTP 400 `not_supported`.","uniqueKey":"problem.relations.oneOf.0.items.[INDEX].oneOf.4.stops.oneOf.1","typeLabel":"null"}],"uniqueKey":"problem.relations.oneOf.0.items.[INDEX].oneOf.4.stops","typeLabel":"string[] | null"}},"additionalProperties":false,"uniqueKey":"problem.relations.oneOf.0.items.[INDEX].oneOf.4","typeLabel":"Same vehicle · object"},{"type":"object","title":"Same day","description":"A hard constraint between tasks, selected by `type`: `sequence`,\n`tag_order`, `same_vehicle`, `same_day`, `same_route`, `synchronized`,\n`time_lag`, `compatible_vehicles` or `all_or_none`.\nEach type carries only its own fields; any other `type` is rejected with\nHTTP 400.\n\nMembers are named by `stops` (job ids, or shipment-leg stop ids where\nthe type accepts them, see below). `same_vehicle`, `same_day` and\n`same_route` take **either** `stops` **or** a `tag`, not both. Every\nrelation is hard.\n\nA shipment takes part through its legs: `sequence`, `same_vehicle`,\n`same_day` and `same_route` accept a leg's stop id (`pickup.id` /\n`delivery.id`, by default `\"{shipment}:pickup\"` / `\":delivery\"`) and bind\nthat leg like a job. A leg coupled to other tasks by a `synchronized` or\n`time_lag` relation (directly, or through a `sequence` with a member that\nis) is rejected with HTTP 400, as is a `sequence` putting a delivery before\nits pickup. A shipment's own id in `stops`, or a shipment carrying the\n`tag` of a `same_vehicle` or `same_day` relation, is rejected with HTTP 400\n`not_supported`: relations never silently skip a member. `same_route`,\n`time_lag`, `compatible_vehicles`, `all_or_none` and `tag_order` reject a\nshipment with HTTP 400 as well.","required":["type","stops"],"example":{"stops":["job-1","job-2"],"type":"sequence"},"properties":{"stops":{"oneOf":[{"type":"array","items":{"type":"string","uniqueKey":"problem.relations.oneOf.0.items.[INDEX].oneOf.5.stops.oneOf.0.items.[INDEX]","typeLabel":"string"},"description":"Job ids or shipment-leg stop ids in the relation (mutually\nexclusive with `tag`). A shipment's own id is rejected with\nHTTP 400 `not_supported`.","isRequired":true,"uniqueKey":"problem.relations.oneOf.0.items.[INDEX].oneOf.5.stops.oneOf.0","typeLabel":"string[]"},{"type":"null","items":{"type":"string"},"description":"Job ids or shipment-leg stop ids in the relation (mutually\nexclusive with `tag`). A shipment's own id is rejected with\nHTTP 400 `not_supported`.","isRequired":true,"uniqueKey":"problem.relations.oneOf.0.items.[INDEX].oneOf.5.stops.oneOf.1","typeLabel":"null"}],"isRequired":true,"uniqueKey":"problem.relations.oneOf.0.items.[INDEX].oneOf.5.stops","typeLabel":"string[] | null"},"type":{"type":"string","description":"Discriminator: always `same_day`.","enum":["same_day"],"isRequired":true,"uniqueKey":"problem.relations.oneOf.0.items.[INDEX].oneOf.5.type","typeLabel":"enum\u003cstring>"},"tag":{"oneOf":[{"type":"string","description":"Tag selecting the relation members (mutually exclusive with `stops`).","uniqueKey":"problem.relations.oneOf.0.items.[INDEX].oneOf.5.tag.oneOf.0","typeLabel":"string"},{"type":"null","description":"Tag selecting the relation members (mutually exclusive with `stops`).","uniqueKey":"problem.relations.oneOf.0.items.[INDEX].oneOf.5.tag.oneOf.1","typeLabel":"null"}],"uniqueKey":"problem.relations.oneOf.0.items.[INDEX].oneOf.5.tag","typeLabel":"string | null"}},"additionalProperties":false,"uniqueKey":"problem.relations.oneOf.0.items.[INDEX].oneOf.5","typeLabel":"Same day · object"},{"type":"object","title":"Same day","description":"A hard constraint between tasks, selected by `type`: `sequence`,\n`tag_order`, `same_vehicle`, `same_day`, `same_route`, `synchronized`,\n`time_lag`, `compatible_vehicles` or `all_or_none`.\nEach type carries only its own fields; any other `type` is rejected with\nHTTP 400.\n\nMembers are named by `stops` (job ids, or shipment-leg stop ids where\nthe type accepts them, see below). `same_vehicle`, `same_day` and\n`same_route` take **either** `stops` **or** a `tag`, not both. Every\nrelation is hard.\n\nA shipment takes part through its legs: `sequence`, `same_vehicle`,\n`same_day` and `same_route` accept a leg's stop id (`pickup.id` /\n`delivery.id`, by default `\"{shipment}:pickup\"` / `\":delivery\"`) and bind\nthat leg like a job. A leg coupled to other tasks by a `synchronized` or\n`time_lag` relation (directly, or through a `sequence` with a member that\nis) is rejected with HTTP 400, as is a `sequence` putting a delivery before\nits pickup. A shipment's own id in `stops`, or a shipment carrying the\n`tag` of a `same_vehicle` or `same_day` relation, is rejected with HTTP 400\n`not_supported`: relations never silently skip a member. `same_route`,\n`time_lag`, `compatible_vehicles`, `all_or_none` and `tag_order` reject a\nshipment with HTTP 400 as well.","required":["type","tag"],"example":{"stops":["job-1","job-2"],"type":"sequence"},"properties":{"tag":{"oneOf":[{"type":"string","description":"Tag selecting the relation members (mutually exclusive with `stops`).","isRequired":true,"uniqueKey":"problem.relations.oneOf.0.items.[INDEX].oneOf.6.tag.oneOf.0","typeLabel":"string"},{"type":"null","description":"Tag selecting the relation members (mutually exclusive with `stops`).","isRequired":true,"uniqueKey":"problem.relations.oneOf.0.items.[INDEX].oneOf.6.tag.oneOf.1","typeLabel":"null"}],"isRequired":true,"uniqueKey":"problem.relations.oneOf.0.items.[INDEX].oneOf.6.tag","typeLabel":"string | null"},"type":{"type":"string","description":"Discriminator: always `same_day`.","enum":["same_day"],"isRequired":true,"uniqueKey":"problem.relations.oneOf.0.items.[INDEX].oneOf.6.type","typeLabel":"enum\u003cstring>"},"stops":{"oneOf":[{"type":"array","items":{"type":"string","uniqueKey":"problem.relations.oneOf.0.items.[INDEX].oneOf.6.stops.oneOf.0.items.[INDEX]","typeLabel":"string"},"description":"Job ids or shipment-leg stop ids in the relation (mutually\nexclusive with `tag`). A shipment's own id is rejected with\nHTTP 400 `not_supported`.","uniqueKey":"problem.relations.oneOf.0.items.[INDEX].oneOf.6.stops.oneOf.0","typeLabel":"string[]"},{"type":"null","items":{"type":"string"},"description":"Job ids or shipment-leg stop ids in the relation (mutually\nexclusive with `tag`). A shipment's own id is rejected with\nHTTP 400 `not_supported`.","uniqueKey":"problem.relations.oneOf.0.items.[INDEX].oneOf.6.stops.oneOf.1","typeLabel":"null"}],"uniqueKey":"problem.relations.oneOf.0.items.[INDEX].oneOf.6.stops","typeLabel":"string[] | null"}},"additionalProperties":false,"uniqueKey":"problem.relations.oneOf.0.items.[INDEX].oneOf.6","typeLabel":"Same day · object"},{"type":"object","title":"Same route","description":"A hard constraint between tasks, selected by `type`: `sequence`,\n`tag_order`, `same_vehicle`, `same_day`, `same_route`, `synchronized`,\n`time_lag`, `compatible_vehicles` or `all_or_none`.\nEach type carries only its own fields; any other `type` is rejected with\nHTTP 400.\n\nMembers are named by `stops` (job ids, or shipment-leg stop ids where\nthe type accepts them, see below). `same_vehicle`, `same_day` and\n`same_route` take **either** `stops` **or** a `tag`, not both. Every\nrelation is hard.\n\nA shipment takes part through its legs: `sequence`, `same_vehicle`,\n`same_day` and `same_route` accept a leg's stop id (`pickup.id` /\n`delivery.id`, by default `\"{shipment}:pickup\"` / `\":delivery\"`) and bind\nthat leg like a job. A leg coupled to other tasks by a `synchronized` or\n`time_lag` relation (directly, or through a `sequence` with a member that\nis) is rejected with HTTP 400, as is a `sequence` putting a delivery before\nits pickup. A shipment's own id in `stops`, or a shipment carrying the\n`tag` of a `same_vehicle` or `same_day` relation, is rejected with HTTP 400\n`not_supported`: relations never silently skip a member. `same_route`,\n`time_lag`, `compatible_vehicles`, `all_or_none` and `tag_order` reject a\nshipment with HTTP 400 as well.","required":["type","stops"],"example":{"stops":["job-1","job-2"],"type":"sequence"},"properties":{"stops":{"oneOf":[{"type":"array","items":{"type":"string","uniqueKey":"problem.relations.oneOf.0.items.[INDEX].oneOf.7.stops.oneOf.0.items.[INDEX]","typeLabel":"string"},"description":"Job ids or shipment-leg stop ids in the relation (mutually\nexclusive with `tag`). A shipment's own id is rejected with HTTP\n400.","isRequired":true,"uniqueKey":"problem.relations.oneOf.0.items.[INDEX].oneOf.7.stops.oneOf.0","typeLabel":"string[]"},{"type":"null","items":{"type":"string"},"description":"Job ids or shipment-leg stop ids in the relation (mutually\nexclusive with `tag`). A shipment's own id is rejected with HTTP\n400.","isRequired":true,"uniqueKey":"problem.relations.oneOf.0.items.[INDEX].oneOf.7.stops.oneOf.1","typeLabel":"null"}],"isRequired":true,"uniqueKey":"problem.relations.oneOf.0.items.[INDEX].oneOf.7.stops","typeLabel":"string[] | null"},"type":{"type":"string","description":"Discriminator: always `same_route`.","enum":["same_route"],"isRequired":true,"uniqueKey":"problem.relations.oneOf.0.items.[INDEX].oneOf.7.type","typeLabel":"enum\u003cstring>"},"tag":{"oneOf":[{"type":"string","description":"Tag selecting the relation members (mutually exclusive with `stops`).","uniqueKey":"problem.relations.oneOf.0.items.[INDEX].oneOf.7.tag.oneOf.0","typeLabel":"string"},{"type":"null","description":"Tag selecting the relation members (mutually exclusive with `stops`).","uniqueKey":"problem.relations.oneOf.0.items.[INDEX].oneOf.7.tag.oneOf.1","typeLabel":"null"}],"uniqueKey":"problem.relations.oneOf.0.items.[INDEX].oneOf.7.tag","typeLabel":"string | null"}},"additionalProperties":false,"uniqueKey":"problem.relations.oneOf.0.items.[INDEX].oneOf.7","typeLabel":"Same route · object"},{"type":"object","title":"Same route","description":"A hard constraint between tasks, selected by `type`: `sequence`,\n`tag_order`, `same_vehicle`, `same_day`, `same_route`, `synchronized`,\n`time_lag`, `compatible_vehicles` or `all_or_none`.\nEach type carries only its own fields; any other `type` is rejected with\nHTTP 400.\n\nMembers are named by `stops` (job ids, or shipment-leg stop ids where\nthe type accepts them, see below). `same_vehicle`, `same_day` and\n`same_route` take **either** `stops` **or** a `tag`, not both. Every\nrelation is hard.\n\nA shipment takes part through its legs: `sequence`, `same_vehicle`,\n`same_day` and `same_route` accept a leg's stop id (`pickup.id` /\n`delivery.id`, by default `\"{shipment}:pickup\"` / `\":delivery\"`) and bind\nthat leg like a job. A leg coupled to other tasks by a `synchronized` or\n`time_lag` relation (directly, or through a `sequence` with a member that\nis) is rejected with HTTP 400, as is a `sequence` putting a delivery before\nits pickup. A shipment's own id in `stops`, or a shipment carrying the\n`tag` of a `same_vehicle` or `same_day` relation, is rejected with HTTP 400\n`not_supported`: relations never silently skip a member. `same_route`,\n`time_lag`, `compatible_vehicles`, `all_or_none` and `tag_order` reject a\nshipment with HTTP 400 as well.","required":["type","tag"],"example":{"stops":["job-1","job-2"],"type":"sequence"},"properties":{"tag":{"oneOf":[{"type":"string","description":"Tag selecting the relation members (mutually exclusive with `stops`).","isRequired":true,"uniqueKey":"problem.relations.oneOf.0.items.[INDEX].oneOf.8.tag.oneOf.0","typeLabel":"string"},{"type":"null","description":"Tag selecting the relation members (mutually exclusive with `stops`).","isRequired":true,"uniqueKey":"problem.relations.oneOf.0.items.[INDEX].oneOf.8.tag.oneOf.1","typeLabel":"null"}],"isRequired":true,"uniqueKey":"problem.relations.oneOf.0.items.[INDEX].oneOf.8.tag","typeLabel":"string | null"},"type":{"type":"string","description":"Discriminator: always `same_route`.","enum":["same_route"],"isRequired":true,"uniqueKey":"problem.relations.oneOf.0.items.[INDEX].oneOf.8.type","typeLabel":"enum\u003cstring>"},"stops":{"oneOf":[{"type":"array","items":{"type":"string","uniqueKey":"problem.relations.oneOf.0.items.[INDEX].oneOf.8.stops.oneOf.0.items.[INDEX]","typeLabel":"string"},"description":"Job ids or shipment-leg stop ids in the relation (mutually\nexclusive with `tag`). A shipment's own id is rejected with HTTP\n400.","uniqueKey":"problem.relations.oneOf.0.items.[INDEX].oneOf.8.stops.oneOf.0","typeLabel":"string[]"},{"type":"null","items":{"type":"string"},"description":"Job ids or shipment-leg stop ids in the relation (mutually\nexclusive with `tag`). A shipment's own id is rejected with HTTP\n400.","uniqueKey":"problem.relations.oneOf.0.items.[INDEX].oneOf.8.stops.oneOf.1","typeLabel":"null"}],"uniqueKey":"problem.relations.oneOf.0.items.[INDEX].oneOf.8.stops","typeLabel":"string[] | null"}},"additionalProperties":false,"uniqueKey":"problem.relations.oneOf.0.items.[INDEX].oneOf.8","typeLabel":"Same route · object"},{"type":"object","title":"Synchronized","description":"A hard constraint between tasks, selected by `type`: `sequence`,\n`tag_order`, `same_vehicle`, `same_day`, `same_route`, `synchronized`,\n`time_lag`, `compatible_vehicles` or `all_or_none`.\nEach type carries only its own fields; any other `type` is rejected with\nHTTP 400.\n\nMembers are named by `stops` (job ids, or shipment-leg stop ids where\nthe type accepts them, see below). `same_vehicle`, `same_day` and\n`same_route` take **either** `stops` **or** a `tag`, not both. Every\nrelation is hard.\n\nA shipment takes part through its legs: `sequence`, `same_vehicle`,\n`same_day` and `same_route` accept a leg's stop id (`pickup.id` /\n`delivery.id`, by default `\"{shipment}:pickup\"` / `\":delivery\"`) and bind\nthat leg like a job. A leg coupled to other tasks by a `synchronized` or\n`time_lag` relation (directly, or through a `sequence` with a member that\nis) is rejected with HTTP 400, as is a `sequence` putting a delivery before\nits pickup. A shipment's own id in `stops`, or a shipment carrying the\n`tag` of a `same_vehicle` or `same_day` relation, is rejected with HTTP 400\n`not_supported`: relations never silently skip a member. `same_route`,\n`time_lag`, `compatible_vehicles`, `all_or_none` and `tag_order` reject a\nshipment with HTTP 400 as well.","required":["max_spread_s","stops","type"],"example":{"stops":["job-1","job-2"],"type":"sequence"},"properties":{"max_spread_s":{"type":"integer","format":"int64","description":"Maximum spread between the synchronized instants in seconds\n(`0` = exact simultaneity). Required. A negative value, or one that\ndoes not fit in 32 bits, is rejected with HTTP 400 `out_of_range`.","maximum":2147483647,"minimum":0,"isRequired":true,"uniqueKey":"problem.relations.oneOf.0.items.[INDEX].oneOf.9.max_spread_s","typeLabel":"integer\u003cint64>"},"stops":{"type":"array","items":{"type":"string","uniqueKey":"problem.relations.oneOf.0.items.[INDEX].oneOf.9.stops.items.[INDEX]","typeLabel":"string"},"description":"Participating job ids, at most 8 (HTTP 400 `limit_exceeded`\nbeyond that). A shipment-leg stop id is rejected with HTTP 400;\na shipment's own id with HTTP 400 `not_supported`.","maxItems":8,"isRequired":true,"uniqueKey":"problem.relations.oneOf.0.items.[INDEX].oneOf.9.stops","typeLabel":"string[]"},"type":{"type":"string","description":"Discriminator: always `synchronized`.","enum":["synchronized"],"isRequired":true,"uniqueKey":"problem.relations.oneOf.0.items.[INDEX].oneOf.9.type","typeLabel":"enum\u003cstring>"},"on":{"oneOf":[{"type":"null","description":"Which instant is synchronized: `service_start` (default) or\n`departure` (the service end), the stop fields of the same names.","default":"service_start","uniqueKey":"problem.relations.oneOf.0.items.[INDEX].oneOf.9.on.oneOf.0","typeLabel":"null"},{"type":"string","description":"Which instant is synchronized: `service_start` (default) or\n`departure` (the service end), the stop fields of the same names.","default":"service_start","enum":["service_start","departure"],"uniqueKey":"problem.relations.oneOf.0.items.[INDEX].oneOf.9.on.oneOf.1","typeLabel":"enum\u003cstring>"}],"uniqueKey":"problem.relations.oneOf.0.items.[INDEX].oneOf.9.on","typeLabel":"null | enum\u003cstring>"}},"additionalProperties":false,"uniqueKey":"problem.relations.oneOf.0.items.[INDEX].oneOf.9","typeLabel":"Synchronized · object"},{"type":"object","title":"Time lag","description":"A hard constraint between tasks, selected by `type`: `sequence`,\n`tag_order`, `same_vehicle`, `same_day`, `same_route`, `synchronized`,\n`time_lag`, `compatible_vehicles` or `all_or_none`.\nEach type carries only its own fields; any other `type` is rejected with\nHTTP 400.\n\nMembers are named by `stops` (job ids, or shipment-leg stop ids where\nthe type accepts them, see below). `same_vehicle`, `same_day` and\n`same_route` take **either** `stops` **or** a `tag`, not both. Every\nrelation is hard.\n\nA shipment takes part through its legs: `sequence`, `same_vehicle`,\n`same_day` and `same_route` accept a leg's stop id (`pickup.id` /\n`delivery.id`, by default `\"{shipment}:pickup\"` / `\":delivery\"`) and bind\nthat leg like a job. A leg coupled to other tasks by a `synchronized` or\n`time_lag` relation (directly, or through a `sequence` with a member that\nis) is rejected with HTTP 400, as is a `sequence` putting a delivery before\nits pickup. A shipment's own id in `stops`, or a shipment carrying the\n`tag` of a `same_vehicle` or `same_day` relation, is rejected with HTTP 400\n`not_supported`: relations never silently skip a member. `same_route`,\n`time_lag`, `compatible_vehicles`, `all_or_none` and `tag_order` reject a\nshipment with HTTP 400 as well.","required":["from","to","type"],"example":{"type":"sequence"},"properties":{"from":{"type":"object","description":"The reference end.","required":["stop"],"properties":{"stop":{"type":"string","description":"The stop: a job id. A shipment's own id or a shipment-leg stop id is\nrejected with HTTP 400.","example":"job-1","isRequired":true,"uniqueKey":"problem.relations.oneOf.0.items.[INDEX].oneOf.10.from.stop","typeLabel":"string"},"on":{"oneOf":[{"type":"null","description":"Which instant of the job the bound is measured at: `service_start`\n(default) or `departure`, the stop fields of the same names.","default":"service_start","uniqueKey":"problem.relations.oneOf.0.items.[INDEX].oneOf.10.from.on.oneOf.0","typeLabel":"null"},{"type":"string","description":"Which instant of the job the bound is measured at: `service_start`\n(default) or `departure`, the stop fields of the same names.","default":"service_start","enum":["service_start","departure"],"uniqueKey":"problem.relations.oneOf.0.items.[INDEX].oneOf.10.from.on.oneOf.1","typeLabel":"enum\u003cstring>"}],"uniqueKey":"problem.relations.oneOf.0.items.[INDEX].oneOf.10.from.on","typeLabel":"null | enum\u003cstring>"}},"additionalProperties":false,"example":{"on":"departure","stop":"job-1"},"isRequired":true,"uniqueKey":"problem.relations.oneOf.0.items.[INDEX].oneOf.10.from","typeLabel":"object"},"to":{"type":"object","description":"The bounded end.","required":["stop"],"properties":{"stop":{"type":"string","description":"The stop: a job id. A shipment's own id or a shipment-leg stop id is\nrejected with HTTP 400.","example":"job-1","isRequired":true,"uniqueKey":"problem.relations.oneOf.0.items.[INDEX].oneOf.10.to.stop","typeLabel":"string"},"on":{"oneOf":[{"type":"null","description":"Which instant of the job the bound is measured at: `service_start`\n(default) or `departure`, the stop fields of the same names.","default":"service_start","uniqueKey":"problem.relations.oneOf.0.items.[INDEX].oneOf.10.to.on.oneOf.0","typeLabel":"null"},{"type":"string","description":"Which instant of the job the bound is measured at: `service_start`\n(default) or `departure`, the stop fields of the same names.","default":"service_start","enum":["service_start","departure"],"uniqueKey":"problem.relations.oneOf.0.items.[INDEX].oneOf.10.to.on.oneOf.1","typeLabel":"enum\u003cstring>"}],"uniqueKey":"problem.relations.oneOf.0.items.[INDEX].oneOf.10.to.on","typeLabel":"null | enum\u003cstring>"}},"additionalProperties":false,"example":{"on":"departure","stop":"job-1"},"isRequired":true,"uniqueKey":"problem.relations.oneOf.0.items.[INDEX].oneOf.10.to","typeLabel":"object"},"type":{"type":"string","description":"Discriminator: always `time_lag`.","enum":["time_lag"],"isRequired":true,"uniqueKey":"problem.relations.oneOf.0.items.[INDEX].oneOf.10.type","typeLabel":"enum\u003cstring>"},"max_s":{"oneOf":[{"type":"integer","format":"int64","description":"Upper bound on `t(to) − t(from)` in seconds. Absent = unbounded.\nMust fit in 32 bits and be `>= min_s` (HTTP 400 otherwise).","maximum":2147483647,"minimum":-2147483648,"uniqueKey":"problem.relations.oneOf.0.items.[INDEX].oneOf.10.max_s.oneOf.0","typeLabel":"integer\u003cint64>"},{"type":"null","format":"int64","description":"Upper bound on `t(to) − t(from)` in seconds. Absent = unbounded.\nMust fit in 32 bits and be `>= min_s` (HTTP 400 otherwise).","maximum":2147483647,"minimum":-2147483648,"uniqueKey":"problem.relations.oneOf.0.items.[INDEX].oneOf.10.max_s.oneOf.1","typeLabel":"null"}],"uniqueKey":"problem.relations.oneOf.0.items.[INDEX].oneOf.10.max_s","typeLabel":"integer\u003cint64> | null"},"min_s":{"oneOf":[{"type":"integer","format":"int64","description":"Lower bound on `t(to) − t(from)` in seconds. Default `0`. Must fit\nin 32 bits.","default":0,"maximum":2147483647,"minimum":-2147483648,"uniqueKey":"problem.relations.oneOf.0.items.[INDEX].oneOf.10.min_s.oneOf.0","typeLabel":"integer\u003cint64>"},{"type":"null","format":"int64","description":"Lower bound on `t(to) − t(from)` in seconds. Default `0`. Must fit\nin 32 bits.","default":0,"maximum":2147483647,"minimum":-2147483648,"uniqueKey":"problem.relations.oneOf.0.items.[INDEX].oneOf.10.min_s.oneOf.1","typeLabel":"null"}],"uniqueKey":"problem.relations.oneOf.0.items.[INDEX].oneOf.10.min_s","typeLabel":"integer\u003cint64> | null"}},"additionalProperties":false,"uniqueKey":"problem.relations.oneOf.0.items.[INDEX].oneOf.10","typeLabel":"Time lag · object"},{"type":"object","title":"Compatible vehicles","description":"A hard constraint between tasks, selected by `type`: `sequence`,\n`tag_order`, `same_vehicle`, `same_day`, `same_route`, `synchronized`,\n`time_lag`, `compatible_vehicles` or `all_or_none`.\nEach type carries only its own fields; any other `type` is rejected with\nHTTP 400.\n\nMembers are named by `stops` (job ids, or shipment-leg stop ids where\nthe type accepts them, see below). `same_vehicle`, `same_day` and\n`same_route` take **either** `stops` **or** a `tag`, not both. Every\nrelation is hard.\n\nA shipment takes part through its legs: `sequence`, `same_vehicle`,\n`same_day` and `same_route` accept a leg's stop id (`pickup.id` /\n`delivery.id`, by default `\"{shipment}:pickup\"` / `\":delivery\"`) and bind\nthat leg like a job. A leg coupled to other tasks by a `synchronized` or\n`time_lag` relation (directly, or through a `sequence` with a member that\nis) is rejected with HTTP 400, as is a `sequence` putting a delivery before\nits pickup. A shipment's own id in `stops`, or a shipment carrying the\n`tag` of a `same_vehicle` or `same_day` relation, is rejected with HTTP 400\n`not_supported`: relations never silently skip a member. `same_route`,\n`time_lag`, `compatible_vehicles`, `all_or_none` and `tag_order` reject a\nshipment with HTTP 400 as well.","required":["stops","type"],"example":{"stops":["job-1","job-2"],"type":"sequence"},"properties":{"stops":{"type":"array","items":{"type":"string","uniqueKey":"problem.relations.oneOf.0.items.[INDEX].oneOf.11.stops.items.[INDEX]","typeLabel":"string"},"description":"Job ids, 2 to 16. A shipment's own id or a shipment-leg stop id\nis rejected with HTTP 400.","example":["job-1","job-2"],"maxItems":16,"minItems":2,"isRequired":true,"uniqueKey":"problem.relations.oneOf.0.items.[INDEX].oneOf.11.stops","typeLabel":"string[]"},"type":{"type":"string","description":"Discriminator: always `compatible_vehicles`.","enum":["compatible_vehicles"],"isRequired":true,"uniqueKey":"problem.relations.oneOf.0.items.[INDEX].oneOf.11.type","typeLabel":"enum\u003cstring>"}},"additionalProperties":false,"uniqueKey":"problem.relations.oneOf.0.items.[INDEX].oneOf.11","typeLabel":"Compatible vehicles · object"},{"type":"object","title":"All or none","description":"A hard constraint between tasks, selected by `type`: `sequence`,\n`tag_order`, `same_vehicle`, `same_day`, `same_route`, `synchronized`,\n`time_lag`, `compatible_vehicles` or `all_or_none`.\nEach type carries only its own fields; any other `type` is rejected with\nHTTP 400.\n\nMembers are named by `stops` (job ids, or shipment-leg stop ids where\nthe type accepts them, see below). `same_vehicle`, `same_day` and\n`same_route` take **either** `stops` **or** a `tag`, not both. Every\nrelation is hard.\n\nA shipment takes part through its legs: `sequence`, `same_vehicle`,\n`same_day` and `same_route` accept a leg's stop id (`pickup.id` /\n`delivery.id`, by default `\"{shipment}:pickup\"` / `\":delivery\"`) and bind\nthat leg like a job. A leg coupled to other tasks by a `synchronized` or\n`time_lag` relation (directly, or through a `sequence` with a member that\nis) is rejected with HTTP 400, as is a `sequence` putting a delivery before\nits pickup. A shipment's own id in `stops`, or a shipment carrying the\n`tag` of a `same_vehicle` or `same_day` relation, is rejected with HTTP 400\n`not_supported`: relations never silently skip a member. `same_route`,\n`time_lag`, `compatible_vehicles`, `all_or_none` and `tag_order` reject a\nshipment with HTTP 400 as well.","required":["stops","type"],"example":{"stops":["job-1","job-2"],"type":"sequence"},"properties":{"stops":{"type":"array","items":{"type":"string","uniqueKey":"problem.relations.oneOf.0.items.[INDEX].oneOf.12.stops.items.[INDEX]","typeLabel":"string"},"description":"Job ids, at least two. A shipment's own id or a shipment-leg stop id\nis rejected with HTTP 400.","example":["job-1","job-2"],"minItems":2,"isRequired":true,"uniqueKey":"problem.relations.oneOf.0.items.[INDEX].oneOf.12.stops","typeLabel":"string[]"},"type":{"type":"string","description":"Discriminator: always `all_or_none`.","enum":["all_or_none"],"isRequired":true,"uniqueKey":"problem.relations.oneOf.0.items.[INDEX].oneOf.12.type","typeLabel":"enum\u003cstring>"}},"additionalProperties":false,"uniqueKey":"problem.relations.oneOf.0.items.[INDEX].oneOf.12","typeLabel":"All or none · object"}],"uniqueKey":"problem.relations.oneOf.0.items.[INDEX]","typeLabel":"Sequence · object · Consecutive · object · Tag order · object · Same vehicle · object · Same vehicle · object · Same day · object · Same day · object · Same route · object · Same route · object · Synchronized · object · Time lag · object · Compatible vehicles · object · All or none · object"},"description":"Ordering, co-assignment and synchronization constraints.","uniqueKey":"problem.relations.oneOf.0","typeLabel":"Sequence · object · Consecutive · object · Tag order · object · Same vehicle · object · Same vehicle · object · Same day · object · Same day · object · Same route · object · Same route · object · Synchronized · object · Time lag · object · Compatible vehicles · object · All or none · object[]"},{"type":"null","items":{"oneOf":[{"type":"object","title":"Sequence","description":"A hard constraint between tasks, selected by `type`: `sequence`,\n`tag_order`, `same_vehicle`, `same_day`, `same_route`, `synchronized`,\n`time_lag`, `compatible_vehicles` or `all_or_none`.\nEach type carries only its own fields; any other `type` is rejected with\nHTTP 400.\n\nMembers are named by `stops` (job ids, or shipment-leg stop ids where\nthe type accepts them, see below). `same_vehicle`, `same_day` and\n`same_route` take **either** `stops` **or** a `tag`, not both. Every\nrelation is hard.\n\nA shipment takes part through its legs: `sequence`, `same_vehicle`,\n`same_day` and `same_route` accept a leg's stop id (`pickup.id` /\n`delivery.id`, by default `\"{shipment}:pickup\"` / `\":delivery\"`) and bind\nthat leg like a job. A leg coupled to other tasks by a `synchronized` or\n`time_lag` relation (directly, or through a `sequence` with a member that\nis) is rejected with HTTP 400, as is a `sequence` putting a delivery before\nits pickup. A shipment's own id in `stops`, or a shipment carrying the\n`tag` of a `same_vehicle` or `same_day` relation, is rejected with HTTP 400\n`not_supported`: relations never silently skip a member. `same_route`,\n`time_lag`, `compatible_vehicles`, `all_or_none` and `tag_order` reject a\nshipment with HTTP 400 as well.","required":["stops","type"],"example":{"stops":["job-1","job-2"],"type":"sequence"},"properties":{"stops":{"type":"array","items":{"type":"string"},"description":"Job ids or shipment-leg stop ids (`pickup.id` / `delivery.id`, by\ndefault `\"{shipment}:pickup\"` / `\"{shipment}:delivery\"`), in the\norder they must be served. A shipment's own id is\nrejected with HTTP 400 `not_supported`."},"type":{"type":"string","description":"Discriminator: always `sequence`.","enum":["sequence"]}},"additionalProperties":false},{"type":"object","title":"Consecutive","description":"A hard constraint between tasks, selected by `type`: `sequence`,\n`tag_order`, `same_vehicle`, `same_day`, `same_route`, `synchronized`,\n`time_lag`, `compatible_vehicles` or `all_or_none`.\nEach type carries only its own fields; any other `type` is rejected with\nHTTP 400.\n\nMembers are named by `stops` (job ids, or shipment-leg stop ids where\nthe type accepts them, see below). `same_vehicle`, `same_day` and\n`same_route` take **either** `stops` **or** a `tag`, not both. Every\nrelation is hard.\n\nA shipment takes part through its legs: `sequence`, `same_vehicle`,\n`same_day` and `same_route` accept a leg's stop id (`pickup.id` /\n`delivery.id`, by default `\"{shipment}:pickup\"` / `\":delivery\"`) and bind\nthat leg like a job. A leg coupled to other tasks by a `synchronized` or\n`time_lag` relation (directly, or through a `sequence` with a member that\nis) is rejected with HTTP 400, as is a `sequence` putting a delivery before\nits pickup. A shipment's own id in `stops`, or a shipment carrying the\n`tag` of a `same_vehicle` or `same_day` relation, is rejected with HTTP 400\n`not_supported`: relations never silently skip a member. `same_route`,\n`time_lag`, `compatible_vehicles`, `all_or_none` and `tag_order` reject a\nshipment with HTTP 400 as well.","required":["stops","type"],"example":{"stops":["job-1","job-2"],"type":"sequence"},"properties":{"stops":{"type":"array","items":{"type":"string"},"description":"Job ids or shipment-leg stop ids, in the order they must be served\nback to back. At least 2. A stop has one successor and one predecessor\nacross all `consecutive` relations, so `[a, b]` and `[b, c]` may\noverlap but `[a, b]` and `[a, c]` may not. A shipment's own id is rejected with HTTP\n400 `not_supported`.","minItems":2},"type":{"type":"string","description":"Discriminator: always `consecutive`.","enum":["consecutive"]}},"additionalProperties":false},{"type":"object","title":"Tag order","description":"A hard constraint between tasks, selected by `type`: `sequence`,\n`tag_order`, `same_vehicle`, `same_day`, `same_route`, `synchronized`,\n`time_lag`, `compatible_vehicles` or `all_or_none`.\nEach type carries only its own fields; any other `type` is rejected with\nHTTP 400.\n\nMembers are named by `stops` (job ids, or shipment-leg stop ids where\nthe type accepts them, see below). `same_vehicle`, `same_day` and\n`same_route` take **either** `stops` **or** a `tag`, not both. Every\nrelation is hard.\n\nA shipment takes part through its legs: `sequence`, `same_vehicle`,\n`same_day` and `same_route` accept a leg's stop id (`pickup.id` /\n`delivery.id`, by default `\"{shipment}:pickup\"` / `\":delivery\"`) and bind\nthat leg like a job. A leg coupled to other tasks by a `synchronized` or\n`time_lag` relation (directly, or through a `sequence` with a member that\nis) is rejected with HTTP 400, as is a `sequence` putting a delivery before\nits pickup. A shipment's own id in `stops`, or a shipment carrying the\n`tag` of a `same_vehicle` or `same_day` relation, is rejected with HTTP 400\n`not_supported`: relations never silently skip a member. `same_route`,\n`time_lag`, `compatible_vehicles`, `all_or_none` and `tag_order` reject a\nshipment with HTTP 400 as well.","required":["tags","type"],"example":{"type":"sequence"},"properties":{"tags":{"type":"array","items":{"type":"string"},"description":"Tag labels in precedence order. Requires at least 2 entries.","minItems":2},"type":{"type":"string","description":"Discriminator: always `tag_order`.","enum":["tag_order"]}},"additionalProperties":false},{"type":"object","title":"Same vehicle","description":"A hard constraint between tasks, selected by `type`: `sequence`,\n`tag_order`, `same_vehicle`, `same_day`, `same_route`, `synchronized`,\n`time_lag`, `compatible_vehicles` or `all_or_none`.\nEach type carries only its own fields; any other `type` is rejected with\nHTTP 400.\n\nMembers are named by `stops` (job ids, or shipment-leg stop ids where\nthe type accepts them, see below). `same_vehicle`, `same_day` and\n`same_route` take **either** `stops` **or** a `tag`, not both. Every\nrelation is hard.\n\nA shipment takes part through its legs: `sequence`, `same_vehicle`,\n`same_day` and `same_route` accept a leg's stop id (`pickup.id` /\n`delivery.id`, by default `\"{shipment}:pickup\"` / `\":delivery\"`) and bind\nthat leg like a job. A leg coupled to other tasks by a `synchronized` or\n`time_lag` relation (directly, or through a `sequence` with a member that\nis) is rejected with HTTP 400, as is a `sequence` putting a delivery before\nits pickup. A shipment's own id in `stops`, or a shipment carrying the\n`tag` of a `same_vehicle` or `same_day` relation, is rejected with HTTP 400\n`not_supported`: relations never silently skip a member. `same_route`,\n`time_lag`, `compatible_vehicles`, `all_or_none` and `tag_order` reject a\nshipment with HTTP 400 as well.","required":["type","stops"],"example":{"stops":["job-1","job-2"],"type":"sequence"},"properties":{"stops":{"oneOf":[{"type":"array","items":{"type":"string"},"description":"Job ids or shipment-leg stop ids in the relation (mutually\nexclusive with `tag`). A shipment's own id is rejected with\nHTTP 400 `not_supported`."},{"type":"null","items":{"type":"string"},"description":"Job ids or shipment-leg stop ids in the relation (mutually\nexclusive with `tag`). A shipment's own id is rejected with\nHTTP 400 `not_supported`."}]},"tag":{"oneOf":[{"type":"string","description":"Tag selecting the relation members (mutually exclusive with `stops`)."},{"type":"null","description":"Tag selecting the relation members (mutually exclusive with `stops`)."}]},"type":{"type":"string","description":"Discriminator: always `same_vehicle`.","enum":["same_vehicle"]}},"additionalProperties":false},{"type":"object","title":"Same vehicle","description":"A hard constraint between tasks, selected by `type`: `sequence`,\n`tag_order`, `same_vehicle`, `same_day`, `same_route`, `synchronized`,\n`time_lag`, `compatible_vehicles` or `all_or_none`.\nEach type carries only its own fields; any other `type` is rejected with\nHTTP 400.\n\nMembers are named by `stops` (job ids, or shipment-leg stop ids where\nthe type accepts them, see below). `same_vehicle`, `same_day` and\n`same_route` take **either** `stops` **or** a `tag`, not both. Every\nrelation is hard.\n\nA shipment takes part through its legs: `sequence`, `same_vehicle`,\n`same_day` and `same_route` accept a leg's stop id (`pickup.id` /\n`delivery.id`, by default `\"{shipment}:pickup\"` / `\":delivery\"`) and bind\nthat leg like a job. A leg coupled to other tasks by a `synchronized` or\n`time_lag` relation (directly, or through a `sequence` with a member that\nis) is rejected with HTTP 400, as is a `sequence` putting a delivery before\nits pickup. A shipment's own id in `stops`, or a shipment carrying the\n`tag` of a `same_vehicle` or `same_day` relation, is rejected with HTTP 400\n`not_supported`: relations never silently skip a member. `same_route`,\n`time_lag`, `compatible_vehicles`, `all_or_none` and `tag_order` reject a\nshipment with HTTP 400 as well.","required":["type","tag"],"example":{"stops":["job-1","job-2"],"type":"sequence"},"properties":{"stops":{"oneOf":[{"type":"array","items":{"type":"string"},"description":"Job ids or shipment-leg stop ids in the relation (mutually\nexclusive with `tag`). A shipment's own id is rejected with\nHTTP 400 `not_supported`."},{"type":"null","items":{"type":"string"},"description":"Job ids or shipment-leg stop ids in the relation (mutually\nexclusive with `tag`). A shipment's own id is rejected with\nHTTP 400 `not_supported`."}]},"tag":{"oneOf":[{"type":"string","description":"Tag selecting the relation members (mutually exclusive with `stops`)."},{"type":"null","description":"Tag selecting the relation members (mutually exclusive with `stops`)."}]},"type":{"type":"string","description":"Discriminator: always `same_vehicle`.","enum":["same_vehicle"]}},"additionalProperties":false},{"type":"object","title":"Same day","description":"A hard constraint between tasks, selected by `type`: `sequence`,\n`tag_order`, `same_vehicle`, `same_day`, `same_route`, `synchronized`,\n`time_lag`, `compatible_vehicles` or `all_or_none`.\nEach type carries only its own fields; any other `type` is rejected with\nHTTP 400.\n\nMembers are named by `stops` (job ids, or shipment-leg stop ids where\nthe type accepts them, see below). `same_vehicle`, `same_day` and\n`same_route` take **either** `stops` **or** a `tag`, not both. Every\nrelation is hard.\n\nA shipment takes part through its legs: `sequence`, `same_vehicle`,\n`same_day` and `same_route` accept a leg's stop id (`pickup.id` /\n`delivery.id`, by default `\"{shipment}:pickup\"` / `\":delivery\"`) and bind\nthat leg like a job. A leg coupled to other tasks by a `synchronized` or\n`time_lag` relation (directly, or through a `sequence` with a member that\nis) is rejected with HTTP 400, as is a `sequence` putting a delivery before\nits pickup. A shipment's own id in `stops`, or a shipment carrying the\n`tag` of a `same_vehicle` or `same_day` relation, is rejected with HTTP 400\n`not_supported`: relations never silently skip a member. `same_route`,\n`time_lag`, `compatible_vehicles`, `all_or_none` and `tag_order` reject a\nshipment with HTTP 400 as well.","required":["type","stops"],"example":{"stops":["job-1","job-2"],"type":"sequence"},"properties":{"stops":{"oneOf":[{"type":"array","items":{"type":"string"},"description":"Job ids or shipment-leg stop ids in the relation (mutually\nexclusive with `tag`). A shipment's own id is rejected with\nHTTP 400 `not_supported`."},{"type":"null","items":{"type":"string"},"description":"Job ids or shipment-leg stop ids in the relation (mutually\nexclusive with `tag`). A shipment's own id is rejected with\nHTTP 400 `not_supported`."}]},"tag":{"oneOf":[{"type":"string","description":"Tag selecting the relation members (mutually exclusive with `stops`)."},{"type":"null","description":"Tag selecting the relation members (mutually exclusive with `stops`)."}]},"type":{"type":"string","description":"Discriminator: always `same_day`.","enum":["same_day"]}},"additionalProperties":false},{"type":"object","title":"Same day","description":"A hard constraint between tasks, selected by `type`: `sequence`,\n`tag_order`, `same_vehicle`, `same_day`, `same_route`, `synchronized`,\n`time_lag`, `compatible_vehicles` or `all_or_none`.\nEach type carries only its own fields; any other `type` is rejected with\nHTTP 400.\n\nMembers are named by `stops` (job ids, or shipment-leg stop ids where\nthe type accepts them, see below). `same_vehicle`, `same_day` and\n`same_route` take **either** `stops` **or** a `tag`, not both. Every\nrelation is hard.\n\nA shipment takes part through its legs: `sequence`, `same_vehicle`,\n`same_day` and `same_route` accept a leg's stop id (`pickup.id` /\n`delivery.id`, by default `\"{shipment}:pickup\"` / `\":delivery\"`) and bind\nthat leg like a job. A leg coupled to other tasks by a `synchronized` or\n`time_lag` relation (directly, or through a `sequence` with a member that\nis) is rejected with HTTP 400, as is a `sequence` putting a delivery before\nits pickup. A shipment's own id in `stops`, or a shipment carrying the\n`tag` of a `same_vehicle` or `same_day` relation, is rejected with HTTP 400\n`not_supported`: relations never silently skip a member. `same_route`,\n`time_lag`, `compatible_vehicles`, `all_or_none` and `tag_order` reject a\nshipment with HTTP 400 as well.","required":["type","tag"],"example":{"stops":["job-1","job-2"],"type":"sequence"},"properties":{"stops":{"oneOf":[{"type":"array","items":{"type":"string"},"description":"Job ids or shipment-leg stop ids in the relation (mutually\nexclusive with `tag`). A shipment's own id is rejected with\nHTTP 400 `not_supported`."},{"type":"null","items":{"type":"string"},"description":"Job ids or shipment-leg stop ids in the relation (mutually\nexclusive with `tag`). A shipment's own id is rejected with\nHTTP 400 `not_supported`."}]},"tag":{"oneOf":[{"type":"string","description":"Tag selecting the relation members (mutually exclusive with `stops`)."},{"type":"null","description":"Tag selecting the relation members (mutually exclusive with `stops`)."}]},"type":{"type":"string","description":"Discriminator: always `same_day`.","enum":["same_day"]}},"additionalProperties":false},{"type":"object","title":"Same route","description":"A hard constraint between tasks, selected by `type`: `sequence`,\n`tag_order`, `same_vehicle`, `same_day`, `same_route`, `synchronized`,\n`time_lag`, `compatible_vehicles` or `all_or_none`.\nEach type carries only its own fields; any other `type` is rejected with\nHTTP 400.\n\nMembers are named by `stops` (job ids, or shipment-leg stop ids where\nthe type accepts them, see below). `same_vehicle`, `same_day` and\n`same_route` take **either** `stops` **or** a `tag`, not both. Every\nrelation is hard.\n\nA shipment takes part through its legs: `sequence`, `same_vehicle`,\n`same_day` and `same_route` accept a leg's stop id (`pickup.id` /\n`delivery.id`, by default `\"{shipment}:pickup\"` / `\":delivery\"`) and bind\nthat leg like a job. A leg coupled to other tasks by a `synchronized` or\n`time_lag` relation (directly, or through a `sequence` with a member that\nis) is rejected with HTTP 400, as is a `sequence` putting a delivery before\nits pickup. A shipment's own id in `stops`, or a shipment carrying the\n`tag` of a `same_vehicle` or `same_day` relation, is rejected with HTTP 400\n`not_supported`: relations never silently skip a member. `same_route`,\n`time_lag`, `compatible_vehicles`, `all_or_none` and `tag_order` reject a\nshipment with HTTP 400 as well.","required":["type","stops"],"example":{"stops":["job-1","job-2"],"type":"sequence"},"properties":{"stops":{"oneOf":[{"type":"array","items":{"type":"string"},"description":"Job ids or shipment-leg stop ids in the relation (mutually\nexclusive with `tag`). A shipment's own id is rejected with HTTP\n400."},{"type":"null","items":{"type":"string"},"description":"Job ids or shipment-leg stop ids in the relation (mutually\nexclusive with `tag`). A shipment's own id is rejected with HTTP\n400."}]},"tag":{"oneOf":[{"type":"string","description":"Tag selecting the relation members (mutually exclusive with `stops`)."},{"type":"null","description":"Tag selecting the relation members (mutually exclusive with `stops`)."}]},"type":{"type":"string","description":"Discriminator: always `same_route`.","enum":["same_route"]}},"additionalProperties":false},{"type":"object","title":"Same route","description":"A hard constraint between tasks, selected by `type`: `sequence`,\n`tag_order`, `same_vehicle`, `same_day`, `same_route`, `synchronized`,\n`time_lag`, `compatible_vehicles` or `all_or_none`.\nEach type carries only its own fields; any other `type` is rejected with\nHTTP 400.\n\nMembers are named by `stops` (job ids, or shipment-leg stop ids where\nthe type accepts them, see below). `same_vehicle`, `same_day` and\n`same_route` take **either** `stops` **or** a `tag`, not both. Every\nrelation is hard.\n\nA shipment takes part through its legs: `sequence`, `same_vehicle`,\n`same_day` and `same_route` accept a leg's stop id (`pickup.id` /\n`delivery.id`, by default `\"{shipment}:pickup\"` / `\":delivery\"`) and bind\nthat leg like a job. A leg coupled to other tasks by a `synchronized` or\n`time_lag` relation (directly, or through a `sequence` with a member that\nis) is rejected with HTTP 400, as is a `sequence` putting a delivery before\nits pickup. A shipment's own id in `stops`, or a shipment carrying the\n`tag` of a `same_vehicle` or `same_day` relation, is rejected with HTTP 400\n`not_supported`: relations never silently skip a member. `same_route`,\n`time_lag`, `compatible_vehicles`, `all_or_none` and `tag_order` reject a\nshipment with HTTP 400 as well.","required":["type","tag"],"example":{"stops":["job-1","job-2"],"type":"sequence"},"properties":{"stops":{"oneOf":[{"type":"array","items":{"type":"string"},"description":"Job ids or shipment-leg stop ids in the relation (mutually\nexclusive with `tag`). A shipment's own id is rejected with HTTP\n400."},{"type":"null","items":{"type":"string"},"description":"Job ids or shipment-leg stop ids in the relation (mutually\nexclusive with `tag`). A shipment's own id is rejected with HTTP\n400."}]},"tag":{"oneOf":[{"type":"string","description":"Tag selecting the relation members (mutually exclusive with `stops`)."},{"type":"null","description":"Tag selecting the relation members (mutually exclusive with `stops`)."}]},"type":{"type":"string","description":"Discriminator: always `same_route`.","enum":["same_route"]}},"additionalProperties":false},{"type":"object","title":"Synchronized","description":"A hard constraint between tasks, selected by `type`: `sequence`,\n`tag_order`, `same_vehicle`, `same_day`, `same_route`, `synchronized`,\n`time_lag`, `compatible_vehicles` or `all_or_none`.\nEach type carries only its own fields; any other `type` is rejected with\nHTTP 400.\n\nMembers are named by `stops` (job ids, or shipment-leg stop ids where\nthe type accepts them, see below). `same_vehicle`, `same_day` and\n`same_route` take **either** `stops` **or** a `tag`, not both. Every\nrelation is hard.\n\nA shipment takes part through its legs: `sequence`, `same_vehicle`,\n`same_day` and `same_route` accept a leg's stop id (`pickup.id` /\n`delivery.id`, by default `\"{shipment}:pickup\"` / `\":delivery\"`) and bind\nthat leg like a job. A leg coupled to other tasks by a `synchronized` or\n`time_lag` relation (directly, or through a `sequence` with a member that\nis) is rejected with HTTP 400, as is a `sequence` putting a delivery before\nits pickup. A shipment's own id in `stops`, or a shipment carrying the\n`tag` of a `same_vehicle` or `same_day` relation, is rejected with HTTP 400\n`not_supported`: relations never silently skip a member. `same_route`,\n`time_lag`, `compatible_vehicles`, `all_or_none` and `tag_order` reject a\nshipment with HTTP 400 as well.","required":["max_spread_s","stops","type"],"example":{"stops":["job-1","job-2"],"type":"sequence"},"properties":{"max_spread_s":{"type":"integer","format":"int64","description":"Maximum spread between the synchronized instants in seconds\n(`0` = exact simultaneity). Required. A negative value, or one that\ndoes not fit in 32 bits, is rejected with HTTP 400 `out_of_range`.","maximum":2147483647,"minimum":0},"on":{"oneOf":[{"type":"null","description":"Which instant is synchronized: `service_start` (default) or\n`departure` (the service end), the stop fields of the same names.","default":"service_start"},{"type":"string","description":"Which instant is synchronized: `service_start` (default) or\n`departure` (the service end), the stop fields of the same names.","default":"service_start","enum":["service_start","departure"]}]},"stops":{"type":"array","items":{"type":"string"},"description":"Participating job ids, at most 8 (HTTP 400 `limit_exceeded`\nbeyond that). A shipment-leg stop id is rejected with HTTP 400;\na shipment's own id with HTTP 400 `not_supported`.","maxItems":8},"type":{"type":"string","description":"Discriminator: always `synchronized`.","enum":["synchronized"]}},"additionalProperties":false},{"type":"object","title":"Time lag","description":"A hard constraint between tasks, selected by `type`: `sequence`,\n`tag_order`, `same_vehicle`, `same_day`, `same_route`, `synchronized`,\n`time_lag`, `compatible_vehicles` or `all_or_none`.\nEach type carries only its own fields; any other `type` is rejected with\nHTTP 400.\n\nMembers are named by `stops` (job ids, or shipment-leg stop ids where\nthe type accepts them, see below). `same_vehicle`, `same_day` and\n`same_route` take **either** `stops` **or** a `tag`, not both. Every\nrelation is hard.\n\nA shipment takes part through its legs: `sequence`, `same_vehicle`,\n`same_day` and `same_route` accept a leg's stop id (`pickup.id` /\n`delivery.id`, by default `\"{shipment}:pickup\"` / `\":delivery\"`) and bind\nthat leg like a job. A leg coupled to other tasks by a `synchronized` or\n`time_lag` relation (directly, or through a `sequence` with a member that\nis) is rejected with HTTP 400, as is a `sequence` putting a delivery before\nits pickup. A shipment's own id in `stops`, or a shipment carrying the\n`tag` of a `same_vehicle` or `same_day` relation, is rejected with HTTP 400\n`not_supported`: relations never silently skip a member. `same_route`,\n`time_lag`, `compatible_vehicles`, `all_or_none` and `tag_order` reject a\nshipment with HTTP 400 as well.","required":["from","to","type"],"example":{"type":"sequence"},"properties":{"from":{"type":"object","description":"The reference end.","required":["stop"],"properties":{"on":{"oneOf":[{"type":"null","description":"Which instant of the job the bound is measured at: `service_start`\n(default) or `departure`, the stop fields of the same names.","default":"service_start"},{"type":"string","description":"Which instant of the job the bound is measured at: `service_start`\n(default) or `departure`, the stop fields of the same names.","default":"service_start","enum":["service_start","departure"]}]},"stop":{"type":"string","description":"The stop: a job id. A shipment's own id or a shipment-leg stop id is\nrejected with HTTP 400.","example":"job-1"}},"additionalProperties":false,"example":{"on":"departure","stop":"job-1"}},"max_s":{"oneOf":[{"type":"integer","format":"int64","description":"Upper bound on `t(to) − t(from)` in seconds. Absent = unbounded.\nMust fit in 32 bits and be `>= min_s` (HTTP 400 otherwise).","maximum":2147483647,"minimum":-2147483648},{"type":"null","format":"int64","description":"Upper bound on `t(to) − t(from)` in seconds. Absent = unbounded.\nMust fit in 32 bits and be `>= min_s` (HTTP 400 otherwise).","maximum":2147483647,"minimum":-2147483648}]},"min_s":{"oneOf":[{"type":"integer","format":"int64","description":"Lower bound on `t(to) − t(from)` in seconds. Default `0`. Must fit\nin 32 bits.","default":0,"maximum":2147483647,"minimum":-2147483648},{"type":"null","format":"int64","description":"Lower bound on `t(to) − t(from)` in seconds. Default `0`. Must fit\nin 32 bits.","default":0,"maximum":2147483647,"minimum":-2147483648}]},"to":{"type":"object","description":"The bounded end.","required":["stop"],"properties":{"on":{"oneOf":[{"type":"null","description":"Which instant of the job the bound is measured at: `service_start`\n(default) or `departure`, the stop fields of the same names.","default":"service_start"},{"type":"string","description":"Which instant of the job the bound is measured at: `service_start`\n(default) or `departure`, the stop fields of the same names.","default":"service_start","enum":["service_start","departure"]}]},"stop":{"type":"string","description":"The stop: a job id. A shipment's own id or a shipment-leg stop id is\nrejected with HTTP 400.","example":"job-1"}},"additionalProperties":false,"example":{"on":"departure","stop":"job-1"}},"type":{"type":"string","description":"Discriminator: always `time_lag`.","enum":["time_lag"]}},"additionalProperties":false},{"type":"object","title":"Compatible vehicles","description":"A hard constraint between tasks, selected by `type`: `sequence`,\n`tag_order`, `same_vehicle`, `same_day`, `same_route`, `synchronized`,\n`time_lag`, `compatible_vehicles` or `all_or_none`.\nEach type carries only its own fields; any other `type` is rejected with\nHTTP 400.\n\nMembers are named by `stops` (job ids, or shipment-leg stop ids where\nthe type accepts them, see below). `same_vehicle`, `same_day` and\n`same_route` take **either** `stops` **or** a `tag`, not both. Every\nrelation is hard.\n\nA shipment takes part through its legs: `sequence`, `same_vehicle`,\n`same_day` and `same_route` accept a leg's stop id (`pickup.id` /\n`delivery.id`, by default `\"{shipment}:pickup\"` / `\":delivery\"`) and bind\nthat leg like a job. A leg coupled to other tasks by a `synchronized` or\n`time_lag` relation (directly, or through a `sequence` with a member that\nis) is rejected with HTTP 400, as is a `sequence` putting a delivery before\nits pickup. A shipment's own id in `stops`, or a shipment carrying the\n`tag` of a `same_vehicle` or `same_day` relation, is rejected with HTTP 400\n`not_supported`: relations never silently skip a member. `same_route`,\n`time_lag`, `compatible_vehicles`, `all_or_none` and `tag_order` reject a\nshipment with HTTP 400 as well.","required":["stops","type"],"example":{"stops":["job-1","job-2"],"type":"sequence"},"properties":{"stops":{"type":"array","items":{"type":"string"},"description":"Job ids, 2 to 16. A shipment's own id or a shipment-leg stop id\nis rejected with HTTP 400.","example":["job-1","job-2"],"maxItems":16,"minItems":2},"type":{"type":"string","description":"Discriminator: always `compatible_vehicles`.","enum":["compatible_vehicles"]}},"additionalProperties":false},{"type":"object","title":"All or none","description":"A hard constraint between tasks, selected by `type`: `sequence`,\n`tag_order`, `same_vehicle`, `same_day`, `same_route`, `synchronized`,\n`time_lag`, `compatible_vehicles` or `all_or_none`.\nEach type carries only its own fields; any other `type` is rejected with\nHTTP 400.\n\nMembers are named by `stops` (job ids, or shipment-leg stop ids where\nthe type accepts them, see below). `same_vehicle`, `same_day` and\n`same_route` take **either** `stops` **or** a `tag`, not both. Every\nrelation is hard.\n\nA shipment takes part through its legs: `sequence`, `same_vehicle`,\n`same_day` and `same_route` accept a leg's stop id (`pickup.id` /\n`delivery.id`, by default `\"{shipment}:pickup\"` / `\":delivery\"`) and bind\nthat leg like a job. A leg coupled to other tasks by a `synchronized` or\n`time_lag` relation (directly, or through a `sequence` with a member that\nis) is rejected with HTTP 400, as is a `sequence` putting a delivery before\nits pickup. A shipment's own id in `stops`, or a shipment carrying the\n`tag` of a `same_vehicle` or `same_day` relation, is rejected with HTTP 400\n`not_supported`: relations never silently skip a member. `same_route`,\n`time_lag`, `compatible_vehicles`, `all_or_none` and `tag_order` reject a\nshipment with HTTP 400 as well.","required":["stops","type"],"example":{"stops":["job-1","job-2"],"type":"sequence"},"properties":{"stops":{"type":"array","items":{"type":"string"},"description":"Job ids, at least two. A shipment's own id or a shipment-leg stop id\nis rejected with HTTP 400.","example":["job-1","job-2"],"minItems":2},"type":{"type":"string","description":"Discriminator: always `all_or_none`.","enum":["all_or_none"]}},"additionalProperties":false}]},"description":"Ordering, co-assignment and synchronization constraints.","uniqueKey":"problem.relations.oneOf.1","typeLabel":"null"}],"uniqueKey":"problem.relations","typeLabel":"Sequence · object · Consecutive · object · Tag order · object · Same vehicle · object · Same vehicle · object · Same day · object · Same day · object · Same route · object · Same route · object · Synchronized · object · Time lag · object · Compatible vehicles · object · All or none · object[] | null"},"shipments":{"type":"array","items":{"type":"object","description":"A bound pickup→delivery shipment (the `shipments[]` entry type).\n\nTwo stops served by one vehicle, pickup strictly before delivery, with\n`load` carried on the vehicle between the two legs.\n\n`drop_cost` and vehicle eligibility (`eligible_vehicles`, allow\n**and** exclude, any length) are fully supported and applied to both legs — a\nshipment's pickup and delivery share one droppability/eligibility decision,\nsince one vehicle must serve both.","required":["id","pickup","delivery"],"properties":{"delivery":{"type":"object","description":"Delivery leg (load off).","required":["location"],"properties":{"location":{"type":"array","items":{"type":"number","format":"double","uniqueKey":"problem.shipments.items.[INDEX].delivery.location.items.[INDEX]","typeLabel":"number\u003cdouble>"},"description":"Where this stop happens.","examples":[[3.725,51.05]],"maxItems":2,"minItems":2,"isRequired":true,"uniqueKey":"problem.shipments.items.[INDEX].delivery.location","typeLabel":"number\u003cdouble>[]"},"id":{"oneOf":[{"type":"string","description":"Stop id: 1 to 128 characters when set. Defaults to\n`\"{shipment}:pickup\"` / `\"{shipment}:delivery\"`. The effective id\n(custom or default) must be unique across all job, shipment, and stop\nids — a collision is rejected with HTTP 400.","example":"ship-1:pickup","maxLength":128,"minLength":1,"uniqueKey":"problem.shipments.items.[INDEX].delivery.id.oneOf.0","typeLabel":"string"},{"type":"null","description":"Stop id: 1 to 128 characters when set. Defaults to\n`\"{shipment}:pickup\"` / `\"{shipment}:delivery\"`. The effective id\n(custom or default) must be unique across all job, shipment, and stop\nids — a collision is rejected with HTTP 400.","example":"ship-1:pickup","maxLength":128,"minLength":1,"uniqueKey":"problem.shipments.items.[INDEX].delivery.id.oneOf.1","typeLabel":"null"}],"uniqueKey":"problem.shipments.items.[INDEX].delivery.id","typeLabel":"string | null"},"service_duration_s":{"oneOf":[{"type":"integer","format":"int32","description":"On-site service time paid per job (seconds).\n\nThis is the nominal figure. The serving vehicle's `service_factor`\nscales it — the time actually scheduled is\n`service_duration_s / service_factor` — so the solution's\n`stops[].service_s` may differ from what you sent here. Default `0`;\na negative value is rejected with HTTP 400.","example":300,"minimum":0,"uniqueKey":"problem.shipments.items.[INDEX].delivery.service_duration_s.oneOf.0","typeLabel":"integer\u003cint32>"},{"type":"null","format":"int32","description":"On-site service time paid per job (seconds).\n\nThis is the nominal figure. The serving vehicle's `service_factor`\nscales it — the time actually scheduled is\n`service_duration_s / service_factor` — so the solution's\n`stops[].service_s` may differ from what you sent here. Default `0`;\na negative value is rejected with HTTP 400.","example":300,"minimum":0,"uniqueKey":"problem.shipments.items.[INDEX].delivery.service_duration_s.oneOf.1","typeLabel":"null"}],"uniqueKey":"problem.shipments.items.[INDEX].delivery.service_duration_s","typeLabel":"integer\u003cint32> | null"},"setup_duration_s":{"oneOf":[{"type":"integer","format":"int32","description":"Setup time paid once on arrival at a new location (seconds),\ndistinct from `service_duration_s`. Skipped when the immediate real\npredecessor in the route already sits at this location — co-located\nstops share one setup.\n\nNot scaled by the vehicle's `service_factor`: setup is fixed arrival\noverhead (parking, walking to the door), not the work itself.\nDefault `0`; a negative value is rejected with HTTP 400.","example":60,"minimum":0,"uniqueKey":"problem.shipments.items.[INDEX].delivery.setup_duration_s.oneOf.0","typeLabel":"integer\u003cint32>"},{"type":"null","format":"int32","description":"Setup time paid once on arrival at a new location (seconds),\ndistinct from `service_duration_s`. Skipped when the immediate real\npredecessor in the route already sits at this location — co-located\nstops share one setup.\n\nNot scaled by the vehicle's `service_factor`: setup is fixed arrival\noverhead (parking, walking to the door), not the work itself.\nDefault `0`; a negative value is rejected with HTTP 400.","example":60,"minimum":0,"uniqueKey":"problem.shipments.items.[INDEX].delivery.setup_duration_s.oneOf.1","typeLabel":"null"}],"uniqueKey":"problem.shipments.items.[INDEX].delivery.setup_duration_s","typeLabel":"integer\u003cint32> | null"},"time_windows":{"oneOf":[{"type":"array","items":{"type":"object","description":"A time window. Hard unless it (or `objective.per_late_hour`, for\nevery window) prices lateness.","required":["from","to"],"properties":{"from":{"type":"string","format":"date-time","description":"Earliest allowed start of service (RFC 3339 instant, UTC offset\nrequired). A vehicle that arrives earlier waits.","example":"2026-07-01T09:00:00+02:00","isRequired":true,"uniqueKey":"problem.shipments.items.[INDEX].delivery.time_windows.oneOf.0.items.[INDEX].from","typeLabel":"string\u003cdate-time>"},"to":{"type":"string","format":"date-time","description":"Latest allowed start of service (RFC 3339 instant, UTC offset\nrequired), measured from arrival plus any windowed break taken first\n(#1750 D1). Hard unless `per_late_hour` prices lateness.","example":"2026-07-01T12:00:00+02:00","isRequired":true,"uniqueKey":"problem.shipments.items.[INDEX].delivery.time_windows.oneOf.0.items.[INDEX].to","typeLabel":"string\u003cdate-time>"},"choice_cost":{"oneOf":[{"type":"number","format":"double","description":"Optional flat cost, in the objective's currency, added when this\njob/stop is served within THIS window rather than a free/cheaper\nalternative window on the same task. Absent = 0 (no charge). Every\nwindow in the list remains individually hard — a job must still land\nin *some* window — this only grades preference among the hard\nalternatives; it does not soften time-window feasibility. Must be\nfinite and `>= 0`, and requires at least 2 windows on the task. Once\nany window on the task carries a *nonzero* cost, that task's windows\nmust also be pairwise non-overlapping, and windows that only touch\ncount as overlapping (a task whose costs are all\n`0`/absent has its overlapping windows merged).\n\n**Cannot be combined with `objective.per_late_hour > 0`** — a\nnonzero `choice_cost` anywhere in the request alongside priced lateness\nis rejected with HTTP 400 (the two read opposite ways about which\nwindow was paid for). Choose one: priced alternative windows, or priced\nlateness.","maximum":21474.83647,"minimum":0,"uniqueKey":"problem.shipments.items.[INDEX].delivery.time_windows.oneOf.0.items.[INDEX].choice_cost.oneOf.0","typeLabel":"number\u003cdouble>"},{"type":"null","format":"double","description":"Optional flat cost, in the objective's currency, added when this\njob/stop is served within THIS window rather than a free/cheaper\nalternative window on the same task. Absent = 0 (no charge). Every\nwindow in the list remains individually hard — a job must still land\nin *some* window — this only grades preference among the hard\nalternatives; it does not soften time-window feasibility. Must be\nfinite and `>= 0`, and requires at least 2 windows on the task. Once\nany window on the task carries a *nonzero* cost, that task's windows\nmust also be pairwise non-overlapping, and windows that only touch\ncount as overlapping (a task whose costs are all\n`0`/absent has its overlapping windows merged).\n\n**Cannot be combined with `objective.per_late_hour > 0`** — a\nnonzero `choice_cost` anywhere in the request alongside priced lateness\nis rejected with HTTP 400 (the two read opposite ways about which\nwindow was paid for). Choose one: priced alternative windows, or priced\nlateness.","maximum":21474.83647,"minimum":0,"uniqueKey":"problem.shipments.items.[INDEX].delivery.time_windows.oneOf.0.items.[INDEX].choice_cost.oneOf.1","typeLabel":"null"}],"uniqueKey":"problem.shipments.items.[INDEX].delivery.time_windows.oneOf.0.items.[INDEX].choice_cost","typeLabel":"number\u003cdouble> | null"},"per_late_hour":{"oneOf":[{"type":"number","format":"double","description":"Makes this window soft on its late side: arriving after `to` is\nallowed and priced at this rate, in the objective's currency per hour\nlate, in place of `objective.per_late_hour` (and whether or not\nthat is set, so hard and soft windows can share one request). Must be\n`> 0`; omit it for a hard window. Only on a\ntask with exactly one window. Arriving early still waits for `from`.","example":60,"minimum":0.0006,"uniqueKey":"problem.shipments.items.[INDEX].delivery.time_windows.oneOf.0.items.[INDEX].per_late_hour.oneOf.0","typeLabel":"number\u003cdouble>"},{"type":"null","format":"double","description":"Makes this window soft on its late side: arriving after `to` is\nallowed and priced at this rate, in the objective's currency per hour\nlate, in place of `objective.per_late_hour` (and whether or not\nthat is set, so hard and soft windows can share one request). Must be\n`> 0`; omit it for a hard window. Only on a\ntask with exactly one window. Arriving early still waits for `from`.","example":60,"minimum":0.0006,"uniqueKey":"problem.shipments.items.[INDEX].delivery.time_windows.oneOf.0.items.[INDEX].per_late_hour.oneOf.1","typeLabel":"null"}],"uniqueKey":"problem.shipments.items.[INDEX].delivery.time_windows.oneOf.0.items.[INDEX].per_late_hour","typeLabel":"number\u003cdouble> | null"}},"additionalProperties":false,"example":{"choice_cost":15,"from":"2026-07-01T09:00:00+02:00","to":"2026-07-01T12:00:00+02:00"},"uniqueKey":"problem.shipments.items.[INDEX].delivery.time_windows.oneOf.0.items.[INDEX]","typeLabel":"object"},"description":"Time windows for this stop.","uniqueKey":"problem.shipments.items.[INDEX].delivery.time_windows.oneOf.0","typeLabel":"object[]"},{"type":"null","items":{"type":"object","description":"A time window. Hard unless it (or `objective.per_late_hour`, for\nevery window) prices lateness.","required":["from","to"],"properties":{"choice_cost":{"oneOf":[{"type":"number","format":"double","description":"Optional flat cost, in the objective's currency, added when this\njob/stop is served within THIS window rather than a free/cheaper\nalternative window on the same task. Absent = 0 (no charge). Every\nwindow in the list remains individually hard — a job must still land\nin *some* window — this only grades preference among the hard\nalternatives; it does not soften time-window feasibility. Must be\nfinite and `>= 0`, and requires at least 2 windows on the task. Once\nany window on the task carries a *nonzero* cost, that task's windows\nmust also be pairwise non-overlapping, and windows that only touch\ncount as overlapping (a task whose costs are all\n`0`/absent has its overlapping windows merged).\n\n**Cannot be combined with `objective.per_late_hour > 0`** — a\nnonzero `choice_cost` anywhere in the request alongside priced lateness\nis rejected with HTTP 400 (the two read opposite ways about which\nwindow was paid for). Choose one: priced alternative windows, or priced\nlateness.","maximum":21474.83647,"minimum":0},{"type":"null","format":"double","description":"Optional flat cost, in the objective's currency, added when this\njob/stop is served within THIS window rather than a free/cheaper\nalternative window on the same task. Absent = 0 (no charge). Every\nwindow in the list remains individually hard — a job must still land\nin *some* window — this only grades preference among the hard\nalternatives; it does not soften time-window feasibility. Must be\nfinite and `>= 0`, and requires at least 2 windows on the task. Once\nany window on the task carries a *nonzero* cost, that task's windows\nmust also be pairwise non-overlapping, and windows that only touch\ncount as overlapping (a task whose costs are all\n`0`/absent has its overlapping windows merged).\n\n**Cannot be combined with `objective.per_late_hour > 0`** — a\nnonzero `choice_cost` anywhere in the request alongside priced lateness\nis rejected with HTTP 400 (the two read opposite ways about which\nwindow was paid for). Choose one: priced alternative windows, or priced\nlateness.","maximum":21474.83647,"minimum":0}]},"from":{"type":"string","format":"date-time","description":"Earliest allowed start of service (RFC 3339 instant, UTC offset\nrequired). A vehicle that arrives earlier waits.","example":"2026-07-01T09:00:00+02:00"},"per_late_hour":{"oneOf":[{"type":"number","format":"double","description":"Makes this window soft on its late side: arriving after `to` is\nallowed and priced at this rate, in the objective's currency per hour\nlate, in place of `objective.per_late_hour` (and whether or not\nthat is set, so hard and soft windows can share one request). Must be\n`> 0`; omit it for a hard window. Only on a\ntask with exactly one window. Arriving early still waits for `from`.","example":60,"minimum":0.0006},{"type":"null","format":"double","description":"Makes this window soft on its late side: arriving after `to` is\nallowed and priced at this rate, in the objective's currency per hour\nlate, in place of `objective.per_late_hour` (and whether or not\nthat is set, so hard and soft windows can share one request). Must be\n`> 0`; omit it for a hard window. Only on a\ntask with exactly one window. Arriving early still waits for `from`.","example":60,"minimum":0.0006}]},"to":{"type":"string","format":"date-time","description":"Latest allowed start of service (RFC 3339 instant, UTC offset\nrequired), measured from arrival plus any windowed break taken first\n(#1750 D1). Hard unless `per_late_hour` prices lateness.","example":"2026-07-01T12:00:00+02:00"}},"additionalProperties":false,"example":{"choice_cost":15,"from":"2026-07-01T09:00:00+02:00","to":"2026-07-01T12:00:00+02:00"}},"description":"Time windows for this stop.","uniqueKey":"problem.shipments.items.[INDEX].delivery.time_windows.oneOf.1","typeLabel":"null"}],"uniqueKey":"problem.shipments.items.[INDEX].delivery.time_windows","typeLabel":"object[] | null"}},"additionalProperties":false,"example":{"id":"ship-1:pickup","location":[3.725,51.05],"service_duration_s":300,"setup_duration_s":60,"time_windows":[{"from":"2026-07-01T09:00:00+02:00","to":"2026-07-01T12:00:00+02:00"}]},"isRequired":true,"uniqueKey":"problem.shipments.items.[INDEX].delivery","typeLabel":"object"},"id":{"type":"string","description":"Shipment id: 1 to 128 characters, unique across `jobs` + `shipments`.","example":"ship-1","maxLength":128,"minLength":1,"isRequired":true,"uniqueKey":"problem.shipments.items.[INDEX].id","typeLabel":"string"},"pickup":{"type":"object","description":"Pickup leg (load on).","required":["location"],"properties":{"location":{"type":"array","items":{"type":"number","format":"double","uniqueKey":"problem.shipments.items.[INDEX].pickup.location.items.[INDEX]","typeLabel":"number\u003cdouble>"},"description":"Where this stop happens.","examples":[[3.725,51.05]],"maxItems":2,"minItems":2,"isRequired":true,"uniqueKey":"problem.shipments.items.[INDEX].pickup.location","typeLabel":"number\u003cdouble>[]"},"id":{"oneOf":[{"type":"string","description":"Stop id: 1 to 128 characters when set. Defaults to\n`\"{shipment}:pickup\"` / `\"{shipment}:delivery\"`. The effective id\n(custom or default) must be unique across all job, shipment, and stop\nids — a collision is rejected with HTTP 400.","example":"ship-1:pickup","maxLength":128,"minLength":1,"uniqueKey":"problem.shipments.items.[INDEX].pickup.id.oneOf.0","typeLabel":"string"},{"type":"null","description":"Stop id: 1 to 128 characters when set. Defaults to\n`\"{shipment}:pickup\"` / `\"{shipment}:delivery\"`. The effective id\n(custom or default) must be unique across all job, shipment, and stop\nids — a collision is rejected with HTTP 400.","example":"ship-1:pickup","maxLength":128,"minLength":1,"uniqueKey":"problem.shipments.items.[INDEX].pickup.id.oneOf.1","typeLabel":"null"}],"uniqueKey":"problem.shipments.items.[INDEX].pickup.id","typeLabel":"string | null"},"service_duration_s":{"oneOf":[{"type":"integer","format":"int32","description":"On-site service time paid per job (seconds).\n\nThis is the nominal figure. The serving vehicle's `service_factor`\nscales it — the time actually scheduled is\n`service_duration_s / service_factor` — so the solution's\n`stops[].service_s` may differ from what you sent here. Default `0`;\na negative value is rejected with HTTP 400.","example":300,"minimum":0,"uniqueKey":"problem.shipments.items.[INDEX].pickup.service_duration_s.oneOf.0","typeLabel":"integer\u003cint32>"},{"type":"null","format":"int32","description":"On-site service time paid per job (seconds).\n\nThis is the nominal figure. The serving vehicle's `service_factor`\nscales it — the time actually scheduled is\n`service_duration_s / service_factor` — so the solution's\n`stops[].service_s` may differ from what you sent here. Default `0`;\na negative value is rejected with HTTP 400.","example":300,"minimum":0,"uniqueKey":"problem.shipments.items.[INDEX].pickup.service_duration_s.oneOf.1","typeLabel":"null"}],"uniqueKey":"problem.shipments.items.[INDEX].pickup.service_duration_s","typeLabel":"integer\u003cint32> | null"},"setup_duration_s":{"oneOf":[{"type":"integer","format":"int32","description":"Setup time paid once on arrival at a new location (seconds),\ndistinct from `service_duration_s`. Skipped when the immediate real\npredecessor in the route already sits at this location — co-located\nstops share one setup.\n\nNot scaled by the vehicle's `service_factor`: setup is fixed arrival\noverhead (parking, walking to the door), not the work itself.\nDefault `0`; a negative value is rejected with HTTP 400.","example":60,"minimum":0,"uniqueKey":"problem.shipments.items.[INDEX].pickup.setup_duration_s.oneOf.0","typeLabel":"integer\u003cint32>"},{"type":"null","format":"int32","description":"Setup time paid once on arrival at a new location (seconds),\ndistinct from `service_duration_s`. Skipped when the immediate real\npredecessor in the route already sits at this location — co-located\nstops share one setup.\n\nNot scaled by the vehicle's `service_factor`: setup is fixed arrival\noverhead (parking, walking to the door), not the work itself.\nDefault `0`; a negative value is rejected with HTTP 400.","example":60,"minimum":0,"uniqueKey":"problem.shipments.items.[INDEX].pickup.setup_duration_s.oneOf.1","typeLabel":"null"}],"uniqueKey":"problem.shipments.items.[INDEX].pickup.setup_duration_s","typeLabel":"integer\u003cint32> | null"},"time_windows":{"oneOf":[{"type":"array","items":{"type":"object","description":"A time window. Hard unless it (or `objective.per_late_hour`, for\nevery window) prices lateness.","required":["from","to"],"properties":{"from":{"type":"string","format":"date-time","description":"Earliest allowed start of service (RFC 3339 instant, UTC offset\nrequired). A vehicle that arrives earlier waits.","example":"2026-07-01T09:00:00+02:00","isRequired":true,"uniqueKey":"problem.shipments.items.[INDEX].pickup.time_windows.oneOf.0.items.[INDEX].from","typeLabel":"string\u003cdate-time>"},"to":{"type":"string","format":"date-time","description":"Latest allowed start of service (RFC 3339 instant, UTC offset\nrequired), measured from arrival plus any windowed break taken first\n(#1750 D1). Hard unless `per_late_hour` prices lateness.","example":"2026-07-01T12:00:00+02:00","isRequired":true,"uniqueKey":"problem.shipments.items.[INDEX].pickup.time_windows.oneOf.0.items.[INDEX].to","typeLabel":"string\u003cdate-time>"},"choice_cost":{"oneOf":[{"type":"number","format":"double","description":"Optional flat cost, in the objective's currency, added when this\njob/stop is served within THIS window rather than a free/cheaper\nalternative window on the same task. Absent = 0 (no charge). Every\nwindow in the list remains individually hard — a job must still land\nin *some* window — this only grades preference among the hard\nalternatives; it does not soften time-window feasibility. Must be\nfinite and `>= 0`, and requires at least 2 windows on the task. Once\nany window on the task carries a *nonzero* cost, that task's windows\nmust also be pairwise non-overlapping, and windows that only touch\ncount as overlapping (a task whose costs are all\n`0`/absent has its overlapping windows merged).\n\n**Cannot be combined with `objective.per_late_hour > 0`** — a\nnonzero `choice_cost` anywhere in the request alongside priced lateness\nis rejected with HTTP 400 (the two read opposite ways about which\nwindow was paid for). Choose one: priced alternative windows, or priced\nlateness.","maximum":21474.83647,"minimum":0,"uniqueKey":"problem.shipments.items.[INDEX].pickup.time_windows.oneOf.0.items.[INDEX].choice_cost.oneOf.0","typeLabel":"number\u003cdouble>"},{"type":"null","format":"double","description":"Optional flat cost, in the objective's currency, added when this\njob/stop is served within THIS window rather than a free/cheaper\nalternative window on the same task. Absent = 0 (no charge). Every\nwindow in the list remains individually hard — a job must still land\nin *some* window — this only grades preference among the hard\nalternatives; it does not soften time-window feasibility. Must be\nfinite and `>= 0`, and requires at least 2 windows on the task. Once\nany window on the task carries a *nonzero* cost, that task's windows\nmust also be pairwise non-overlapping, and windows that only touch\ncount as overlapping (a task whose costs are all\n`0`/absent has its overlapping windows merged).\n\n**Cannot be combined with `objective.per_late_hour > 0`** — a\nnonzero `choice_cost` anywhere in the request alongside priced lateness\nis rejected with HTTP 400 (the two read opposite ways about which\nwindow was paid for). Choose one: priced alternative windows, or priced\nlateness.","maximum":21474.83647,"minimum":0,"uniqueKey":"problem.shipments.items.[INDEX].pickup.time_windows.oneOf.0.items.[INDEX].choice_cost.oneOf.1","typeLabel":"null"}],"uniqueKey":"problem.shipments.items.[INDEX].pickup.time_windows.oneOf.0.items.[INDEX].choice_cost","typeLabel":"number\u003cdouble> | null"},"per_late_hour":{"oneOf":[{"type":"number","format":"double","description":"Makes this window soft on its late side: arriving after `to` is\nallowed and priced at this rate, in the objective's currency per hour\nlate, in place of `objective.per_late_hour` (and whether or not\nthat is set, so hard and soft windows can share one request). Must be\n`> 0`; omit it for a hard window. Only on a\ntask with exactly one window. Arriving early still waits for `from`.","example":60,"minimum":0.0006,"uniqueKey":"problem.shipments.items.[INDEX].pickup.time_windows.oneOf.0.items.[INDEX].per_late_hour.oneOf.0","typeLabel":"number\u003cdouble>"},{"type":"null","format":"double","description":"Makes this window soft on its late side: arriving after `to` is\nallowed and priced at this rate, in the objective's currency per hour\nlate, in place of `objective.per_late_hour` (and whether or not\nthat is set, so hard and soft windows can share one request). Must be\n`> 0`; omit it for a hard window. Only on a\ntask with exactly one window. Arriving early still waits for `from`.","example":60,"minimum":0.0006,"uniqueKey":"problem.shipments.items.[INDEX].pickup.time_windows.oneOf.0.items.[INDEX].per_late_hour.oneOf.1","typeLabel":"null"}],"uniqueKey":"problem.shipments.items.[INDEX].pickup.time_windows.oneOf.0.items.[INDEX].per_late_hour","typeLabel":"number\u003cdouble> | null"}},"additionalProperties":false,"example":{"choice_cost":15,"from":"2026-07-01T09:00:00+02:00","to":"2026-07-01T12:00:00+02:00"},"uniqueKey":"problem.shipments.items.[INDEX].pickup.time_windows.oneOf.0.items.[INDEX]","typeLabel":"object"},"description":"Time windows for this stop.","uniqueKey":"problem.shipments.items.[INDEX].pickup.time_windows.oneOf.0","typeLabel":"object[]"},{"type":"null","items":{"type":"object","description":"A time window. Hard unless it (or `objective.per_late_hour`, for\nevery window) prices lateness.","required":["from","to"],"properties":{"choice_cost":{"oneOf":[{"type":"number","format":"double","description":"Optional flat cost, in the objective's currency, added when this\njob/stop is served within THIS window rather than a free/cheaper\nalternative window on the same task. Absent = 0 (no charge). Every\nwindow in the list remains individually hard — a job must still land\nin *some* window — this only grades preference among the hard\nalternatives; it does not soften time-window feasibility. Must be\nfinite and `>= 0`, and requires at least 2 windows on the task. Once\nany window on the task carries a *nonzero* cost, that task's windows\nmust also be pairwise non-overlapping, and windows that only touch\ncount as overlapping (a task whose costs are all\n`0`/absent has its overlapping windows merged).\n\n**Cannot be combined with `objective.per_late_hour > 0`** — a\nnonzero `choice_cost` anywhere in the request alongside priced lateness\nis rejected with HTTP 400 (the two read opposite ways about which\nwindow was paid for). Choose one: priced alternative windows, or priced\nlateness.","maximum":21474.83647,"minimum":0},{"type":"null","format":"double","description":"Optional flat cost, in the objective's currency, added when this\njob/stop is served within THIS window rather than a free/cheaper\nalternative window on the same task. Absent = 0 (no charge). Every\nwindow in the list remains individually hard — a job must still land\nin *some* window — this only grades preference among the hard\nalternatives; it does not soften time-window feasibility. Must be\nfinite and `>= 0`, and requires at least 2 windows on the task. Once\nany window on the task carries a *nonzero* cost, that task's windows\nmust also be pairwise non-overlapping, and windows that only touch\ncount as overlapping (a task whose costs are all\n`0`/absent has its overlapping windows merged).\n\n**Cannot be combined with `objective.per_late_hour > 0`** — a\nnonzero `choice_cost` anywhere in the request alongside priced lateness\nis rejected with HTTP 400 (the two read opposite ways about which\nwindow was paid for). Choose one: priced alternative windows, or priced\nlateness.","maximum":21474.83647,"minimum":0}]},"from":{"type":"string","format":"date-time","description":"Earliest allowed start of service (RFC 3339 instant, UTC offset\nrequired). A vehicle that arrives earlier waits.","example":"2026-07-01T09:00:00+02:00"},"per_late_hour":{"oneOf":[{"type":"number","format":"double","description":"Makes this window soft on its late side: arriving after `to` is\nallowed and priced at this rate, in the objective's currency per hour\nlate, in place of `objective.per_late_hour` (and whether or not\nthat is set, so hard and soft windows can share one request). Must be\n`> 0`; omit it for a hard window. Only on a\ntask with exactly one window. Arriving early still waits for `from`.","example":60,"minimum":0.0006},{"type":"null","format":"double","description":"Makes this window soft on its late side: arriving after `to` is\nallowed and priced at this rate, in the objective's currency per hour\nlate, in place of `objective.per_late_hour` (and whether or not\nthat is set, so hard and soft windows can share one request). Must be\n`> 0`; omit it for a hard window. Only on a\ntask with exactly one window. Arriving early still waits for `from`.","example":60,"minimum":0.0006}]},"to":{"type":"string","format":"date-time","description":"Latest allowed start of service (RFC 3339 instant, UTC offset\nrequired), measured from arrival plus any windowed break taken first\n(#1750 D1). Hard unless `per_late_hour` prices lateness.","example":"2026-07-01T12:00:00+02:00"}},"additionalProperties":false,"example":{"choice_cost":15,"from":"2026-07-01T09:00:00+02:00","to":"2026-07-01T12:00:00+02:00"}},"description":"Time windows for this stop.","uniqueKey":"problem.shipments.items.[INDEX].pickup.time_windows.oneOf.1","typeLabel":"null"}],"uniqueKey":"problem.shipments.items.[INDEX].pickup.time_windows","typeLabel":"object[] | null"}},"additionalProperties":false,"example":{"id":"ship-1:pickup","location":[3.725,51.05],"service_duration_s":300,"setup_duration_s":60,"time_windows":[{"from":"2026-07-01T09:00:00+02:00","to":"2026-07-01T12:00:00+02:00"}]},"isRequired":true,"uniqueKey":"problem.shipments.items.[INDEX].pickup","typeLabel":"object"},"assignment_costs":{"oneOf":[{"type":"array","items":{"type":"object","description":"Absolute price of serving one task on one vehicle.","required":["vehicle","cost"],"properties":{"cost":{"type":"number","format":"double","description":"Cost, in the objective's currency, incurred when this vehicle serves\nthe task. Must be finite and `>= 0`. A vehicle not listed costs `0`.","example":12.5,"maximum":21474.83647,"minimum":0,"isRequired":true,"uniqueKey":"problem.shipments.items.[INDEX].assignment_costs.oneOf.0.items.[INDEX].cost","typeLabel":"number\u003cdouble>"},"vehicle":{"type":"string","description":"Vehicle id; applies to every shift of that vehicle. An id that matches\nno vehicle, or a vehicle listed twice in one task's\n`assignment_costs`, is rejected with HTTP 400.","example":"v1","isRequired":true,"uniqueKey":"problem.shipments.items.[INDEX].assignment_costs.oneOf.0.items.[INDEX].vehicle","typeLabel":"string"}},"additionalProperties":false,"example":{"cost":12.5,"vehicle":"v1"},"uniqueKey":"problem.shipments.items.[INDEX].assignment_costs.oneOf.0.items.[INDEX]","typeLabel":"object"},"description":"Absolute price of serving this task on a given vehicle, in the\nobjective's currency. Charged once, when that vehicle (on any of its\nshifts) serves the task; unlisted vehicles cost nothing. Unlike\n`preferences`, which charges the vehicles that did NOT get the task,\nthis prices the vehicle that did, so a task rated badly everywhere is\nthe first one dropped when capacity runs out. It lives in the cost tier,\nbelow `priority`, and adds to `preferences`, `drop_cost` and travel.\nNot applied by decomposition: a problem that sets it solves monolithically.","uniqueKey":"problem.shipments.items.[INDEX].assignment_costs.oneOf.0","typeLabel":"object[]"},{"type":"null","items":{"type":"object","description":"Absolute price of serving one task on one vehicle.","required":["vehicle","cost"],"properties":{"cost":{"type":"number","format":"double","description":"Cost, in the objective's currency, incurred when this vehicle serves\nthe task. Must be finite and `>= 0`. A vehicle not listed costs `0`.","example":12.5,"maximum":21474.83647,"minimum":0},"vehicle":{"type":"string","description":"Vehicle id; applies to every shift of that vehicle. An id that matches\nno vehicle, or a vehicle listed twice in one task's\n`assignment_costs`, is rejected with HTTP 400.","example":"v1"}},"additionalProperties":false,"example":{"cost":12.5,"vehicle":"v1"}},"description":"Absolute price of serving this task on a given vehicle, in the\nobjective's currency. Charged once, when that vehicle (on any of its\nshifts) serves the task; unlisted vehicles cost nothing. Unlike\n`preferences`, which charges the vehicles that did NOT get the task,\nthis prices the vehicle that did, so a task rated badly everywhere is\nthe first one dropped when capacity runs out. It lives in the cost tier,\nbelow `priority`, and adds to `preferences`, `drop_cost` and travel.\nNot applied by decomposition: a problem that sets it solves monolithically.","uniqueKey":"problem.shipments.items.[INDEX].assignment_costs.oneOf.1","typeLabel":"null"}],"uniqueKey":"problem.shipments.items.[INDEX].assignment_costs","typeLabel":"object[] | null"},"drop_cost":{"oneOf":[{"type":"number","format":"double","description":"Drop **price** — what leaving this task unserved costs you, in the same\ncurrency as `objective.costs`, and the only way to make a task\ndroppable. Tasks without a `drop_cost` must be served.\n\nThis is money, not a priority: it enters the same cost the solver\nminimises, so the task is served only while serving it costs less than\ndropping it. Drop costs the plan chose to pay are reported in\n`score.components.drop_costs` and summed into `score.cost`.\n\nOn a shipment the drop cost applies to the pair, charged once.\n\nMust be finite, `>= 0` and at most `1e9`; combined with `priority` it\nis rejected with HTTP 400 (`conflicting_fields`). Also rejected with\nHTTP 400 (`not_supported`) while a positive `objective.per_delay_workday` is set,\nsince a droppable task could be dropped to avoid its delay charge.","example":25,"maximum":1000000000,"minimum":0,"uniqueKey":"problem.shipments.items.[INDEX].drop_cost.oneOf.0","typeLabel":"number\u003cdouble>"},{"type":"null","format":"double","description":"Drop **price** — what leaving this task unserved costs you, in the same\ncurrency as `objective.costs`, and the only way to make a task\ndroppable. Tasks without a `drop_cost` must be served.\n\nThis is money, not a priority: it enters the same cost the solver\nminimises, so the task is served only while serving it costs less than\ndropping it. Drop costs the plan chose to pay are reported in\n`score.components.drop_costs` and summed into `score.cost`.\n\nOn a shipment the drop cost applies to the pair, charged once.\n\nMust be finite, `>= 0` and at most `1e9`; combined with `priority` it\nis rejected with HTTP 400 (`conflicting_fields`). Also rejected with\nHTTP 400 (`not_supported`) while a positive `objective.per_delay_workday` is set,\nsince a droppable task could be dropped to avoid its delay charge.","example":25,"maximum":1000000000,"minimum":0,"uniqueKey":"problem.shipments.items.[INDEX].drop_cost.oneOf.1","typeLabel":"null"}],"uniqueKey":"problem.shipments.items.[INDEX].drop_cost","typeLabel":"number\u003cdouble> | null"},"eligible_vehicles":{"oneOf":[{"type":"null","description":"Hard vehicle allow/exclude. A request may use at most 256 distinct\npermitted-vehicle sets (after resolving `allowed`/`excluded`) across\nall jobs and shipments (HTTP 400 `limit_exceeded` beyond that).","uniqueKey":"problem.shipments.items.[INDEX].eligible_vehicles.oneOf.0","typeLabel":"null"},{"type":"object","description":"Hard vehicle allow/exclude. A request may use at most 256 distinct\npermitted-vehicle sets (after resolving `allowed`/`excluded`) across\nall jobs and shipments (HTTP 400 `limit_exceeded` beyond that).","example":{"allowed":["v1","v2"]},"properties":{"allowed":{"oneOf":[{"type":"array","items":{"type":"string","uniqueKey":"problem.shipments.items.[INDEX].eligible_vehicles.oneOf.1.allowed.oneOf.0.items.[INDEX]","typeLabel":"string"},"description":"Hard whitelist of vehicle ids. Omit = all vehicles allowed. An empty\nlist, or an id that names no vehicle, is rejected with HTTP 400.","minItems":1,"uniqueKey":"problem.shipments.items.[INDEX].eligible_vehicles.oneOf.1.allowed.oneOf.0","typeLabel":"string[]"},{"type":"null","items":{"type":"string"},"description":"Hard whitelist of vehicle ids. Omit = all vehicles allowed. An empty\nlist, or an id that names no vehicle, is rejected with HTTP 400.","minItems":1,"uniqueKey":"problem.shipments.items.[INDEX].eligible_vehicles.oneOf.1.allowed.oneOf.1","typeLabel":"null"}],"uniqueKey":"problem.shipments.items.[INDEX].eligible_vehicles.oneOf.1.allowed","typeLabel":"string[] | null"},"excluded":{"oneOf":[{"type":"array","items":{"type":"string","uniqueKey":"problem.shipments.items.[INDEX].eligible_vehicles.oneOf.1.excluded.oneOf.0.items.[INDEX]","typeLabel":"string"},"description":"Hard blacklist of vehicle ids. Mutually exclusive with `allowed`. An\nid that names no vehicle is rejected with HTTP 400.","uniqueKey":"problem.shipments.items.[INDEX].eligible_vehicles.oneOf.1.excluded.oneOf.0","typeLabel":"string[]"},{"type":"null","items":{"type":"string"},"description":"Hard blacklist of vehicle ids. Mutually exclusive with `allowed`. An\nid that names no vehicle is rejected with HTTP 400.","uniqueKey":"problem.shipments.items.[INDEX].eligible_vehicles.oneOf.1.excluded.oneOf.1","typeLabel":"null"}],"uniqueKey":"problem.shipments.items.[INDEX].eligible_vehicles.oneOf.1.excluded","typeLabel":"string[] | null"}},"additionalProperties":false,"uniqueKey":"problem.shipments.items.[INDEX].eligible_vehicles.oneOf.1","typeLabel":"object"}],"uniqueKey":"problem.shipments.items.[INDEX].eligible_vehicles","typeLabel":"null | object"},"load":{"oneOf":[{"type":"null","description":"Load carried from the pickup to the delivery: picked up at one leg and\nthe same quantity dropped off at the other. Non-negative magnitudes\nper named dimension.","uniqueKey":"problem.shipments.items.[INDEX].load.oneOf.0","typeLabel":"null"},{"type":"object","description":"Load carried from the pickup to the delivery: picked up at one leg and\nthe same quantity dropped off at the other. Non-negative magnitudes\nper named dimension.","example":{"volume":2,"weight":20},"additionalProperties":{"type":"integer","format":"int32","minimum":0,"uniqueKey":"problem.shipments.items.[INDEX].load.oneOf.1.additionalProperties","typeLabel":"integer\u003cint32>"},"uniqueKey":"problem.shipments.items.[INDEX].load.oneOf.1","typeLabel":"object"}],"uniqueKey":"problem.shipments.items.[INDEX].load","typeLabel":"null | object"},"preferences":{"oneOf":[{"type":"array","items":{"type":"object","description":"A soft vehicle affinity preference, priced.","required":["vehicle","violation_cost"],"properties":{"vehicle":{"type":"string","description":"Preferred vehicle id. An id that names no vehicle, or a vehicle listed\ntwice in one task's `preferences`, is rejected with HTTP 400.","example":"v1","isRequired":true,"uniqueKey":"problem.shipments.items.[INDEX].preferences.oneOf.0.items.[INDEX].vehicle","typeLabel":"string"},"violation_cost":{"type":"number","format":"double","description":"Cost, in the objective's currency, incurred when a different vehicle\nserves the job. Must be finite and `>= 0`.","example":50,"maximum":21474.83647,"minimum":0,"isRequired":true,"uniqueKey":"problem.shipments.items.[INDEX].preferences.oneOf.0.items.[INDEX].violation_cost","typeLabel":"number\u003cdouble>"}},"additionalProperties":false,"example":{"vehicle":"v1","violation_cost":50},"uniqueKey":"problem.shipments.items.[INDEX].preferences.oneOf.0.items.[INDEX]","typeLabel":"object"},"description":"Soft vehicle affinity preferences, priced. Each entry is independent:\na job listing several preferred vehicles it doesn't get pays each\none's `violation_cost` (compounding, the same rule as a vehicle's\n`preferred_tags`).","uniqueKey":"problem.shipments.items.[INDEX].preferences.oneOf.0","typeLabel":"object[]"},{"type":"null","items":{"type":"object","description":"A soft vehicle affinity preference, priced.","required":["vehicle","violation_cost"],"properties":{"vehicle":{"type":"string","description":"Preferred vehicle id. An id that names no vehicle, or a vehicle listed\ntwice in one task's `preferences`, is rejected with HTTP 400.","example":"v1"},"violation_cost":{"type":"number","format":"double","description":"Cost, in the objective's currency, incurred when a different vehicle\nserves the job. Must be finite and `>= 0`.","example":50,"maximum":21474.83647,"minimum":0}},"additionalProperties":false,"example":{"vehicle":"v1","violation_cost":50}},"description":"Soft vehicle affinity preferences, priced. Each entry is independent:\na job listing several preferred vehicles it doesn't get pays each\none's `violation_cost` (compounding, the same rule as a vehicle's\n`preferred_tags`).","uniqueKey":"problem.shipments.items.[INDEX].preferences.oneOf.1","typeLabel":"null"}],"uniqueKey":"problem.shipments.items.[INDEX].preferences","typeLabel":"object[] | null"},"priority":{"oneOf":[{"type":"integer","format":"int32","description":"Importance of a must-serve task when not all of them fit: the solver\nmaximises the summed `priority` of served tasks before any cost. `>= 1`,\ndefault `1` (maximise the count). A rank, not money — it never makes a\ntask droppable; use `drop_cost` for that. Both set is a 400.","example":3,"minimum":1,"uniqueKey":"problem.shipments.items.[INDEX].priority.oneOf.0","typeLabel":"integer\u003cint32>"},{"type":"null","format":"int32","description":"Importance of a must-serve task when not all of them fit: the solver\nmaximises the summed `priority` of served tasks before any cost. `>= 1`,\ndefault `1` (maximise the count). A rank, not money — it never makes a\ntask droppable; use `drop_cost` for that. Both set is a 400.","example":3,"minimum":1,"uniqueKey":"problem.shipments.items.[INDEX].priority.oneOf.1","typeLabel":"null"}],"uniqueKey":"problem.shipments.items.[INDEX].priority","typeLabel":"integer\u003cint32> | null"},"required_skills":{"oneOf":[{"type":"array","items":{"type":"object","description":"A hard skill requirement — the assigned vehicle must provide it.","required":["name"],"properties":{"name":{"type":"string","description":"Skill name the assigned vehicle must provide.","example":"fridge","isRequired":true,"uniqueKey":"problem.shipments.items.[INDEX].required_skills.oneOf.0.items.[INDEX].name","typeLabel":"string"},"min_level":{"oneOf":[{"type":"integer","format":"int32","description":"Minimum level the serving vehicle must hold for this skill (`>= 1`).\nAbsent = 1. A vehicle skill with no `level` holds level 1.","example":2,"minimum":1,"uniqueKey":"problem.shipments.items.[INDEX].required_skills.oneOf.0.items.[INDEX].min_level.oneOf.0","typeLabel":"integer\u003cint32>"},{"type":"null","format":"int32","description":"Minimum level the serving vehicle must hold for this skill (`>= 1`).\nAbsent = 1. A vehicle skill with no `level` holds level 1.","example":2,"minimum":1,"uniqueKey":"problem.shipments.items.[INDEX].required_skills.oneOf.0.items.[INDEX].min_level.oneOf.1","typeLabel":"null"}],"uniqueKey":"problem.shipments.items.[INDEX].required_skills.oneOf.0.items.[INDEX].min_level","typeLabel":"integer\u003cint32> | null"}},"additionalProperties":false,"example":{"name":"fridge"},"uniqueKey":"problem.shipments.items.[INDEX].required_skills.oneOf.0.items.[INDEX]","typeLabel":"object"},"description":"Hard skill requirements — the assigned vehicle must provide every one,\nat or above each requirement's `min_level`. A request may use at most\n256 distinct `(name, min_level)` pairs across all jobs and shipments\n(HTTP 400 `limit_exceeded` beyond that).","uniqueKey":"problem.shipments.items.[INDEX].required_skills.oneOf.0","typeLabel":"object[]"},{"type":"null","items":{"type":"object","description":"A hard skill requirement — the assigned vehicle must provide it.","required":["name"],"properties":{"min_level":{"oneOf":[{"type":"integer","format":"int32","description":"Minimum level the serving vehicle must hold for this skill (`>= 1`).\nAbsent = 1. A vehicle skill with no `level` holds level 1.","example":2,"minimum":1},{"type":"null","format":"int32","description":"Minimum level the serving vehicle must hold for this skill (`>= 1`).\nAbsent = 1. A vehicle skill with no `level` holds level 1.","example":2,"minimum":1}]},"name":{"type":"string","description":"Skill name the assigned vehicle must provide.","example":"fridge"}},"additionalProperties":false,"example":{"name":"fridge"}},"description":"Hard skill requirements — the assigned vehicle must provide every one,\nat or above each requirement's `min_level`. A request may use at most\n256 distinct `(name, min_level)` pairs across all jobs and shipments\n(HTTP 400 `limit_exceeded` beyond that).","uniqueKey":"problem.shipments.items.[INDEX].required_skills.oneOf.1","typeLabel":"null"}],"uniqueKey":"problem.shipments.items.[INDEX].required_skills","typeLabel":"object[] | null"},"service_factors":{"oneOf":[{"type":"array","items":{"type":"object","description":"Per-vehicle work-rate override for one task's `service_duration_s`.","required":["vehicle","factor"],"properties":{"factor":{"type":"number","format":"double","description":"Work-rate factor of `vehicle` on this task. Service time is DIVIDED by\nit: above `1` the vehicle works faster here, below `1` slower; `1.0` is a\nno-op. It multiplies the vehicle's own rate (the shift's\n`service_factor` if set, else the vehicle's): effective service time =\n`service_duration_s / (shift_or_vehicle_factor * factor)`. Same\ndirection and `[0.001, 5]` range as `vehicles[].service_factor`. V2's\n`proficiency.durationModifier` multiplied duration instead; the V2\ncompatibility layer sends its inverse (`1 / durationModifier`) here.","example":1.25,"maximum":5,"minimum":0.001,"isRequired":true,"uniqueKey":"problem.shipments.items.[INDEX].service_factors.oneOf.0.items.[INDEX].factor","typeLabel":"number\u003cdouble>"},"vehicle":{"type":"string","description":"Vehicle id; applies to every shift of that vehicle.","example":"v1","isRequired":true,"uniqueKey":"problem.shipments.items.[INDEX].service_factors.oneOf.0.items.[INDEX].vehicle","typeLabel":"string"}},"additionalProperties":false,"example":{"factor":1.25,"vehicle":"v1"},"uniqueKey":"problem.shipments.items.[INDEX].service_factors.oneOf.0.items.[INDEX]","typeLabel":"object"},"description":"Per-vehicle work-rate factors for this task's `service_duration_s`,\nwhich is DIVIDED by the factor (above `1` = faster). Each multiplies\nthe serving vehicle's rate (the shift's `service_factor` if set, else\nthe vehicle's): effective service time = `service_duration_s /\n(shift_or_vehicle_factor * factor)`. On a shipment the factor scales\nboth legs. A vehicle not listed works at its own rate.","uniqueKey":"problem.shipments.items.[INDEX].service_factors.oneOf.0","typeLabel":"object[]"},{"type":"null","items":{"type":"object","description":"Per-vehicle work-rate override for one task's `service_duration_s`.","required":["vehicle","factor"],"properties":{"factor":{"type":"number","format":"double","description":"Work-rate factor of `vehicle` on this task. Service time is DIVIDED by\nit: above `1` the vehicle works faster here, below `1` slower; `1.0` is a\nno-op. It multiplies the vehicle's own rate (the shift's\n`service_factor` if set, else the vehicle's): effective service time =\n`service_duration_s / (shift_or_vehicle_factor * factor)`. Same\ndirection and `[0.001, 5]` range as `vehicles[].service_factor`. V2's\n`proficiency.durationModifier` multiplied duration instead; the V2\ncompatibility layer sends its inverse (`1 / durationModifier`) here.","example":1.25,"maximum":5,"minimum":0.001},"vehicle":{"type":"string","description":"Vehicle id; applies to every shift of that vehicle.","example":"v1"}},"additionalProperties":false,"example":{"factor":1.25,"vehicle":"v1"}},"description":"Per-vehicle work-rate factors for this task's `service_duration_s`,\nwhich is DIVIDED by the factor (above `1` = faster). Each multiplies\nthe serving vehicle's rate (the shift's `service_factor` if set, else\nthe vehicle's): effective service time = `service_duration_s /\n(shift_or_vehicle_factor * factor)`. On a shipment the factor scales\nboth legs. A vehicle not listed works at its own rate.","uniqueKey":"problem.shipments.items.[INDEX].service_factors.oneOf.1","typeLabel":"null"}],"uniqueKey":"problem.shipments.items.[INDEX].service_factors","typeLabel":"object[] | null"},"tags":{"oneOf":[{"type":"array","items":{"type":"string","uniqueKey":"problem.shipments.items.[INDEX].tags.oneOf.0.items.[INDEX]","typeLabel":"string"},"description":"Free-form task labels (zones/territories, relation labels).\nUsed for `tag`/relation resolution and, when a shift scopes itself via\n`serves_tags` (hard ANY-overlap) or a vehicle prices them via\n`preferred_tags` (soft), for tag matching. ANY-overlap — contrast with\n`required_skills`, which requires ALL. Not capability matching on its own.\nA request may carry at most 256 distinct tags across all jobs and\nshipments (HTTP 400 `limit_exceeded` beyond that); vehicle-side tag\nlists do not count.","uniqueKey":"problem.shipments.items.[INDEX].tags.oneOf.0","typeLabel":"string[]"},{"type":"null","items":{"type":"string"},"description":"Free-form task labels (zones/territories, relation labels).\nUsed for `tag`/relation resolution and, when a shift scopes itself via\n`serves_tags` (hard ANY-overlap) or a vehicle prices them via\n`preferred_tags` (soft), for tag matching. ANY-overlap — contrast with\n`required_skills`, which requires ALL. Not capability matching on its own.\nA request may carry at most 256 distinct tags across all jobs and\nshipments (HTTP 400 `limit_exceeded` beyond that); vehicle-side tag\nlists do not count.","uniqueKey":"problem.shipments.items.[INDEX].tags.oneOf.1","typeLabel":"null"}],"uniqueKey":"problem.shipments.items.[INDEX].tags","typeLabel":"string[] | null"},"target":{"oneOf":[{"type":"null","description":"Soft target for this task, measured at its arrival (default) or\ndeparture. On a shipment it is measured on the **delivery** leg.","uniqueKey":"problem.shipments.items.[INDEX].target.oneOf.0","typeLabel":"null"},{"type":"object","description":"Soft target for this task, measured at its arrival (default) or\ndeparture. On a shipment it is measured on the **delivery** leg.","required":["at","per_late_hour"],"example":{"at":"2026-07-01T10:00:00+02:00","on":"arrival","per_late_hour":60},"properties":{"at":{"type":"string","format":"date-time","description":"Target instant (RFC 3339, UTC offset required) the `on` instant is measured against.","example":"2026-07-01T10:00:00+02:00","isRequired":true,"uniqueKey":"problem.shipments.items.[INDEX].target.oneOf.1.at","typeLabel":"string\u003cdate-time>"},"per_late_hour":{"type":"number","format":"double","description":"Cost, in the objective's currency, per hour of `on` beyond `at`\n(linear, prorated per second). Must be `> 0`; independent of\n`objective.per_late_hour` (which prices *time-window* lateness,\nnot a target point).","example":60,"maximum":21474.83647,"minimum":0.00001,"isRequired":true,"uniqueKey":"problem.shipments.items.[INDEX].target.oneOf.1.per_late_hour","typeLabel":"number\u003cdouble>"},"on":{"oneOf":[{"type":"null","description":"Which instant of the task is compared to `at`: `arrival` (default) or\n`departure`, the stop fields of the same names.","default":"arrival","uniqueKey":"problem.shipments.items.[INDEX].target.oneOf.1.on.oneOf.0","typeLabel":"null"},{"type":"string","description":"Which instant of the task is compared to `at`: `arrival` (default) or\n`departure`, the stop fields of the same names.","default":"arrival","enum":["arrival","departure"],"uniqueKey":"problem.shipments.items.[INDEX].target.oneOf.1.on.oneOf.1","typeLabel":"enum\u003cstring>"}],"uniqueKey":"problem.shipments.items.[INDEX].target.oneOf.1.on","typeLabel":"null | enum\u003cstring>"}},"additionalProperties":false,"uniqueKey":"problem.shipments.items.[INDEX].target.oneOf.1","typeLabel":"object"}],"uniqueKey":"problem.shipments.items.[INDEX].target","typeLabel":"null | object"}},"additionalProperties":false,"example":{"delivery":{"location":[3.71,51.06],"service_duration_s":300},"id":"ship-1","load":{"weight":20},"pickup":{"location":[3.725,51.05],"service_duration_s":300}},"uniqueKey":"problem.shipments.items.[INDEX]","typeLabel":"object"},"description":"Bound pickup→delivery shipments to serve. Counts toward the same\n10,000-task cap as `jobs`.","maxItems":10000,"uniqueKey":"problem.shipments","typeLabel":"object[]"},"travel":{"oneOf":[{"type":"null","description":"Where travel times and distances come from.","uniqueKey":"problem.travel.oneOf.0","typeLabel":"null"},{"type":"object","description":"Where travel times and distances come from.","example":{"departure_time":"2026-07-01T08:00:00+02:00","engine":"tomtom"},"properties":{"departure_time":{"oneOf":[{"type":"string","format":"date-time","description":"Departure time for the traffic lookup (RFC 3339 instant, any offset).\nOmitted → free-flow times, or traffic at solve time with `engine:\ntomtom`. An explicit departure time bypasses the server-side matrix\ncache.","example":"2026-07-01T08:00:00+02:00","uniqueKey":"problem.travel.oneOf.1.departure_time.oneOf.0","typeLabel":"string\u003cdate-time>"},{"type":"null","format":"date-time","description":"Departure time for the traffic lookup (RFC 3339 instant, any offset).\nOmitted → free-flow times, or traffic at solve time with `engine:\ntomtom`. An explicit departure time bypasses the server-side matrix\ncache.","example":"2026-07-01T08:00:00+02:00","uniqueKey":"problem.travel.oneOf.1.departure_time.oneOf.1","typeLabel":"null"}],"uniqueKey":"problem.travel.oneOf.1.departure_time","typeLabel":"string\u003cdate-time> | null"},"engine":{"oneOf":[{"type":"null","description":"Data behind travel times and distances. Omitted → `osm`, or `tomtom`\nwhen `departure_time` is set.","uniqueKey":"problem.travel.oneOf.1.engine.oneOf.0","typeLabel":"null"},{"type":"string","description":"Data behind travel times and distances. Omitted → `osm`, or `tomtom`\nwhen `departure_time` is set.","enum":["tomtom","osm","tomtom_real_time","straight_line"],"example":"osm","uniqueKey":"problem.travel.oneOf.1.engine.oneOf.1","typeLabel":"enum\u003cstring>"}],"uniqueKey":"problem.travel.oneOf.1.engine","typeLabel":"null | enum\u003cstring>"},"speed_kmh":{"oneOf":[{"type":"number","format":"double","description":"Travel speed for `engine: \"straight_line\"`, in km/h: each leg takes its\ngreat-circle distance at this speed, rounded to the whole second. `1` to\n`1000`, default `50`; `vehicles[].speed_factor` still scales it per\nvehicle. Any other engine rejects it (HTTP 400 `conflicting_fields`).","default":50,"example":50,"maximum":1000,"minimum":1,"uniqueKey":"problem.travel.oneOf.1.speed_kmh.oneOf.0","typeLabel":"number\u003cdouble>"},{"type":"null","format":"double","description":"Travel speed for `engine: \"straight_line\"`, in km/h: each leg takes its\ngreat-circle distance at this speed, rounded to the whole second. `1` to\n`1000`, default `50`; `vehicles[].speed_factor` still scales it per\nvehicle. Any other engine rejects it (HTTP 400 `conflicting_fields`).","default":50,"example":50,"maximum":1000,"minimum":1,"uniqueKey":"problem.travel.oneOf.1.speed_kmh.oneOf.1","typeLabel":"null"}],"uniqueKey":"problem.travel.oneOf.1.speed_kmh","typeLabel":"number\u003cdouble> | null"}},"additionalProperties":false,"uniqueKey":"problem.travel.oneOf.1","typeLabel":"object"}],"uniqueKey":"problem.travel","typeLabel":"null | object"}},"additionalProperties":false,"example":{"depots":[{"id":"gent","location":[3.7174,51.0543]}],"jobs":[{"id":"job-1","location":[3.725,51.05],"pickup_load":{"weight":20},"service_duration_s":300}],"vehicles":[{"capacity":{"weight":500},"id":"v1","shifts":[{"end":{"depot":"gent"},"from":"2026-07-01T08:00:00+02:00","id":"mon","start":{"depot":"gent"},"to":"2026-07-01T17:00:00+02:00"}]}]},"isRequired":true,"uniqueKey":"problem","typeLabel":"object"}},"additionalProperties":false,"example":{"plan":{"routes":[{"shift":"mon","stops":[{"id":"job-1","type":"job"}],"vehicle":"v1"}]},"problem":{"jobs":[{"id":"job-1","location":[3.725,51.05],"pickup_load":{"weight":10},"service_duration_s":300}],"vehicles":[{"capacity":{"weight":500},"id":"v1","shifts":[{"end":{"location":[3.7174,51.0543]},"from":"2026-07-01T08:00:00+02:00","id":"mon","start":{"location":[3.7174,51.0543]},"to":"2026-07-01T17:00:00+02:00"}]}]}},"uniqueKey":"","typeLabel":"object"},"examples":{"Example":{"title":"Example","value":{"plan":{"routes":[{"shift":"mon","stops":[{"id":"job-1","type":"job"}],"vehicle":"v1"}]},"problem":{"jobs":[{"id":"job-1","location":[3.725,51.05],"pickup_load":{"weight":10},"service_duration_s":300}],"vehicles":[{"capacity":{"weight":500},"id":"v1","shifts":[{"end":{"location":[3.7174,51.0543]},"from":"2026-07-01T08:00:00+02:00","id":"mon","start":{"location":[3.7174,51.0543]},"to":"2026-07-01T17:00:00+02:00"}]}]}}}},"exampleType":"generated"}},"required":true,"exampleType":"generated"},"responses":{"c9a07169-5660-46a0-be7e-a5515b9e34ed":{"description":"The request passed every check made before travel times are fetched. `warnings` may contain warnings; none are produced today.","headers":{"x-request-id":{"schema":{"type":"string"},"description":"The request's `X-Request-Id`, echoed, or a generated `req_…` id."}},"content":{"application/json":{"schema":{"type":"object","description":"The 200 body of `POST /v3/routing/validate/{solve,evaluate,suggest}`: the\nrequest passed every check a real call runs before the matrix fetch.","required":["valid","warnings"],"properties":{"valid":{"type":"boolean","description":"Always `true`: an invalid request gets a 400 instead.","isRequired":true,"uniqueKey":"valid","typeLabel":"boolean"},"warnings":{"type":"array","items":{"type":"object","description":"One problem in a request.","required":["code","message"],"properties":{"code":{"type":"string","description":"What is wrong.","x-extensible-enum":["invalid_json","invalid_type","unknown_field","missing_field","invalid_value","not_supported","out_of_range","duplicate_id","unknown_reference","conflicting_fields","limit_exceeded"],"isRequired":true,"uniqueKey":"warnings.items.[INDEX].code","typeLabel":"string"},"message":{"type":"string","description":"Human-readable description.","isRequired":true,"uniqueKey":"warnings.items.[INDEX].message","typeLabel":"string"},"actual":{"oneOf":[{"type":"integer","format":"int64","description":"`limit_exceeded` only: the count this request has.","minimum":0,"uniqueKey":"warnings.items.[INDEX].actual.oneOf.0","typeLabel":"integer\u003cint64>"},{"type":"null","format":"int64","description":"`limit_exceeded` only: the count this request has.","minimum":0,"uniqueKey":"warnings.items.[INDEX].actual.oneOf.1","typeLabel":"null"}],"uniqueKey":"warnings.items.[INDEX].actual","typeLabel":"integer\u003cint64> | null"},"limit":{"oneOf":[{"type":"integer","format":"int64","description":"`limit_exceeded` only: the published cap.","minimum":0,"uniqueKey":"warnings.items.[INDEX].limit.oneOf.0","typeLabel":"integer\u003cint64>"},{"type":"null","format":"int64","description":"`limit_exceeded` only: the published cap.","minimum":0,"uniqueKey":"warnings.items.[INDEX].limit.oneOf.1","typeLabel":"null"}],"uniqueKey":"warnings.items.[INDEX].limit","typeLabel":"integer\u003cint64> | null"},"pointer":{"oneOf":[{"type":"string","description":"RFC 6901 JSON Pointer into the request body, when the problem has a\nlocation. It is relative to the root of the body, so a field of the\nproblem reads `/problem/...` (e.g.\n`\"/problem/vehicles/0/shifts/0/from\"`).","uniqueKey":"warnings.items.[INDEX].pointer.oneOf.0","typeLabel":"string"},{"type":"null","description":"RFC 6901 JSON Pointer into the request body, when the problem has a\nlocation. It is relative to the root of the body, so a field of the\nproblem reads `/problem/...` (e.g.\n`\"/problem/vehicles/0/shifts/0/from\"`).","uniqueKey":"warnings.items.[INDEX].pointer.oneOf.1","typeLabel":"null"}],"uniqueKey":"warnings.items.[INDEX].pointer","typeLabel":"string | null"}},"uniqueKey":"warnings.items.[INDEX]","typeLabel":"object"},"description":"May contain warnings about the request; none are produced today.","isRequired":true,"uniqueKey":"warnings","typeLabel":"object[]"}},"example":{"valid":true,"warnings":[]},"uniqueKey":"","typeLabel":"object"},"examples":{"Example":{"title":"Example","value":{"valid":true,"warnings":[]}}},"exampleType":"generated"}},"exampleType":"generated"},"ac24eec3-b632-4a58-9bc0-23ac25f6046a":{"description":"The request is invalid. `errors[]` lists what to fix, each entry with a `code` and, when the problem is in the body, a JSON `pointer` to it.","headers":{"x-request-id":{"schema":{"type":"string"},"description":"The request's `X-Request-Id`, echoed, or a generated `req_…` id."}},"content":{"application/json":{"schema":{"type":"object","description":"Error body of every `/v3/routing/*` endpoint.\n\n`status` is the HTTP status as text, `code` says what kind of failure it\nis, `request_id` identifies the request, and `errors` holds one item per\nproblem found in the request. Branch on `code`, and on `errors[].code` for\n400s; the messages are for people.","required":["status","code","message"],"properties":{"code":{"type":"string","description":"What kind of failure this is. One value per HTTP status class.","x-extensible-enum":["invalid_request","feature_not_enabled","payload_too_large","unsupported_media_type","internal","travel_provider_error","overloaded"],"isRequired":true,"uniqueKey":"code","typeLabel":"string"},"message":{"type":"string","description":"Human-readable summary. With exactly one item it is that item's\nmessage; with several, `\"{n} problems in request\"` (at most 100 items\nare listed, and the message says when the list is cut).","isRequired":true,"uniqueKey":"message","typeLabel":"string"},"status":{"type":"string","description":"The HTTP status as text, e.g. `\"BAD_REQUEST\"` or\n`\"SERVICE_UNAVAILABLE\"`.","example":"BAD_REQUEST","isRequired":true,"uniqueKey":"status","typeLabel":"string"},"errors":{"type":"array","items":{"type":"object","description":"One problem in a request.","required":["code","message"],"properties":{"code":{"type":"string","description":"What is wrong.","x-extensible-enum":["invalid_json","invalid_type","unknown_field","missing_field","invalid_value","not_supported","out_of_range","duplicate_id","unknown_reference","conflicting_fields","limit_exceeded"],"isRequired":true,"uniqueKey":"errors.items.[INDEX].code","typeLabel":"string"},"message":{"type":"string","description":"Human-readable description.","isRequired":true,"uniqueKey":"errors.items.[INDEX].message","typeLabel":"string"},"actual":{"oneOf":[{"type":"integer","format":"int64","description":"`limit_exceeded` only: the count this request has.","minimum":0,"uniqueKey":"errors.items.[INDEX].actual.oneOf.0","typeLabel":"integer\u003cint64>"},{"type":"null","format":"int64","description":"`limit_exceeded` only: the count this request has.","minimum":0,"uniqueKey":"errors.items.[INDEX].actual.oneOf.1","typeLabel":"null"}],"uniqueKey":"errors.items.[INDEX].actual","typeLabel":"integer\u003cint64> | null"},"limit":{"oneOf":[{"type":"integer","format":"int64","description":"`limit_exceeded` only: the published cap.","minimum":0,"uniqueKey":"errors.items.[INDEX].limit.oneOf.0","typeLabel":"integer\u003cint64>"},{"type":"null","format":"int64","description":"`limit_exceeded` only: the published cap.","minimum":0,"uniqueKey":"errors.items.[INDEX].limit.oneOf.1","typeLabel":"null"}],"uniqueKey":"errors.items.[INDEX].limit","typeLabel":"integer\u003cint64> | null"},"pointer":{"oneOf":[{"type":"string","description":"RFC 6901 JSON Pointer into the request body, when the problem has a\nlocation. It is relative to the root of the body, so a field of the\nproblem reads `/problem/...` (e.g.\n`\"/problem/vehicles/0/shifts/0/from\"`).","uniqueKey":"errors.items.[INDEX].pointer.oneOf.0","typeLabel":"string"},{"type":"null","description":"RFC 6901 JSON Pointer into the request body, when the problem has a\nlocation. It is relative to the root of the body, so a field of the\nproblem reads `/problem/...` (e.g.\n`\"/problem/vehicles/0/shifts/0/from\"`).","uniqueKey":"errors.items.[INDEX].pointer.oneOf.1","typeLabel":"null"}],"uniqueKey":"errors.items.[INDEX].pointer","typeLabel":"string | null"}},"uniqueKey":"errors.items.[INDEX]","typeLabel":"object"},"description":"One entry per problem found in the request. Empty for non-input errors.","uniqueKey":"errors","typeLabel":"object[]"},"request_id":{"oneOf":[{"type":"string","description":"The `X-Request-Id` of the request (echoed, or generated when absent).","uniqueKey":"request_id.oneOf.0","typeLabel":"string"},{"type":"null","description":"The `X-Request-Id` of the request (echoed, or generated when absent).","uniqueKey":"request_id.oneOf.1","typeLabel":"null"}],"uniqueKey":"request_id","typeLabel":"string | null"}},"example":{"code":"invalid_request","errors":[{"code":"out_of_range","message":"depot 'gent': service_duration_s must be >= 0, got -60","pointer":"/problem/depots/0/service_duration_s"}],"message":"depot 'gent': service_duration_s must be >= 0, got -60","request_id":"req_7f3a2c90d1e4b5a6","status":"BAD_REQUEST"},"uniqueKey":"","typeLabel":"object"},"examples":{"Example":{"title":"Example","value":{"code":"invalid_request","errors":[{"code":"out_of_range","message":"depot 'gent': service_duration_s must be >= 0, got -60","pointer":"/problem/depots/0/service_duration_s"}],"message":"depot 'gent': service_duration_s must be >= 0, got -60","request_id":"req_7f3a2c90d1e4b5a6","status":"BAD_REQUEST"}}},"exampleType":"generated"}},"exampleType":"generated"},"1ec46414-4ee4-4d34-a945-8d592f63407f":{"description":"Missing or invalid API key. Returned by the API gateway before the request reaches the solver, so it does not use the `ErrorBody` shape and can have an empty body. Branch on the HTTP status.","content":{"_mintlify/placeholder":{"schema":{"type":"object","description":""}}}},"270fd366-9898-44d8-bca2-de0186d11c49":{"description":"The request uses a feature this account does not have (`tomtom_real_time`)","headers":{"x-request-id":{"schema":{"type":"string"},"description":"The request's `X-Request-Id`, echoed, or a generated `req_…` id."}},"content":{"application/json":{"schema":{"type":"object","description":"Error body of every `/v3/routing/*` endpoint.\n\n`status` is the HTTP status as text, `code` says what kind of failure it\nis, `request_id` identifies the request, and `errors` holds one item per\nproblem found in the request. Branch on `code`, and on `errors[].code` for\n400s; the messages are for people.","required":["status","code","message"],"properties":{"code":{"type":"string","description":"What kind of failure this is. One value per HTTP status class.","x-extensible-enum":["invalid_request","feature_not_enabled","payload_too_large","unsupported_media_type","internal","travel_provider_error","overloaded"],"isRequired":true,"uniqueKey":"code","typeLabel":"string"},"message":{"type":"string","description":"Human-readable summary. With exactly one item it is that item's\nmessage; with several, `\"{n} problems in request\"` (at most 100 items\nare listed, and the message says when the list is cut).","isRequired":true,"uniqueKey":"message","typeLabel":"string"},"status":{"type":"string","description":"The HTTP status as text, e.g. `\"BAD_REQUEST\"` or\n`\"SERVICE_UNAVAILABLE\"`.","example":"BAD_REQUEST","isRequired":true,"uniqueKey":"status","typeLabel":"string"},"errors":{"type":"array","items":{"type":"object","description":"One problem in a request.","required":["code","message"],"properties":{"code":{"type":"string","description":"What is wrong.","x-extensible-enum":["invalid_json","invalid_type","unknown_field","missing_field","invalid_value","not_supported","out_of_range","duplicate_id","unknown_reference","conflicting_fields","limit_exceeded"],"isRequired":true,"uniqueKey":"errors.items.[INDEX].code","typeLabel":"string"},"message":{"type":"string","description":"Human-readable description.","isRequired":true,"uniqueKey":"errors.items.[INDEX].message","typeLabel":"string"},"actual":{"oneOf":[{"type":"integer","format":"int64","description":"`limit_exceeded` only: the count this request has.","minimum":0,"uniqueKey":"errors.items.[INDEX].actual.oneOf.0","typeLabel":"integer\u003cint64>"},{"type":"null","format":"int64","description":"`limit_exceeded` only: the count this request has.","minimum":0,"uniqueKey":"errors.items.[INDEX].actual.oneOf.1","typeLabel":"null"}],"uniqueKey":"errors.items.[INDEX].actual","typeLabel":"integer\u003cint64> | null"},"limit":{"oneOf":[{"type":"integer","format":"int64","description":"`limit_exceeded` only: the published cap.","minimum":0,"uniqueKey":"errors.items.[INDEX].limit.oneOf.0","typeLabel":"integer\u003cint64>"},{"type":"null","format":"int64","description":"`limit_exceeded` only: the published cap.","minimum":0,"uniqueKey":"errors.items.[INDEX].limit.oneOf.1","typeLabel":"null"}],"uniqueKey":"errors.items.[INDEX].limit","typeLabel":"integer\u003cint64> | null"},"pointer":{"oneOf":[{"type":"string","description":"RFC 6901 JSON Pointer into the request body, when the problem has a\nlocation. It is relative to the root of the body, so a field of the\nproblem reads `/problem/...` (e.g.\n`\"/problem/vehicles/0/shifts/0/from\"`).","uniqueKey":"errors.items.[INDEX].pointer.oneOf.0","typeLabel":"string"},{"type":"null","description":"RFC 6901 JSON Pointer into the request body, when the problem has a\nlocation. It is relative to the root of the body, so a field of the\nproblem reads `/problem/...` (e.g.\n`\"/problem/vehicles/0/shifts/0/from\"`).","uniqueKey":"errors.items.[INDEX].pointer.oneOf.1","typeLabel":"null"}],"uniqueKey":"errors.items.[INDEX].pointer","typeLabel":"string | null"}},"uniqueKey":"errors.items.[INDEX]","typeLabel":"object"},"description":"One entry per problem found in the request. Empty for non-input errors.","uniqueKey":"errors","typeLabel":"object[]"},"request_id":{"oneOf":[{"type":"string","description":"The `X-Request-Id` of the request (echoed, or generated when absent).","uniqueKey":"request_id.oneOf.0","typeLabel":"string"},{"type":"null","description":"The `X-Request-Id` of the request (echoed, or generated when absent).","uniqueKey":"request_id.oneOf.1","typeLabel":"null"}],"uniqueKey":"request_id","typeLabel":"string | null"}},"example":{"code":"invalid_request","errors":[{"code":"out_of_range","message":"depot 'gent': service_duration_s must be >= 0, got -60","pointer":"/problem/depots/0/service_duration_s"}],"message":"depot 'gent': service_duration_s must be >= 0, got -60","request_id":"req_7f3a2c90d1e4b5a6","status":"BAD_REQUEST"},"uniqueKey":"","typeLabel":"object"},"example":{"code":"feature_not_enabled","message":"travel.engine: 'tomtom_real_time' is not enabled for this account; use engine 'tomtom'","request_id":"req_7f3a2c90d1e4b5a6","status":"FORBIDDEN"},"examples":{"Example":{"title":"Example","value":{"code":"feature_not_enabled","message":"travel.engine: 'tomtom_real_time' is not enabled for this account; use engine 'tomtom'","request_id":"req_7f3a2c90d1e4b5a6","status":"FORBIDDEN"}}},"exampleType":"examples"}},"exampleType":"examples"},"31071ba1-e707-4080-b5dd-1fd5ca2e59e9":{"description":"Request body larger than 10 MiB (10,485,760 bytes), counted after gzip decompression","headers":{"x-request-id":{"schema":{"type":"string"},"description":"The request's `X-Request-Id`, echoed, or a generated `req_…` id."}},"content":{"application/json":{"schema":{"type":"object","description":"Error body of every `/v3/routing/*` endpoint.\n\n`status` is the HTTP status as text, `code` says what kind of failure it\nis, `request_id` identifies the request, and `errors` holds one item per\nproblem found in the request. Branch on `code`, and on `errors[].code` for\n400s; the messages are for people.","required":["status","code","message"],"properties":{"code":{"type":"string","description":"What kind of failure this is. One value per HTTP status class.","x-extensible-enum":["invalid_request","feature_not_enabled","payload_too_large","unsupported_media_type","internal","travel_provider_error","overloaded"],"isRequired":true,"uniqueKey":"code","typeLabel":"string"},"message":{"type":"string","description":"Human-readable summary. With exactly one item it is that item's\nmessage; with several, `\"{n} problems in request\"` (at most 100 items\nare listed, and the message says when the list is cut).","isRequired":true,"uniqueKey":"message","typeLabel":"string"},"status":{"type":"string","description":"The HTTP status as text, e.g. `\"BAD_REQUEST\"` or\n`\"SERVICE_UNAVAILABLE\"`.","example":"BAD_REQUEST","isRequired":true,"uniqueKey":"status","typeLabel":"string"},"errors":{"type":"array","items":{"type":"object","description":"One problem in a request.","required":["code","message"],"properties":{"code":{"type":"string","description":"What is wrong.","x-extensible-enum":["invalid_json","invalid_type","unknown_field","missing_field","invalid_value","not_supported","out_of_range","duplicate_id","unknown_reference","conflicting_fields","limit_exceeded"],"isRequired":true,"uniqueKey":"errors.items.[INDEX].code","typeLabel":"string"},"message":{"type":"string","description":"Human-readable description.","isRequired":true,"uniqueKey":"errors.items.[INDEX].message","typeLabel":"string"},"actual":{"oneOf":[{"type":"integer","format":"int64","description":"`limit_exceeded` only: the count this request has.","minimum":0,"uniqueKey":"errors.items.[INDEX].actual.oneOf.0","typeLabel":"integer\u003cint64>"},{"type":"null","format":"int64","description":"`limit_exceeded` only: the count this request has.","minimum":0,"uniqueKey":"errors.items.[INDEX].actual.oneOf.1","typeLabel":"null"}],"uniqueKey":"errors.items.[INDEX].actual","typeLabel":"integer\u003cint64> | null"},"limit":{"oneOf":[{"type":"integer","format":"int64","description":"`limit_exceeded` only: the published cap.","minimum":0,"uniqueKey":"errors.items.[INDEX].limit.oneOf.0","typeLabel":"integer\u003cint64>"},{"type":"null","format":"int64","description":"`limit_exceeded` only: the published cap.","minimum":0,"uniqueKey":"errors.items.[INDEX].limit.oneOf.1","typeLabel":"null"}],"uniqueKey":"errors.items.[INDEX].limit","typeLabel":"integer\u003cint64> | null"},"pointer":{"oneOf":[{"type":"string","description":"RFC 6901 JSON Pointer into the request body, when the problem has a\nlocation. It is relative to the root of the body, so a field of the\nproblem reads `/problem/...` (e.g.\n`\"/problem/vehicles/0/shifts/0/from\"`).","uniqueKey":"errors.items.[INDEX].pointer.oneOf.0","typeLabel":"string"},{"type":"null","description":"RFC 6901 JSON Pointer into the request body, when the problem has a\nlocation. It is relative to the root of the body, so a field of the\nproblem reads `/problem/...` (e.g.\n`\"/problem/vehicles/0/shifts/0/from\"`).","uniqueKey":"errors.items.[INDEX].pointer.oneOf.1","typeLabel":"null"}],"uniqueKey":"errors.items.[INDEX].pointer","typeLabel":"string | null"}},"uniqueKey":"errors.items.[INDEX]","typeLabel":"object"},"description":"One entry per problem found in the request. Empty for non-input errors.","uniqueKey":"errors","typeLabel":"object[]"},"request_id":{"oneOf":[{"type":"string","description":"The `X-Request-Id` of the request (echoed, or generated when absent).","uniqueKey":"request_id.oneOf.0","typeLabel":"string"},{"type":"null","description":"The `X-Request-Id` of the request (echoed, or generated when absent).","uniqueKey":"request_id.oneOf.1","typeLabel":"null"}],"uniqueKey":"request_id","typeLabel":"string | null"}},"example":{"code":"invalid_request","errors":[{"code":"out_of_range","message":"depot 'gent': service_duration_s must be >= 0, got -60","pointer":"/problem/depots/0/service_duration_s"}],"message":"depot 'gent': service_duration_s must be >= 0, got -60","request_id":"req_7f3a2c90d1e4b5a6","status":"BAD_REQUEST"},"uniqueKey":"","typeLabel":"object"},"example":{"code":"payload_too_large","message":"Request body exceeds 10485760 bytes","request_id":"req_7f3a2c90d1e4b5a6","status":"PAYLOAD_TOO_LARGE"},"examples":{"Example":{"title":"Example","value":{"code":"payload_too_large","message":"Request body exceeds 10485760 bytes","request_id":"req_7f3a2c90d1e4b5a6","status":"PAYLOAD_TOO_LARGE"}}},"exampleType":"examples"}},"exampleType":"examples"},"cc4252b9-ccaa-4394-ab60-4d5c8f7bc60b":{"description":"Request `Content-Type` is missing or not JSON (`application/json` or `application/*+json`), or the body has a `Content-Encoding` other than `gzip` (the message says which)","headers":{"x-request-id":{"schema":{"type":"string"},"description":"The request's `X-Request-Id`, echoed, or a generated `req_…` id."}},"content":{"application/json":{"schema":{"type":"object","description":"Error body of every `/v3/routing/*` endpoint.\n\n`status` is the HTTP status as text, `code` says what kind of failure it\nis, `request_id` identifies the request, and `errors` holds one item per\nproblem found in the request. Branch on `code`, and on `errors[].code` for\n400s; the messages are for people.","required":["status","code","message"],"properties":{"code":{"type":"string","description":"What kind of failure this is. One value per HTTP status class.","x-extensible-enum":["invalid_request","feature_not_enabled","payload_too_large","unsupported_media_type","internal","travel_provider_error","overloaded"],"isRequired":true,"uniqueKey":"code","typeLabel":"string"},"message":{"type":"string","description":"Human-readable summary. With exactly one item it is that item's\nmessage; with several, `\"{n} problems in request\"` (at most 100 items\nare listed, and the message says when the list is cut).","isRequired":true,"uniqueKey":"message","typeLabel":"string"},"status":{"type":"string","description":"The HTTP status as text, e.g. `\"BAD_REQUEST\"` or\n`\"SERVICE_UNAVAILABLE\"`.","example":"BAD_REQUEST","isRequired":true,"uniqueKey":"status","typeLabel":"string"},"errors":{"type":"array","items":{"type":"object","description":"One problem in a request.","required":["code","message"],"properties":{"code":{"type":"string","description":"What is wrong.","x-extensible-enum":["invalid_json","invalid_type","unknown_field","missing_field","invalid_value","not_supported","out_of_range","duplicate_id","unknown_reference","conflicting_fields","limit_exceeded"],"isRequired":true,"uniqueKey":"errors.items.[INDEX].code","typeLabel":"string"},"message":{"type":"string","description":"Human-readable description.","isRequired":true,"uniqueKey":"errors.items.[INDEX].message","typeLabel":"string"},"actual":{"oneOf":[{"type":"integer","format":"int64","description":"`limit_exceeded` only: the count this request has.","minimum":0,"uniqueKey":"errors.items.[INDEX].actual.oneOf.0","typeLabel":"integer\u003cint64>"},{"type":"null","format":"int64","description":"`limit_exceeded` only: the count this request has.","minimum":0,"uniqueKey":"errors.items.[INDEX].actual.oneOf.1","typeLabel":"null"}],"uniqueKey":"errors.items.[INDEX].actual","typeLabel":"integer\u003cint64> | null"},"limit":{"oneOf":[{"type":"integer","format":"int64","description":"`limit_exceeded` only: the published cap.","minimum":0,"uniqueKey":"errors.items.[INDEX].limit.oneOf.0","typeLabel":"integer\u003cint64>"},{"type":"null","format":"int64","description":"`limit_exceeded` only: the published cap.","minimum":0,"uniqueKey":"errors.items.[INDEX].limit.oneOf.1","typeLabel":"null"}],"uniqueKey":"errors.items.[INDEX].limit","typeLabel":"integer\u003cint64> | null"},"pointer":{"oneOf":[{"type":"string","description":"RFC 6901 JSON Pointer into the request body, when the problem has a\nlocation. It is relative to the root of the body, so a field of the\nproblem reads `/problem/...` (e.g.\n`\"/problem/vehicles/0/shifts/0/from\"`).","uniqueKey":"errors.items.[INDEX].pointer.oneOf.0","typeLabel":"string"},{"type":"null","description":"RFC 6901 JSON Pointer into the request body, when the problem has a\nlocation. It is relative to the root of the body, so a field of the\nproblem reads `/problem/...` (e.g.\n`\"/problem/vehicles/0/shifts/0/from\"`).","uniqueKey":"errors.items.[INDEX].pointer.oneOf.1","typeLabel":"null"}],"uniqueKey":"errors.items.[INDEX].pointer","typeLabel":"string | null"}},"uniqueKey":"errors.items.[INDEX]","typeLabel":"object"},"description":"One entry per problem found in the request. Empty for non-input errors.","uniqueKey":"errors","typeLabel":"object[]"},"request_id":{"oneOf":[{"type":"string","description":"The `X-Request-Id` of the request (echoed, or generated when absent).","uniqueKey":"request_id.oneOf.0","typeLabel":"string"},{"type":"null","description":"The `X-Request-Id` of the request (echoed, or generated when absent).","uniqueKey":"request_id.oneOf.1","typeLabel":"null"}],"uniqueKey":"request_id","typeLabel":"string | null"}},"example":{"code":"invalid_request","errors":[{"code":"out_of_range","message":"depot 'gent': service_duration_s must be >= 0, got -60","pointer":"/problem/depots/0/service_duration_s"}],"message":"depot 'gent': service_duration_s must be >= 0, got -60","request_id":"req_7f3a2c90d1e4b5a6","status":"BAD_REQUEST"},"uniqueKey":"","typeLabel":"object"},"example":{"code":"unsupported_media_type","message":"Expected request with `Content-Type: application/json`","request_id":"req_7f3a2c90d1e4b5a6","status":"UNSUPPORTED_MEDIA_TYPE"},"examples":{"Example":{"title":"Example","value":{"code":"unsupported_media_type","message":"Expected request with `Content-Type: application/json`","request_id":"req_7f3a2c90d1e4b5a6","status":"UNSUPPORTED_MEDIA_TYPE"}}},"exampleType":"examples"}},"exampleType":"examples"},"85e1633f-c6ff-46a5-95b5-3b957de6044a":{"description":"Rate limited. Returned by the API gateway before the request reaches the solver, so it does not use the `ErrorBody` shape. Back off and retry.","content":{"_mintlify/placeholder":{"schema":{"type":"object","description":""}}}},"9bdde50b-2ab8-4535-9514-9d7f04d4275d":{"description":"Server-side error (`code: internal`).","headers":{"x-request-id":{"schema":{"type":"string"},"description":"The request's `X-Request-Id`, echoed, or a generated `req_…` id."}},"content":{"application/json":{"schema":{"type":"object","description":"Error body of every `/v3/routing/*` endpoint.\n\n`status` is the HTTP status as text, `code` says what kind of failure it\nis, `request_id` identifies the request, and `errors` holds one item per\nproblem found in the request. Branch on `code`, and on `errors[].code` for\n400s; the messages are for people.","required":["status","code","message"],"properties":{"code":{"type":"string","description":"What kind of failure this is. One value per HTTP status class.","x-extensible-enum":["invalid_request","feature_not_enabled","payload_too_large","unsupported_media_type","internal","travel_provider_error","overloaded"],"isRequired":true,"uniqueKey":"code","typeLabel":"string"},"message":{"type":"string","description":"Human-readable summary. With exactly one item it is that item's\nmessage; with several, `\"{n} problems in request\"` (at most 100 items\nare listed, and the message says when the list is cut).","isRequired":true,"uniqueKey":"message","typeLabel":"string"},"status":{"type":"string","description":"The HTTP status as text, e.g. `\"BAD_REQUEST\"` or\n`\"SERVICE_UNAVAILABLE\"`.","example":"BAD_REQUEST","isRequired":true,"uniqueKey":"status","typeLabel":"string"},"errors":{"type":"array","items":{"type":"object","description":"One problem in a request.","required":["code","message"],"properties":{"code":{"type":"string","description":"What is wrong.","x-extensible-enum":["invalid_json","invalid_type","unknown_field","missing_field","invalid_value","not_supported","out_of_range","duplicate_id","unknown_reference","conflicting_fields","limit_exceeded"],"isRequired":true,"uniqueKey":"errors.items.[INDEX].code","typeLabel":"string"},"message":{"type":"string","description":"Human-readable description.","isRequired":true,"uniqueKey":"errors.items.[INDEX].message","typeLabel":"string"},"actual":{"oneOf":[{"type":"integer","format":"int64","description":"`limit_exceeded` only: the count this request has.","minimum":0,"uniqueKey":"errors.items.[INDEX].actual.oneOf.0","typeLabel":"integer\u003cint64>"},{"type":"null","format":"int64","description":"`limit_exceeded` only: the count this request has.","minimum":0,"uniqueKey":"errors.items.[INDEX].actual.oneOf.1","typeLabel":"null"}],"uniqueKey":"errors.items.[INDEX].actual","typeLabel":"integer\u003cint64> | null"},"limit":{"oneOf":[{"type":"integer","format":"int64","description":"`limit_exceeded` only: the published cap.","minimum":0,"uniqueKey":"errors.items.[INDEX].limit.oneOf.0","typeLabel":"integer\u003cint64>"},{"type":"null","format":"int64","description":"`limit_exceeded` only: the published cap.","minimum":0,"uniqueKey":"errors.items.[INDEX].limit.oneOf.1","typeLabel":"null"}],"uniqueKey":"errors.items.[INDEX].limit","typeLabel":"integer\u003cint64> | null"},"pointer":{"oneOf":[{"type":"string","description":"RFC 6901 JSON Pointer into the request body, when the problem has a\nlocation. It is relative to the root of the body, so a field of the\nproblem reads `/problem/...` (e.g.\n`\"/problem/vehicles/0/shifts/0/from\"`).","uniqueKey":"errors.items.[INDEX].pointer.oneOf.0","typeLabel":"string"},{"type":"null","description":"RFC 6901 JSON Pointer into the request body, when the problem has a\nlocation. It is relative to the root of the body, so a field of the\nproblem reads `/problem/...` (e.g.\n`\"/problem/vehicles/0/shifts/0/from\"`).","uniqueKey":"errors.items.[INDEX].pointer.oneOf.1","typeLabel":"null"}],"uniqueKey":"errors.items.[INDEX].pointer","typeLabel":"string | null"}},"uniqueKey":"errors.items.[INDEX]","typeLabel":"object"},"description":"One entry per problem found in the request. Empty for non-input errors.","uniqueKey":"errors","typeLabel":"object[]"},"request_id":{"oneOf":[{"type":"string","description":"The `X-Request-Id` of the request (echoed, or generated when absent).","uniqueKey":"request_id.oneOf.0","typeLabel":"string"},{"type":"null","description":"The `X-Request-Id` of the request (echoed, or generated when absent).","uniqueKey":"request_id.oneOf.1","typeLabel":"null"}],"uniqueKey":"request_id","typeLabel":"string | null"}},"example":{"code":"invalid_request","errors":[{"code":"out_of_range","message":"depot 'gent': service_duration_s must be >= 0, got -60","pointer":"/problem/depots/0/service_duration_s"}],"message":"depot 'gent': service_duration_s must be >= 0, got -60","request_id":"req_7f3a2c90d1e4b5a6","status":"BAD_REQUEST"},"uniqueKey":"","typeLabel":"object"},"examples":{"Example":{"title":"Example","value":{"code":"invalid_request","errors":[{"code":"out_of_range","message":"depot 'gent': service_duration_s must be >= 0, got -60","pointer":"/problem/depots/0/service_duration_s"}],"message":"depot 'gent': service_duration_s must be >= 0, got -60","request_id":"req_7f3a2c90d1e4b5a6","status":"BAD_REQUEST"}}},"exampleType":"generated"}},"exampleType":"generated"}},"security":{"9ccad23f-2998-47f5-b1b2-2885a0d8c12b":{"apiKey":{"type":"apiKey","in":"header","name":"Authorization","scopes":[],"schemeName":"apiKey"}}},"servers":{"201228c4-350a-441d-b6ae-257ddac506eb":{"url":"https://api.solvice.io","description":"Production — Solvice API gateway"}},"processedSecurityOptions":[{"schemes":[{"scheme":{"type":"apiKey","in":"header","name":"Authorization","scopes":[],"schemeName":"apiKey"},"schema":{"title":"Authorization","type":"string","isRequired":true,"typeLabel":"string","deprecated":false},"schemeName":"apiKey","name":"Authorization"}],"title":"apiKey"}]},"originalFileLocation":"api-reference/vrp-v3.json"},"subdomain":"solvice-68592f22","siteName":"Solvice Docs","title":"Validate evaluate - Solvice Docs","navMaps":{"firstHrefInVersion":{"v3":{"href":"/api-reference/vrp/v3/validate-evaluate","matchLevel":0},"v2":{"href":"/guides/platform/platform","matchLevel":4}},"firstHrefInLanguage":{}},"lastModified":"2026-10-29T08:47:33.258Z","originalFileLocation":"api-reference/vrp/v3/validate-evaluate.mdx"},"headHtml":"\u003cscript data-mint-head>(function(){var d=document.documentElement,p=null;if(!p){try{p=localStorage.getItem(\"isDarkMode\")}catch(e){}if(p==='true')p='dark';else if(p==='false')p='light';if(p!=='light'\u0026\u0026p!=='dark'\u0026\u0026p!=='system')p=\"system\"}var r=p==='system'?(matchMedia(\"(prefers-color-scheme: dark)\").matches?'dark':'light'):p;d.classList.remove(r==='dark'?'light':'dark');d.classList.add(r);d.setAttribute(\"data-theme-preference\",p)})();\u003c/script>\u003cmeta data-mint-head name=\"description\" content=\"Check a evaluate request without running it\">\u003cmeta data-mint-head name=\"keywords\" content=\"Route Optimization, Route API, Optimization API, Workforce Scheduling, Solvice\">\u003cmeta data-mint-head name=\"application-name\" content=\"Solvice Docs\">\u003cmeta data-mint-head name=\"generator\" content=\"Mintlify\">\u003cmeta data-mint-head name=\"robots\" content=\"index, follow\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"192x192\" href=\"/mintlify-assets/_mintlify/favicons/solvice-68592f22/wZOj_k-mDHXJa5jh/_generated/favicon/android-chrome-192x192.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"apple-touch-icon\" type=\"image/png\" sizes=\"180x180\" href=\"/mintlify-assets/_mintlify/favicons/solvice-68592f22/wZOj_k-mDHXJa5jh/_generated/favicon/apple-touch-icon.png\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"/mintlify-assets/_mintlify/favicons/solvice-68592f22/wZOj_k-mDHXJa5jh/_generated/favicon/favicon-16x16.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"/mintlify-assets/_mintlify/favicons/solvice-68592f22/wZOj_k-mDHXJa5jh/_generated/favicon/favicon-32x32.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"shortcut icon\" type=\"image/x-icon\" href=\"/mintlify-assets/_mintlify/favicons/solvice-68592f22/wZOj_k-mDHXJa5jh/_generated/favicon/favicon.ico\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"192x192\" href=\"/mintlify-assets/_mintlify/favicons/solvice-68592f22/wZOj_k-mDHXJa5jh/_generated/favicon-dark/android-chrome-192x192.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"/mintlify-assets/_mintlify/favicons/solvice-68592f22/wZOj_k-mDHXJa5jh/_generated/favicon-dark/favicon-16x16.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"/mintlify-assets/_mintlify/favicons/solvice-68592f22/wZOj_k-mDHXJa5jh/_generated/favicon-dark/favicon-32x32.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"shortcut icon\" type=\"image/x-icon\" href=\"/mintlify-assets/_mintlify/favicons/solvice-68592f22/wZOj_k-mDHXJa5jh/_generated/favicon-dark/favicon.ico\" media=\"(prefers-color-scheme: dark)\">\u003cmeta data-mint-head property=\"og:title\" content=\"Validate evaluate - Solvice Docs\">\u003cmeta data-mint-head property=\"og:description\" content=\"Check a evaluate request without running it\">\u003cmeta data-mint-head property=\"og:site_name\" content=\"Solvice Docs\">\u003cmeta data-mint-head property=\"og:url\" content=\"https://docs.solvice.io/api-reference/vrp/v3/validate-evaluate\">\u003cmeta data-mint-head property=\"og:type\" content=\"website\">\u003cmeta data-mint-head property=\"og:image\" content=\"https://solvice-68592f22.mintlify.app/link to your default meta tag image\">\u003cmeta data-mint-head property=\"og:image:width\" content=\"1200\">\u003cmeta data-mint-head property=\"og:image:height\" content=\"630\">\u003cmeta data-mint-head name=\"twitter:card\" content=\"summary_large_image\">\u003cmeta data-mint-head name=\"twitter:title\" content=\"Validate evaluate - Solvice Docs\">\u003cmeta data-mint-head name=\"twitter:description\" content=\"Check a evaluate request without running it\">\u003cmeta data-mint-head name=\"twitter:image\" content=\"https://solvice-68592f22.mintlify.app/link to your default meta tag image\">\u003cmeta data-mint-head name=\"twitter:image:width\" content=\"1200\">\u003cmeta data-mint-head name=\"twitter:image:height\" content=\"630\">\u003cmeta data-mint-head name=\"msapplication-config\" content=\"/mintlify-assets/_mintlify/favicons/solvice-68592f22/wZOj_k-mDHXJa5jh/_generated/favicon/browserconfig.xml\">\u003cmeta data-mint-head name=\"apple-mobile-web-app-title\" content=\"Solvice Docs\">\u003cmeta data-mint-head name=\"msapplication-TileColor\" content=\"#0f62fe\">\u003cmeta data-mint-head name=\"charset\" content=\"UTF-8\">\u003cmeta data-mint-head name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\u003cmeta data-mint-head name=\"author\" content=\"Christophe Van Huele\">\u003cmeta data-mint-head name=\"googlebot\" content=\"index, follow\">\u003cmeta data-mint-head name=\"google\" content=\"notranslate\">\u003cmeta data-mint-head name=\"google-site-verification\" content=\"verification_token\">\u003clink data-mint-head rel=\"canonical\" href=\"https://docs.solvice.io/api-reference/vrp/v3/validate-evaluate\">\u003clink data-mint-head rel=\"alternate\" type=\"application/xml\" href=\"/sitemap.xml\">\u003clink data-mint-head rel=\"alternate\" type=\"text/markdown\" href=\"/api-reference/vrp/v3/validate-evaluate.md\">\u003cscript data-mint-head type=\"application/ld+json\">{\"@context\":\"https://schema.org\",\"@graph\":[{\"@type\":\"Organization\",\"@id\":\"https://docs.solvice.io/#organization\",\"name\":\"Solvice Docs\",\"url\":\"https://docs.solvice.io\",\"logo\":{\"@type\":\"ImageObject\",\"url\":\"https://mintcdn.com/solvice-68592f22/1KJ_2AIotizI1Bng/logo/light.svg?fit=max\u0026auto=format\u0026n=1KJ_2AIotizI1Bng\u0026q=85\u0026s=e93560fee320491613107060a1afc094\"}},{\"@type\":\"WebSite\",\"@id\":\"https://docs.solvice.io#website\",\"name\":\"Solvice Docs\",\"url\":\"https://docs.solvice.io\",\"publisher\":{\"@id\":\"https://docs.solvice.io/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https://docs.solvice.io/api-reference/vrp/v3/validate-evaluate#webpage\",\"url\":\"https://docs.solvice.io/api-reference/vrp/v3/validate-evaluate\",\"name\":\"Validate evaluate\",\"description\":\"Check a evaluate request without running it\",\"dateModified\":\"2026-10-29T08:47:33.258Z\",\"isPartOf\":{\"@id\":\"https://docs.solvice.io#website\"},\"breadcrumb\":{\"@id\":\"https://docs.solvice.io/api-reference/vrp/v3/validate-evaluate#breadcrumb\"}},{\"@type\":\"BreadcrumbList\",\"@id\":\"https://docs.solvice.io/api-reference/vrp/v3/validate-evaluate#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Routing API\",\"item\":\"https://docs.solvice.io/api-reference/vrp/v3/introduction\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Validate\",\"item\":\"https://docs.solvice.io/api-reference/vrp/v3/validate-solve\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"Validate evaluate\",\"item\":\"https://docs.solvice.io/api-reference/vrp/v3/validate-evaluate\"}]},{\"@type\":[\"TechArticle\",\"APIReference\"],\"@id\":\"https://docs.solvice.io/api-reference/vrp/v3/validate-evaluate#apireference\",\"headline\":\"Validate evaluate\",\"name\":\"Validate evaluate\",\"description\":\"Check a evaluate request without running it\",\"url\":\"https://docs.solvice.io/api-reference/vrp/v3/validate-evaluate\",\"mainEntityOfPage\":{\"@id\":\"https://docs.solvice.io/api-reference/vrp/v3/validate-evaluate#webpage\"},\"image\":\"https://docs.solvice.io/link%20to%20your%20default%20meta%20tag%20image\",\"dateModified\":\"2026-10-29T08:47:33.258Z\",\"publisher\":{\"@id\":\"https://docs.solvice.io/#organization\"},\"isPartOf\":{\"@id\":\"https://docs.solvice.io#website\"}}]}\u003c/script>\u003cscript data-mint-head type=\"application/ld+json\">{\"@context\":\"https://schema.org\",\"@type\":\"WebSite\",\"name\":\"Solvice Docs\",\"creator\":{\"@type\":\"Organization\",\"name\":\"Mintlify\",\"url\":\"https://mintlify.com\"}}\u003c/script>","siteName":"Solvice Docs","nav":{"global":{"anchors":[{"anchor":"Dashboard","icon":"book-open-cover","href":"https://platform.solvice.io"},{"anchor":"Website","icon":"planet-ringed","href":"https://www.solvice.io"},{"anchor":"Blog","icon":"newspaper","href":"https://www.solvice.io/blog/news"}]},"versions":[{"version":"v3","tabs":[{"tab":"Guides","pages":[{"title":"Guides","href":"/guides/platform/platform"}]},{"tab":"API Reference","groups":[{"group":"Routing API","pages":[{"title":"Introduction","href":"/api-reference/vrp/v3/introduction"},{"title":"OpenAPI specification","href":"/api-reference/vrp/v3/openapi"},{"group":"Endpoints","pages":[{"title":"Solve","openapi":"vrp-v3 POST /v3/routing/solve","href":"/api-reference/vrp/v3/solve"},{"title":"Evaluate","openapi":"vrp-v3 POST /v3/routing/evaluate","href":"/api-reference/vrp/v3/evaluate"},{"title":"Suggest","openapi":"vrp-v3 POST /v3/routing/suggest","href":"/api-reference/vrp/v3/suggest"}]},{"group":"Validate","pages":[{"title":"Validate solve","openapi":"vrp-v3 POST /v3/routing/validate/solve","description":"Check a solve request without running it","href":"/api-reference/vrp/v3/validate-solve"},{"title":"Validate evaluate","openapi":"vrp-v3 POST /v3/routing/validate/evaluate","href":"/api-reference/vrp/v3/validate-evaluate"},{"title":"Validate suggest","openapi":"vrp-v3 POST /v3/routing/validate/suggest","description":"Check a suggest request without running it","href":"/api-reference/vrp/v3/validate-suggest"}]},{"group":"Async runs","pages":[{"title":"Submit a run","openapi":"vrp-v3-runs POST /v3/routing/runs","href":"/api-reference/vrp/v3/runs-submit"},{"title":"Run status","openapi":"vrp-v3-runs GET /v3/routing/runs/{id}","href":"/api-reference/vrp/v3/runs-status"},{"title":"Run result","openapi":"vrp-v3-runs GET /v3/routing/runs/{id}/result","href":"/api-reference/vrp/v3/runs-result"},{"title":"Cancel a run","openapi":"vrp-v3-runs POST /v3/routing/runs/{id}/cancel","href":"/api-reference/vrp/v3/runs-cancel"}]}]}]},{"tab":"Changelog","pages":[{"title":"Changelog","href":"/changelog/vrp-v3"}]}]},{"version":"v2","default":true,"pages":[{"title":"v2","href":"/guides/platform/platform"}]}]},"title":"Validate evaluate - Solvice Docs","buildId":"dpl_2xiSHD9XEvLsPGPcfoMtkLTB3dy9","deploymentId":"dpl_2xiSHD9XEvLsPGPcfoMtkLTB3dy9","dynamics":["c2aa737661","b0f84f53ff","a9bb46feb3","2b790eda92"],"chunks":["OpenApiReferenceProvider-DmVyH30O.js","utils-BHQqGGOd.js","cloneDeep-izs3Hzxb.js","_Uint8Array-BVIqJ90l.js","isObjectLike-C8vmzPEN.js","isArray-Dcu1dQ5t.js","utils-CD-E4BIt.js","toString-BX-iyh8G.js","isSymbol-CSH9U2Gm.js","addUniqueKeysToSchema-Bp5Lq9Ds.js","snippetPresets-C4xAVCFP.js","style-to-object-BY3JEAdk.js","v4-DIgz8zy6.js","Page-CBCH2P7b.js","ApiExamples-CgXVLxUC.js","isEqual-BfaiBbcl.js","usePlaygroundInputsStore-BF8I5oUf.js","shallow-Byd0lWnC.js","getApiPlaygroundDisplay-BGOZG1OK.js","CodeSnippet-CpvQL0CY.js","CodeSnippets-B8wkBKXa.js","getPastedJson-Ry3scI3Y.js","icon-D7a9HcdD.js","MethodPill-CJ8pmHhz.js","DuplicateIcon-rh1HJF0t.js","createIcon-DvGznqYs.js","DynamicMarkdown-Cc6AuSHS.js","SectionHeading-B4A0S-ep.js","axios-vUo_bRtp.js","Markdown-Cc16CX65.js","clsx-Cs6nMGht.js","lib-DuNMoZ05.js","lib-B8HbPgcC.js","html-void-elements-mCSPHezU.js","dist-zbf22OZA.js","katex-YMM-FMeD.js","marked.esm-CZWythHk.js","AssistantPageLink-C_fs-y5n.js"]}