Lock part of a tour while the engine re-plans the rest, supervise a tour live as it progresses, and reserve a stop for one resource without making it mandatory.
Real-time re-optimization covers replacing the whole plan on disruption. This page covers the finer-grained controls: locking part of a resource’s tour in place while the engine re-plans the rest, and reserving a stop for exactly one resource without making it mandatory.
state is set per resource and works on two levels: state.mode applies to the resource as a whole, while status applies to each individual entry in state.assignments (a stop, a break, or the tour’s begin or end).
status: "assigned" — the entry is assigned to this resource, but its position in the sequence isn’t imposed: the engine sequences the resource’s assigned entries according to the plan’s objectives.
status: "fixed" (the default) — the entry is taken as given: its position in the sequence, and its times, aren’t challenged.
mode: "free" (the default) — the engine can add more stops to this resource’s tour.
mode: "fixed" — the resource’s tour is limited to its assigned entries. The engine can’t add any more stops.
The two combine as follows:
assignments[].status: "assigned"
assignments[].status: "fixed"
mode: "fixed"
The engine sequences the given stops according to the plan’s objectives, adding no further stops — useful to check whether assigning these stops to this resource is feasible at all (see Testing a stop on a specific resource).
The engine only checks the given sequence as-is, adding no further stops — a debug/evaluation mode: pose an existing tour to see whether it’s feasible and why a given stop isn’t covered.
mode: "free"
Not allowed.
The engine keeps the given sequence exactly as the start of the tour, and is free to add new stops after it — the real-time supervision case below. fixed assignments can only form the beginning of the tour: the engine never inserts a new stop before or between them.
Reflect a driver’s real progress with successive PUT /plans/{planId} calls: a begin assignment with the real departureTime, then stop assignments filled in with arrivalTime/beginTime/departureTime as they actually happen, a break inserted dynamically if needed. Keep mode: "free" so the engine can still plan what comes after, and give every pinned assignment status: "fixed". Each of these calls carries the complete plan; the following excerpt only shows the resources entry being updated:
For a pinned time to be kept as given rather than re-planned by the optimization, every assignment before it in the sequence must also carry its times, and those times must be chronologically consistent: each entry’s times can’t be earlier than the previous entry’s. In practice, fill in assignments in the order the driver actually completes them, starting from begin, without leaving an earlier entry’s times blank.
Pinning a stop to exactly one resource (pattern “Isolate”)
forbiddenAssignment bars the resources that carry its resourceTag from the stops that carry its stopTag. See Barring one resource from a stop. For a breakdown, see also Real-time re-optimization. There’s no single dedicated field for the opposite — reserving a stop for one resource — but three mechanisms get you there, from strictest to softest:
state.assignments — pin the stop directly onto the resource’s tour, as described in the first section of this page. The only one of the three that the engine keeps exactly as given.
skills/requiredSkills (pattern “Isolate”) — give the resource a skills entry derived from its own id (for example skills: ["resource-12"]) and require it on the targeted order (requiredSkills: ["resource-12"]). No other resource can then serve the stop.
preferredStopTags — tag the stop, list that tag in the resource’s preferredStopTags, and include maximizePreferredStops in objectives. A soft preference: another resource can still take the stop when that serves a higher-priority objective better.
Pinning a stop to a resource through requiredSkills doesn’t guarantee that the stop is planned: it only restricts which resource can serve it. The engine can still leave the stop unplanned if the assignment degrades a higher-priority objective. To keep the stop on that resource’s tour whatever the objectives, use state.assignments instead.
{"docsConfig":{"theme":"mint","$schema":"https://mintlify.com/docs.json","name":"Kardinal Route Optimization API","description":"Documentation for Kardinal's self-service logistics optimization API. Create an account and get an API key at https://console.kardinal.ai.","colors":{"primary":"#4D6AFF","light":"#C5A4FF","dark":"#1B1813"},"logo":{"light":"https://mintcdn.com/kardinal/NzVu4E70FNnktm7V/images/Logo-blue-black.png?fit=max\u0026auto=format\u0026n=NzVu4E70FNnktm7V\u0026q=85\u0026s=877e4130943370aa62e85ed76662c9bc","dark":"https://mintcdn.com/kardinal/NzVu4E70FNnktm7V/images/Logo-blue-white.png?fit=max\u0026auto=format\u0026n=NzVu4E70FNnktm7V\u0026q=85\u0026s=65aa4a2a695f749b32d5fe890b8017ec","href":"/"},"favicon":"https://mintcdn.com/kardinal/NzVu4E70FNnktm7V/images/Icon-blue.png?fit=max\u0026auto=format\u0026n=NzVu4E70FNnktm7V\u0026q=85\u0026s=e8d6c833a0278ea081ea2f0507ed7cd5","navbar":{"links":[{"href":"mailto:customer.success@kardinal.ai","label":"Support"},{"href":"https://console.kardinal.ai","label":"Sign in"}],"primary":{"type":"button","label":"Get API key","href":"https://console.kardinal.ai/keys"}},"footer":{"socials":{"website":"https://kardinal.ai"}},"seo":{"organization":{"id":"https://kardinal.ai/#organization","name":"Kardinal","url":"https://kardinal.ai/","sameAs":["https://www.linkedin.com/company/kardinalai","https://github.com/KardinalAI"]},"indexing":"navigable"},"integrations":{"gtm":{"tagId":"GTM-W6RBWSX"}},"banner":{"content":"Every new account starts with 1,000 free credits. [Create your account](https://console.kardinal.ai)","dismissible":true},"styling":{"latex":false},"navigation":{"languages":[{"language":"en","default":true,"href":""}]}},"deployment":{"deploymentMetadataValue":{"subdomain":"kardinal","hasAudioNarration":false,"actualSubdomain":"kardinal","customDomains":["developers.kardinal.ai"],"gitSource":{"type":"gitlab","owner":"public-docs","repo":"mintlify","deployBranch":"main","contentDirectory":"","isPrivate":true,"projectId":682,"hostUrl":"https://gitlab.kardinal.ai","mountPath":"","label":""},"chroma":{"collectionId":"44807bae-0c5b-41f5-baf0-105d62e503c8","liveDeploymentHistoryId":"6ae45060aff4ffe6b582b403","schemaVersion":"v3","latestBuiltDeploymentHistoryId":"6ae45060aff4ffe6b582b403"},"feedback":{"thumbs":true,"agentFeedback":true},"entitlements":{"AI_CHAT":{"status":"ENABLED"},"WEB_MCP":{"status":"ENABLED"},"NARRATION":{"status":"ENABLED"}},"buildId":"6ae45060aff4ffe6b582b403","clientVersion":"0.0.4043","searchFilterCounts":[{"language":"en","tag":"Guides","count":16},{"language":"en","tag":"API Reference","count":14},{"language":"en","tag":"SDKs","count":12},{"language":"en","tag":"API","count":9},{"language":"en","tag":"Modeling examples by industry","count":8},{"language":"en","tag":"By industry","count":8},{"language":"en","tag":"Plan","count":7},{"language":"en","tag":"Advanced modeling","count":5},{"language":"en","tag":"Concepts","count":4},{"language":"en","tag":"Getting started","count":4}]},"assistantConfig":{"enableAskAiButton":false,"enableStarterQuestions":false,"enableContextualStarterQuestions":false,"enableAskAiSearchBar":true},"basePath":"","hasChatPermissions":true,"hasWebMcpPermissions":true,"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":"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":"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":"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":"full-page-search","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":"turbopuffer-dual-write","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},{"name":"approve-review-flow","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false}],"googleFontsInlined":false},"customCss":[{"filePath":"style.css","content":"html.dark #topbar-cta-button .bg-primary-dark{background-color:rgb(var(--primary))}"}],"page":{"pagePath":"guides/manual-assignment-and-supervision","slug":"/guides/manual-assignment-and-supervision","pageMetadata":{"title":"Manual assignment and supervision","description":"Lock part of a tour while the engine re-plans the rest, supervise a tour live as it progresses, and reserve a stop for one resource without making it mandatory.","href":"/guides/manual-assignment-and-supervision"},"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: \"Lock part of a tour while the engine re-plans the rest, supervise a tour live as it progresses, and reserve a stop for one resource without making it mandatory.\"\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{Fragment:_Fragment,jsx:_jsx,jsxs:_jsxs}=arguments[0];const{useMDXComponents:_provideComponents}=arguments[0];function _createMdxContent(props){const _components={a:`a`,code:`code`,li:`li`,p:`p`,pre:`pre`,span:`span`,strong:`strong`,tbody:`tbody`,td:`td`,th:`th`,thead:`thead`,tr:`tr`,ul:`ul`,..._provideComponents(),...props.components},{CodeBlock,Heading,Table,Warning}=_components;if(!CodeBlock)_missingMdxReference(`CodeBlock`,true);if(!Heading)_missingMdxReference(`Heading`,true);if(!Table)_missingMdxReference(`Table`,true);if(!Warning)_missingMdxReference(`Warning`,true);return _jsxs(_Fragment,{children:[_jsxs(_components.p,{children:[_jsx(_components.a,{href:`/guides/real-time-reoptimization`,children:`Real-time re-optimization`}),` covers replacing the whole plan on disruption. This page covers the finer-grained controls: locking part of a resource’s tour in place while the engine re-plans the rest, and reserving a stop for exactly one resource without making it mandatory.`]}),`\n`,_jsxs(Heading,{level:`2`,id:`locking-a-sequence-mode-×-assignment-status`,children:[`Locking a sequence: `,_jsx(_components.code,{children:`mode`}),` × assignment `,_jsx(_components.code,{children:`status`})]}),`\n`,_jsxs(_components.p,{children:[_jsx(_components.code,{children:`state`}),` is set per resource and works on two levels: `,_jsx(_components.code,{children:`state.mode`}),` applies to the resource as a whole, while `,_jsx(_components.code,{children:`status`}),` applies to each individual entry in `,_jsx(_components.code,{children:`state.assignments`}),` (a stop, a break, or the tour’s `,_jsx(_components.code,{children:`begin`}),` or `,_jsx(_components.code,{children:`end`}),`).`]}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[_jsx(_components.code,{children:`status: \"assigned\"`}),` — the entry is assigned to this resource, but its position in the sequence isn’t imposed: the engine sequences the resource’s assigned entries according to the plan’s objectives.`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.code,{children:`status: \"fixed\"`}),` (the default) — the entry is taken as given: its position in the sequence, and its times, aren’t challenged.`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.code,{children:`mode: \"free\"`}),` (the default) — the engine can add more stops to this resource’s tour.`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.code,{children:`mode: \"fixed\"`}),` — the resource’s tour is limited to its assigned entries. The engine can’t add any more stops.`]}),`\n`]}),`\n`,_jsx(_components.p,{children:`The two combine as follows:`}),`\n`,_jsxs(Table,{children:[_jsx(_components.thead,{children:_jsxs(_components.tr,{children:[_jsx(_components.th,{}),_jsx(_components.th,{children:_jsx(_components.code,{children:`assignments[].status: \"assigned\"`})}),_jsx(_components.th,{children:_jsx(_components.code,{children:`assignments[].status: \"fixed\"`})})]})}),_jsxs(_components.tbody,{children:[_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.strong,{children:_jsx(_components.code,{children:`mode: \"fixed\"`})})}),_jsxs(_components.td,{children:[`The engine sequences the given stops according to the plan’s objectives, adding no further stops — useful to check whether assigning these stops to this resource is feasible at all (see `,_jsx(_components.a,{href:`/guides/handling-infeasibility#testing-a-stop-on-a-specific-resource-with-state-assignments`,children:`Testing a stop on a specific resource`}),`).`]}),_jsx(_components.td,{children:`The engine only checks the given sequence as-is, adding no further stops — a debug/evaluation mode: pose an existing tour to see whether it’s feasible and why a given stop isn’t covered.`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.strong,{children:_jsx(_components.code,{children:`mode: \"free\"`})})}),_jsx(_components.td,{children:`Not allowed.`}),_jsxs(_components.td,{children:[`The engine keeps the given sequence exactly as the start of the tour, and is free to add new stops after it — the real-time supervision case below. `,_jsx(_components.code,{children:`fixed`}),` assignments can only form the beginning of the tour: the engine never inserts a new stop before or between them.`]})]})]})]}),`\n`,_jsx(Heading,{level:`2`,id:`live-supervision-as-a-tour-progresses`,children:`Live supervision as a tour progresses`}),`\n`,_jsxs(_components.p,{children:[`Reflect a driver’s real progress with successive `,_jsx(_components.code,{children:`PUT /plans/{planId}`}),` calls: a `,_jsx(_components.code,{children:`begin`}),` assignment with the real `,_jsx(_components.code,{children:`departureTime`}),`, then `,_jsx(_components.code,{children:`stop`}),` assignments filled in with `,_jsx(_components.code,{children:`arrivalTime`}),`/`,_jsx(_components.code,{children:`beginTime`}),`/`,_jsx(_components.code,{children:`departureTime`}),` as they actually happen, a `,_jsx(_components.code,{children:`break`}),` inserted dynamically if needed. Keep `,_jsx(_components.code,{children:`mode: \"free\"`}),` so the engine can still plan what comes after, and give every pinned assignment `,_jsx(_components.code,{children:`status: \"fixed\"`}),`. Each of these calls carries the complete plan; the following excerpt only shows the `,_jsx(_components.code,{children:`resources`}),` entry being updated:`]}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`15`,language:`json`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`json`,children:_jsxs(_components.code,{language:`json`,numberOfLines:`15`,children:[_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`{`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"tz\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"Europe/Paris\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"resources\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: [`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` {`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"id\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"driver-1\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"state\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: {`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"mode\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"free\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"assignments\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: [`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` { `}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:`\"type\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"begin\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, `}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:`\"status\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"fixed\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, `}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:`\"departureTime\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"2026-08-03 07:02\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` },`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` { `}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:`\"type\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"stop\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, `}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:`\"status\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"fixed\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, `}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:`\"stopId\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"stop-1\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, `}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:`\"arrivalTime\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"2026-08-03 07:40\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, `}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:`\"departureTime\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"2026-08-03 07:55\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` }`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` ]`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` }`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` }`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` ]`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`}`})}),`\n`]})})}),`\n`,_jsxs(_components.p,{children:[`For a pinned time to be kept as given rather than re-planned by the optimization, every assignment before it in the sequence must also carry its times, and those times must be chronologically consistent: each entry’s times can’t be earlier than the previous entry’s. In practice, fill in assignments in the order the driver actually completes them, starting from `,_jsx(_components.code,{children:`begin`}),`, without leaving an earlier entry’s times blank.`]}),`\n`,_jsx(Heading,{level:`2`,id:`pinning-a-stop-to-exactly-one-resource-pattern-“isolate”`,children:`Pinning a stop to exactly one resource (pattern “Isolate”)`}),`\n`,_jsxs(_components.p,{children:[_jsx(_components.code,{children:`forbiddenAssignment`}),` bars the resources that carry its `,_jsx(_components.code,{children:`resourceTag`}),` from the stops that carry its `,_jsx(_components.code,{children:`stopTag`}),`. See `,_jsx(_components.a,{href:`/guides/skills-and-assignments#barring-one-resource-from-a-stop`,children:`Barring one resource from a stop`}),`. For a breakdown, see also `,_jsx(_components.a,{href:`/guides/real-time-reoptimization`,children:`Real-time re-optimization`}),`. There’s no single dedicated field for the opposite — reserving a stop for one resource — but three mechanisms get you there, from strictest to softest:`]}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:_jsx(_components.code,{children:`state.assignments`})}),` — pin the stop directly onto the resource’s tour, as described in the first section of this page. The only one of the three that the engine keeps exactly as given.`]}),`\n`,_jsxs(_components.li,{children:[_jsxs(_components.strong,{children:[_jsx(_components.code,{children:`skills`}),`/`,_jsx(_components.code,{children:`requiredSkills`})]}),` (pattern “Isolate”) — give the resource a `,_jsx(_components.code,{children:`skills`}),` entry derived from its own id (for example `,_jsx(_components.code,{children:`skills: [\"resource-12\"]`}),`) and require it on the targeted order (`,_jsx(_components.code,{children:`requiredSkills: [\"resource-12\"]`}),`). No other resource can then serve the stop.`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:_jsx(_components.code,{children:`preferredStopTags`})}),` — tag the stop, list that tag in the resource’s `,_jsx(_components.code,{children:`preferredStopTags`}),`, and include `,_jsx(_components.code,{children:`maximizePreferredStops`}),` in `,_jsx(_components.code,{children:`objectives`}),`. A soft preference: another resource can still take the stop when that serves a higher-priority objective better.`]}),`\n`]}),`\n`,_jsx(Warning,{children:_jsxs(_components.p,{children:[`Pinning a stop to a resource through `,_jsx(_components.code,{children:`requiredSkills`}),` doesn’t guarantee that the stop is planned: it only restricts which resource can serve it. The engine can still leave the stop unplanned if the assignment degrades a higher-priority objective. To keep the stop on that resource’s tour whatever the objectives, use `,_jsx(_components.code,{children:`state.assignments`}),` instead.`]})}),`\n`,_jsx(Heading,{level:`2`,id:`see-also`,children:`See also`}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[_jsx(_components.a,{href:`/guides/skills-and-assignments#prefer-instead-of-require`,children:`Skills and assignments`}),` — `,_jsx(_components.code,{children:`preferredStopTags`}),`/`,_jsx(_components.code,{children:`maximizePreferredStops`}),`, the soft-preference counterpart to the preceding “Isolate” pattern.`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.a,{href:`/guides/real-time-reoptimization`,children:`Real-time re-optimization`}),` — the full-plan `,_jsx(_components.code,{children:`PUT`}),` mechanics and `,_jsx(_components.code,{children:`forbiddenAssignment`}),`.`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.a,{href:`/reference/data-model#status-and-state`,children:`Data model`}),` — `,_jsx(_components.code,{children:`status`}),`/`,_jsx(_components.code,{children:`state`}),` field reference.`]}),`\n`]})]})}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":"Manual assignment and supervision","description":"Lock part of a tour while the engine re-plans the rest, supervise a tour live as it progresses, and reserve a stop for one resource without making it mandatory.","href":"/guides/manual-assignment-and-supervision"}}},"mdxSourceWithNoJs":null},"mdxExtracts":{"tableOfContents":[{"title":"Locking a sequence: mode × assignment status","slug":"locking-a-sequence-mode-×-assignment-status","depth":2,"children":[]},{"title":"Live supervision as a tour progresses","slug":"live-supervision-as-a-tour-progresses","depth":2,"children":[]},{"title":"Pinning a stop to exactly one resource (pattern “Isolate”)","slug":"pinning-a-stop-to-exactly-one-resource-pattern-“isolate”","depth":2,"children":[]},{"title":"See also","slug":"see-also","depth":2,"children":[]}],"codeExamples":{}},"jsLinks":["/_mintlify/custom/kardinal/d55e84efee54b775/kd-att-docs.js"],"subdomain":"kardinal","siteName":"Kardinal Route Optimization API","title":"Manual assignment and supervision - Kardinal Route Optimization API","navMaps":{"firstHrefInVersion":{},"firstHrefInLanguage":{"en":{"href":"/guides/manual-assignment-and-supervision","matchLevel":0}}},"lastModified":"2026-10-30T08:02:28.077Z","originalFileLocation":"guides/manual-assignment-and-supervision.mdx","locale":"en"},"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=\"Lock part of a tour while the engine re-plans the rest, supervise a tour live as it progresses, and reserve a stop for one resource without making it mandatory.\">\u003cmeta data-mint-head name=\"application-name\" content=\"Kardinal Route Optimization API\">\u003cmeta data-mint-head name=\"generator\" content=\"Mintlify\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"192x192\" href=\"/mintlify-assets/_mintlify/favicons/kardinal/4VnUJAe0ozIKpmRZ/_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/kardinal/4VnUJAe0ozIKpmRZ/_generated/favicon/apple-touch-icon.png\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"/mintlify-assets/_mintlify/favicons/kardinal/4VnUJAe0ozIKpmRZ/_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/kardinal/4VnUJAe0ozIKpmRZ/_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/kardinal/4VnUJAe0ozIKpmRZ/_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/kardinal/4VnUJAe0ozIKpmRZ/_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/kardinal/4VnUJAe0ozIKpmRZ/_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/kardinal/4VnUJAe0ozIKpmRZ/_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/kardinal/4VnUJAe0ozIKpmRZ/_generated/favicon-dark/favicon.ico\" media=\"(prefers-color-scheme: dark)\">\u003cmeta data-mint-head property=\"og:title\" content=\"Manual assignment and supervision - Kardinal Route Optimization API\">\u003cmeta data-mint-head property=\"og:description\" content=\"Lock part of a tour while the engine re-plans the rest, supervise a tour live as it progresses, and reserve a stop for one resource without making it mandatory.\">\u003cmeta data-mint-head property=\"og:site_name\" content=\"Kardinal Route Optimization API\">\u003cmeta data-mint-head property=\"og:url\" content=\"https://developers.kardinal.ai/guides/manual-assignment-and-supervision\">\u003cmeta data-mint-head property=\"og:type\" content=\"website\">\u003cmeta data-mint-head property=\"og:image\" content=\"https://kardinal.mintlify.app/_mintlify/api/og/v2?division=Operations\u0026amp;title=Manual+assignment+and+supervision\u0026amp;description=Lock+part+of+a+tour+while+the+engine+re-plans+the+rest%2C+supervise+a+tour+live+as+it+progresses%2C+and+reserve+a+stop+for+one+resource+without+making+it+mandatory.\u0026amp;theme=36328a05d721350f0182956e\u0026amp;signature=b96da74e5f151d2a70589669f641294adbf118f3b5b5d2c07319ac91cf250afc\">\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=\"Manual assignment and supervision - Kardinal Route Optimization API\">\u003cmeta data-mint-head name=\"twitter:description\" content=\"Lock part of a tour while the engine re-plans the rest, supervise a tour live as it progresses, and reserve a stop for one resource without making it mandatory.\">\u003cmeta data-mint-head name=\"twitter:image\" content=\"https://kardinal.mintlify.app/_mintlify/api/og/v2?division=Operations\u0026amp;title=Manual+assignment+and+supervision\u0026amp;description=Lock+part+of+a+tour+while+the+engine+re-plans+the+rest%2C+supervise+a+tour+live+as+it+progresses%2C+and+reserve+a+stop+for+one+resource+without+making+it+mandatory.\u0026amp;theme=36328a05d721350f0182956e\u0026amp;signature=b96da74e5f151d2a70589669f641294adbf118f3b5b5d2c07319ac91cf250afc\">\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/kardinal/4VnUJAe0ozIKpmRZ/_generated/favicon/browserconfig.xml\">\u003cmeta data-mint-head name=\"apple-mobile-web-app-title\" content=\"Kardinal Route Optimization API\">\u003cmeta data-mint-head name=\"msapplication-TileColor\" content=\"#4D6AFF\">\u003clink data-mint-head rel=\"canonical\" href=\"https://developers.kardinal.ai/guides/manual-assignment-and-supervision\">\u003clink data-mint-head rel=\"alternate\" type=\"application/xml\" href=\"/sitemap.xml\">\u003clink data-mint-head rel=\"alternate\" type=\"text/markdown\" href=\"/guides/manual-assignment-and-supervision.md\">\u003cscript data-mint-head type=\"application/ld+json\">{\"@context\":\"https://schema.org\",\"@graph\":[{\"@type\":\"Organization\",\"@id\":\"https://kardinal.ai/#organization\",\"name\":\"Kardinal\",\"url\":\"https://kardinal.ai/\",\"logo\":{\"@type\":\"ImageObject\",\"url\":\"https://mintcdn.com/kardinal/NzVu4E70FNnktm7V/images/Logo-blue-black.png?fit=max\u0026auto=format\u0026n=NzVu4E70FNnktm7V\u0026q=85\u0026s=877e4130943370aa62e85ed76662c9bc\"},\"sameAs\":[\"https://www.linkedin.com/company/kardinalai\",\"https://github.com/KardinalAI\"]},{\"@type\":\"WebSite\",\"@id\":\"https://developers.kardinal.ai#website\",\"name\":\"Kardinal Route Optimization API\",\"url\":\"https://developers.kardinal.ai\",\"publisher\":{\"@id\":\"https://kardinal.ai/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https://developers.kardinal.ai/guides/manual-assignment-and-supervision#webpage\",\"url\":\"https://developers.kardinal.ai/guides/manual-assignment-and-supervision\",\"name\":\"Manual assignment and supervision\",\"description\":\"Lock part of a tour while the engine re-plans the rest, supervise a tour live as it progresses, and reserve a stop for one resource without making it mandatory.\",\"dateModified\":\"2026-10-30T08:02:28.077Z\",\"isPartOf\":{\"@id\":\"https://developers.kardinal.ai#website\"},\"breadcrumb\":{\"@id\":\"https://developers.kardinal.ai/guides/manual-assignment-and-supervision#breadcrumb\"}},{\"@type\":\"BreadcrumbList\",\"@id\":\"https://developers.kardinal.ai/guides/manual-assignment-and-supervision#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Operations\",\"item\":\"https://developers.kardinal.ai/guides/real-time-reoptimization\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Manual assignment and supervision\",\"item\":\"https://developers.kardinal.ai/guides/manual-assignment-and-supervision\"}]},{\"@type\":[\"Article\",\"TechArticle\"],\"@id\":\"https://developers.kardinal.ai/guides/manual-assignment-and-supervision#article\",\"headline\":\"Manual assignment and supervision\",\"name\":\"Manual assignment and supervision\",\"description\":\"Lock part of a tour while the engine re-plans the rest, supervise a tour live as it progresses, and reserve a stop for one resource without making it mandatory.\",\"url\":\"https://developers.kardinal.ai/guides/manual-assignment-and-supervision\",\"mainEntityOfPage\":{\"@id\":\"https://developers.kardinal.ai/guides/manual-assignment-and-supervision#webpage\"},\"dateModified\":\"2026-10-30T08:02:28.077Z\",\"publisher\":{\"@id\":\"https://kardinal.ai/#organization\"},\"isPartOf\":{\"@id\":\"https://developers.kardinal.ai#website\"}}]}\u003c/script>\u003cscript data-mint-head type=\"application/ld+json\">{\"@context\":\"https://schema.org\",\"@type\":\"WebSite\",\"name\":\"Kardinal Route Optimization API\",\"creator\":{\"@type\":\"Organization\",\"name\":\"Mintlify\",\"url\":\"https://mintlify.com\"}}\u003c/script>","siteName":"Kardinal Route Optimization API","nav":{"global":null,"languages":[{"language":"en","default":true,"tabs":[{"tab":"Getting started","pages":[{"title":"Getting started","href":""}]},{"tab":"Concepts","pages":[{"title":"Concepts","href":"/concepts/how-the-optimization-engine-works"}]},{"tab":"Guides","groups":[{"group":"Vocabulary mapping","pages":[{"title":"Vocabulary mapping","mode":"wide","href":"/guides/vocabulary-mapping"}]},{"group":"Before modeling","pages":[{"title":"Requirements briefing checklist","href":"/guides/requirements-briefing"}]},{"group":"Modeling business rules","pages":[{"title":"Time windows","href":"/guides/time-windows"},{"title":"Breaks","href":"/guides/breaks"},{"title":"Skills and assignments","href":"/guides/skills-and-assignments"},{"title":"Capacities","href":"/guides/capacities"}]},{"group":"Integration","pages":[{"title":"Authentication and API keys","href":"/guides/authentication"},{"title":"Moving from sandbox to production","href":"/guides/sandbox-to-production"},{"title":"Handling large volumes","href":"/guides/handling-large-volumes"}]},{"group":"Advanced modeling","pages":[{"title":"Modeling advanced constraints","href":"/guides/advanced-constraints"},{"title":"Cost modeling","href":"/guides/cost-modeling"},{"title":"Multi-trip tours (depot returns)","href":"/guides/multi-trip-tours"},{"title":"Swap-body and container-exchange orders","href":"/guides/swap-body-exchange"},{"title":"Handling infeasibility","href":"/guides/handling-infeasibility"}]},{"group":"Operations","pages":[{"title":"Real-time re-optimization","description":"Update a running plan after a delay, cancellation, or urgent order, so the engine repairs its solution instead of starting over, and choose how often to update.","href":"/guides/real-time-reoptimization"},{"title":"Manual assignment and supervision","href":"/guides/manual-assignment-and-supervision"}]}]},{"tab":"SDKs","pages":[{"title":"SDKs","href":"/sdks/overview"}]},{"tab":"API Reference","pages":[{"title":"API Reference","href":"/api-reference/plan/retrieve-the-list-of-plans-in-a-light-representation"}]},{"tab":"Modeling examples by industry","pages":[{"title":"Modeling examples by industry","href":"/case-studies/overview"}]}]}]},"basePath":"","title":"Manual assignment and supervision - Kardinal Route Optimization API","buildId":"dpl_G9nrg4qeJSZtah1Ziwbc2n6WkLch","deploymentId":"dpl_G9nrg4qeJSZtah1Ziwbc2n6WkLch","dynamics":["10e4515597"],"chunks":["BannerMarkdown-CXEEkV6J.js","dist-lvhuD9Du.js","lib-DuNMoZ05.js","lib-B8HbPgcC.js","clsx-D1Z-ELXV.js","html-void-elements-mCSPHezU.js","katex-YMM-FMeD.js","marked.esm-CZWythHk.js"]}