{"info":{"_postman_id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","name":"ShuttleControl Open API","description":"<html><head></head><body><p>The ShuttleControl Open API is organized around REST. Our Open API has predictable resource-oriented URLs, accepts JSON request bodies, returns JSON-encoded responses, and uses standard HTTP response codes, authentication, and verbs.  </p>\n<p>Replace {{hostname}} with <a href=\"https://api.shuttlecontrol.com\">https://api.shuttlecontrol.com</a> and {{apiKey}} with the API Key found under your in-app Company tab when using the Open API.</p>\n</body></html>","schema":"https://schema.getpostman.com/json/collection/v2.0.0/collection.json","toc":[],"owner":"2834192","collectionId":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","publishedId":"2s93JrvQC4","public":true,"customColor":{"top-bar":"0d6efd","right-sidebar":"303030","highlight":"0D6EFD"},"publishDate":"2023-03-13T19:29:23.000Z"},"item":[{"name":"Accounts","item":[{"name":"Get Account","id":"c839b147-33bf-4a0c-acf8-0907284822bf","request":{"method":"GET","header":[],"url":"{{hostname}}/v2/accounts/me","description":"<p>Returns the account of the authenticated caller.</p>\n<p>⚠️ The response includes the account’s <code>apiKey</code> — treat it like a password.</p>\n<h4 id=\"response\">Response</h4>\n<p>Returns the account object: <code>id</code>, <code>apiKey</code>, <code>name</code>, <code>plan</code> (<code>BASIC</code> | <code>SHUTTLECONTROL</code> | <code>FLEET</code>), <code>industry</code>, <code>phoneNumber</code>, <code>timezoneId</code> (IANA), <code>uom</code> (<code>METRIC</code> | <code>IMPERIAL</code>), <code>country</code> (ISO 3166-1 alpha-2), <code>monthlyReportEnabled</code>, <code>stripeConnectAccountId</code>, <code>stripeConnectAccountOnboarded</code>, <code>createdAt</code>, <code>updatedAt</code>.</p>\n","auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{apiKey}}"}]},"isInherited":true,"source":{"_postman_id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","name":"ShuttleControl Open API","type":"collection"}},"urlObject":{"path":["v2","accounts","me"],"host":["{{hostname}}"],"query":[],"variable":[]}},"response":[{"id":"43c31f3d-0018-40ea-98ca-15be968f5748","name":"Get Account response","originalRequest":{"method":"GET","header":[],"url":"{{hostname}}/v2/accounts/me"},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"content-length","value":"277"},{"key":"content-type","value":"application/json; charset=utf-8"}],"cookie":[],"responseTime":null,"body":"{\n    \"id\": \"a9d32a39-86e0-4c8f-a69e-6aa2a56f2ac8\",\n    \"apiKey\": \"726768e2-4f75-4a49-95ab-9d63f5223747\",\n    \"name\": \"demo\",\n    \"plan\": \"FLEET\",\n    \"industry\": \"AUTOMOTIVE\",\n    \"phoneNumber\": \"\",\n    \"uom\": \"METRIC\",\n    \"country\": \"CA\",\n    \"createdAt\": \"2023-03-13T18:05:39.247Z\",\n    \"updatedAt\": null,\n    \"monthlyReportEnabled\": true\n}"}],"_postman_id":"c839b147-33bf-4a0c-acf8-0907284822bf"},{"name":"Update Account","id":"f169ce24-2a10-422e-a246-0c2eff5411f7","request":{"method":"PUT","header":[],"body":{"mode":"raw","raw":"{\n  \"name\": \"Acme Shuttles\",\n  \"uom\": \"METRIC\",\n  \"country\": \"CA\",\n  \"industry\": \"AUTOMOTIVE\",\n  \"phoneNumber\": \"+1 514 555 0100\",\n  \"monthlyReportEnabled\": true,\n  \"timezoneId\": \"America/Toronto\"\n}","options":{"raw":{"language":"json"}}},"url":"{{hostname}}/v2/accounts/me","description":"<p>Updates account-level settings. All fields are optional — only the fields present in the body are changed.</p>\n<p><strong>Required role:</strong> <code>OWNER</code> or higher. An account API key always satisfies this (it authenticates as the account owner).</p>\n<h4 id=\"body-fields\">Body fields</h4>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Field</th>\n<th>Type</th>\n<th>Required</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>name</code></td>\n<td>string</td>\n<td>No</td>\n<td>Account (business) name, max 100 characters. Also synced to your Stripe customer profile.</td>\n</tr>\n<tr>\n<td><code>uom</code></td>\n<td>string</td>\n<td>No</td>\n<td>Unit of measurement: <code>METRIC</code> or <code>IMPERIAL</code>.</td>\n</tr>\n<tr>\n<td><code>country</code></td>\n<td>string</td>\n<td>No</td>\n<td>Two-letter ISO 3166-1 country code (e.g. <code>CA</code>, <code>US</code>). European countries are not supported.</td>\n</tr>\n<tr>\n<td><code>industry</code></td>\n<td>string</td>\n<td>No</td>\n<td>One of: AUTOMOTIVE</td>\n</tr>\n<tr>\n<td><code>phoneNumber</code></td>\n<td>string</td>\n<td>No</td>\n<td>Contact phone number for the account.</td>\n</tr>\n<tr>\n<td><code>monthlyReportEnabled</code></td>\n<td>boolean</td>\n<td>No</td>\n<td>Whether the monthly summary report email is sent.</td>\n</tr>\n<tr>\n<td><code>timezoneId</code></td>\n<td>string</td>\n<td>No</td>\n<td>IANA timezone identifier, e.g. <code>America/Toronto</code>.</td>\n</tr>\n</tbody>\n</table>\n</div><h4 id=\"response\">Response</h4>\n<p>Returns the updated account object.</p>\n","auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{apiKey}}"}]},"isInherited":true,"source":{"_postman_id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","name":"ShuttleControl Open API","type":"collection"}},"urlObject":{"path":["v2","accounts","me"],"host":["{{hostname}}"],"query":[],"variable":[]}},"response":[{"id":"c34933b1-b0c0-4dcf-8c77-e615386513a9","name":"Update Account response","originalRequest":{"method":"PUT","header":[],"body":{"mode":"raw","raw":"{\n    \"name\": \"ACME Inc.\",\n    \"uom\": \"METRIC\",\n    \"country\": \"CA\",\n    \"industry\": \"AUTOMOTIVE\",\n    \"phoneNumber\": \"555 123 1234\",\n    \"monthlyReportEnabled\": false\n}","options":{"raw":{"language":"json"}}},"url":"{{hostname}}/v2/accounts/me"},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"content-length","value":"215"},{"key":"content-type","value":"application/json; charset=utf-8"}],"cookie":[],"responseTime":null,"body":"{\n    \"id\": \"a9d32a39-86e0-4c8f-a69e-6aa2a56f2ac8\",\n    \"name\": \"ACME Inc.\",\n    \"uom\": \"METRIC\",\n    \"country\": \"CA\",\n    \"industry\": \"AUTOMOTIVE\",\n    \"phoneNumber\": \"555 123 1234\",\n    \"monthlyReportEnabled\": false,\n    \"updatedAt\": \"2023-03-16T15:29:27.213Z\"\n}"}],"_postman_id":"f169ce24-2a10-422e-a246-0c2eff5411f7"},{"name":"Get Billing Portal","id":"6602484e-5799-42ad-a9d1-f23f9133d296","request":{"method":"GET","header":[],"url":"{{hostname}}/v2/accounts/billingPortal","description":"<p>Creates a Stripe billing-portal session for the account and returns its URL. Direct the user’s browser to this URL to let them manage payment methods, invoices, and their subscription.</p>\n<p><strong>Required role:</strong> <code>BILLING</code> or higher. An account API key always satisfies this (it authenticates as the account owner).</p>\n<h4 id=\"response\">Response</h4>\n<p>Returns <code>{ url }</code> — a short-lived Stripe billing portal link. Responds <code>400</code> if the account has no Stripe customer.</p>\n","auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{apiKey}}"}]},"isInherited":true,"source":{"_postman_id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","name":"ShuttleControl Open API","type":"collection"}},"urlObject":{"path":["v2","accounts","billingPortal"],"host":["{{hostname}}"],"query":[],"variable":[]}},"response":[],"_postman_id":"6602484e-5799-42ad-a9d1-f23f9133d296"}],"id":"6f74ba4e-8ca0-44fa-9ea5-10d720bd0807","description":"<p>Manage the account that owns your stores, users, and subscription.</p>\n","_postman_id":"6f74ba4e-8ca0-44fa-9ea5-10d720bd0807","auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{apiKey}}"}]},"isInherited":true,"source":{"_postman_id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","name":"ShuttleControl Open API","type":"collection"}}},{"name":"Users","item":[{"name":"Create User","id":"df0ba39d-fc17-48b0-8033-c384461024b8","request":{"method":"POST","header":[],"body":{"mode":"raw","raw":"{\n  \"email\": \"driver@example.com\",\n  \"role\": \"DRIVER\",\n  \"language\": \"en\",\n  \"firstName\": \"Sam\",\n  \"lastName\": \"Lee\",\n  \"phoneNumber\": \"+1 514 555 0111\",\n  \"storeIds\": [\n    \"9f2d1c34-0000-0000-0000-000000000000\"\n  ]\n}","options":{"raw":{"language":"json"}}},"url":"{{hostname}}/v2/users","description":"<p>Creates a new user and emails them an invitation to set their password. The email address must not already be in use (responds <code>409</code> if it is — see <strong>Retake User</strong> to re-enable a previously deactivated user).</p>\n<p><strong>Required role:</strong> <code>ADMIN</code> or higher. An account API key always satisfies this (it authenticates as the account owner).</p>\n<h4 id=\"body-fields\">Body fields</h4>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Field</th>\n<th>Type</th>\n<th>Required</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>email</code></td>\n<td>string</td>\n<td>Yes</td>\n<td>Email address, max 83 characters. Must be unique across ShuttleControl.</td>\n</tr>\n<tr>\n<td><code>role</code></td>\n<td>string</td>\n<td>Yes</td>\n<td>One of <code>ADMIN</code>, <code>DISPATCHER</code>, <code>DRIVER</code>, <code>BILLING</code>.</td>\n</tr>\n<tr>\n<td><code>language</code></td>\n<td>string</td>\n<td>Yes</td>\n<td>Invitation/notification language: <code>en</code> or <code>fr</code>.</td>\n</tr>\n<tr>\n<td><code>firstName</code></td>\n<td>string</td>\n<td>Yes</td>\n<td>First name, max 100 characters.</td>\n</tr>\n<tr>\n<td><code>lastName</code></td>\n<td>string</td>\n<td>Yes</td>\n<td>Last name, max 100 characters.</td>\n</tr>\n<tr>\n<td><code>phoneNumber</code></td>\n<td>string</td>\n<td>Yes</td>\n<td>Phone number, max 100 characters. May be an empty string.</td>\n</tr>\n<tr>\n<td><code>storeIds</code></td>\n<td>string[] (UUID)</td>\n<td>Yes</td>\n<td>Stores to assign the user to. At least one is required.</td>\n</tr>\n</tbody>\n</table>\n</div><h4 id=\"response\">Response</h4>\n<p>Responds <code>201</code> with the created user and a <code>Location</code> header. <code>password</code> and <code>loginToken</code> are never returned.</p>\n","auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{apiKey}}"}]},"isInherited":true,"source":{"_postman_id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","name":"ShuttleControl Open API","type":"collection"}},"urlObject":{"path":["v2","users"],"host":["{{hostname}}"],"query":[],"variable":[]}},"response":[{"id":"de4adad4-5f69-4eca-96d2-58d937acccc1","name":"Create User response","originalRequest":{"method":"POST","header":[],"body":{"mode":"raw","raw":"{\n    \"email\": \"noah.sky@shuttlecontrol.com\",\n    \"role\": \"DISPATCHER\",\n    \"language\": \"en\",\n    \"firstName\": \"Noah\",\n    \"lastName\": \"Sky\",\n    \"phoneNumber\": \"555 123 1234\",\n    \"storeIds\": [\n        \"\"\n    ]\n}","options":{"raw":{"language":"json"}}},"url":"{{hostname}}/v2/users"},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"content-length","value":"494"},{"key":"content-type","value":"application/json; charset=utf-8"}],"cookie":[],"responseTime":null,"body":"{\n    \"fcmToken\": null,\n    \"updatedAt\": null,\n    \"emailVerified\": false,\n    \"phoneNumber\": \"555 123 1234\",\n    \"vehicle\": null,\n    \"enabled\": true,\n    \"language\": \"en\",\n    \"lastLoginAt\": null,\n    \"account\": \"a9d32a39-86e0-4c8f-a69e-6aa2a56f2ac8\",\n    \"updatedBy\": null,\n    \"email\": \"noah.sky@shuttlecontrol.com\",\n    \"role\": \"DISPATCHER\",\n    \"stores\": [\n        \"f1a04c8a-dc36-4203-9a9e-698e06cf7cef\"\n    ],\n    \"lastName\": \"Sky\",\n    \"firstName\": \"Noah\",\n    \"id\": \"a61a5ff9-7f64-43b3-aabb-012dd5660f4c\",\n    \"createdAt\": \"2023-03-16T19:12:53.226Z\",\n    \"createdBy\": \"7b5f6ea6-7b3a-4437-838a-9a31994aacb3\"\n}"}],"_postman_id":"df0ba39d-fc17-48b0-8033-c384461024b8"},{"name":"Retake User","id":"3f17f2ae-82a2-4991-bfe2-5d8df3c38611","request":{"method":"POST","header":[],"body":{"mode":"raw","raw":"{\n  \"email\": \"driver@example.com\",\n  \"role\": \"DRIVER\",\n  \"language\": \"en\",\n  \"firstName\": \"Sam\",\n  \"lastName\": \"Lee\",\n  \"phoneNumber\": \"+1 514 555 0111\",\n  \"storeIds\": [\n    \"9f2d1c34-0000-0000-0000-000000000000\"\n  ]\n}","options":{"raw":{"language":"json"}}},"url":"{{hostname}}/v2/users/retake","description":"<p>Re-enables a previously <strong>deactivated</strong> user on your account, overwriting their role, name, language, phone number, and store assignments, and re-sends the invitation email. Responds <code>404</code> if no user exists with that email, and <code>400</code> if the user is currently active.</p>\n<p><strong>Required role:</strong> <code>ADMIN</code> or higher. An account API key always satisfies this (it authenticates as the account owner).</p>\n<h4 id=\"body-fields\">Body fields</h4>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Field</th>\n<th>Type</th>\n<th>Required</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>email</code></td>\n<td>string</td>\n<td>Yes</td>\n<td>Email of the deactivated user to retake (max 83 characters).</td>\n</tr>\n<tr>\n<td><code>role</code></td>\n<td>string</td>\n<td>Yes</td>\n<td>One of <code>ADMIN</code>, <code>DISPATCHER</code>, <code>DRIVER</code>, <code>BILLING</code>.</td>\n</tr>\n<tr>\n<td><code>language</code></td>\n<td>string</td>\n<td>Yes</td>\n<td><code>en</code> or <code>fr</code>.</td>\n</tr>\n<tr>\n<td><code>firstName</code></td>\n<td>string</td>\n<td>Yes</td>\n<td>First name, max 100 characters.</td>\n</tr>\n<tr>\n<td><code>lastName</code></td>\n<td>string</td>\n<td>Yes</td>\n<td>Last name, max 100 characters.</td>\n</tr>\n<tr>\n<td><code>phoneNumber</code></td>\n<td>string</td>\n<td>Yes</td>\n<td>Phone number, max 100 characters.</td>\n</tr>\n<tr>\n<td><code>storeIds</code></td>\n<td>string[] (UUID)</td>\n<td>Yes</td>\n<td>Stores to assign. Replaces any previous assignment. At least one is required.</td>\n</tr>\n</tbody>\n</table>\n</div><h4 id=\"response\">Response</h4>\n<p>Responds <code>201</code> with the re-enabled user.</p>\n","auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{apiKey}}"}]},"isInherited":true,"source":{"_postman_id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","name":"ShuttleControl Open API","type":"collection"}},"urlObject":{"path":["v2","users","retake"],"host":["{{hostname}}"],"query":[],"variable":[]}},"response":[],"_postman_id":"3f17f2ae-82a2-4991-bfe2-5d8df3c38611"},{"name":"List Users","id":"04f319fb-d22c-4425-b7f0-10d63da87111","request":{"method":"GET","header":[],"url":"{{hostname}}/v2/users/list?page=0&size=10","description":"<p>Returns a paginated list of active users visible to the caller, optionally filtered by store, role, or a free-text search.</p>\n<p><strong>Required role:</strong> <code>ADMIN</code> or higher. An account API key always satisfies this (it authenticates as the account owner).</p>\n<h4 id=\"response\">Response</h4>\n<p>Returns <code>{ items, count, total, userLimit }</code> — <code>count</code> is the number of matches, <code>total</code> the account-wide user count, and <code>userLimit</code> your plan’s cap.</p>\n","auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{apiKey}}"}]},"isInherited":true,"source":{"_postman_id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","name":"ShuttleControl Open API","type":"collection"}},"urlObject":{"path":["v2","users","list"],"host":["{{hostname}}"],"query":[{"description":{"content":"<p>Zero-based page index. Default <code>0</code>.</p>\n","type":"text/plain"},"key":"page","value":"0"},{"description":{"content":"<p>Page size, 1–100. Default <code>10</code>.</p>\n","type":"text/plain"},"key":"size","value":"10"},{"disabled":true,"description":{"content":"<p>Repeatable UUID filter: only users assigned to these stores.</p>\n","type":"text/plain"},"key":"storeIds","value":""},{"disabled":true,"description":{"content":"<p>Free-text search (max 100 characters) over user names/emails.</p>\n","type":"text/plain"},"key":"search","value":""},{"disabled":true,"description":{"content":"<p>Filter by role: <code>ADMIN</code> | <code>DISPATCHER</code> | <code>DRIVER</code> | <code>OWNER</code> | <code>BILLING</code>.</p>\n","type":"text/plain"},"key":"role","value":""}],"variable":[]}},"response":[{"id":"45f6c71c-7ab7-41bf-bdb8-b65c56d94fb0","name":"List Users response","originalRequest":{"method":"GET","header":[],"url":{"raw":"{{hostname}}/v2/users?page=0&size=3","host":["{{hostname}}"],"path":["v2","users"],"query":[{"key":"page","value":"0"},{"key":"size","value":"3"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"content-type","value":"application/json; charset=utf-8"}],"cookie":[],"responseTime":null,"body":"{\n    \"items\": [\n        {\n            \"id\": \"7b5f6ea6-7b3a-4437-838a-9a31994aacb3\",\n            \"role\": \"OWNER\",\n            \"enabled\": true,\n            \"firstName\": \"Edward\",\n            \"lastName\": \"Maxedon\",\n            \"phoneNumber\": \"514 699 7622\",\n            \"email\": \"edward+owner@shuttlecontrol.com\",\n            \"emailVerified\": false,\n            \"language\": \"en\",\n            \"loginToken\": \"cd1cbb48-3f1f-4ef7-83d0-45792be2b167\",\n            \"createdAt\": \"2023-03-13T18:05:39.254Z\",\n            \"account\": {\n                \"id\": \"a9d32a39-86e0-4c8f-a69e-6aa2a56f2ac8\",\n                \"enabled\": true,\n                \"name\": \"ACME Inc.\",\n                \"plan\": \"FLEET\",\n                \"uom\": \"METRIC\",\n                \"createdAt\": \"2023-03-13T18:05:39.247Z\",\n                \"country\": \"CA\",\n                \"trialEndAt\": \"2023-03-27T18:05:39.247Z\",\n                \"integrations\": []\n            },\n            \"stores\": [\n                {\n                    \"id\": \"f1a04c8a-dc36-4203-9a9e-698e06cf7cef\",\n                    \"name\": \"Alpha Store\",\n                    \"color\": \"blue\",\n                    \"radiusBound\": null,\n                    \"place\": {\n                        \"id\": \"c60c1e2c-e3af-4e6b-8917-45023225488f\",\n                        \"latitude\": 45.4919122,\n                        \"longitude\": -73.6186555,\n                        \"address\": \"Saint Joseph's Oratory of Mount Royal\"\n                    }\n                },\n                {\n                    \"id\": \"14142b60-0eec-49e5-b7ee-afd0c0b1e8d7\",\n                    \"name\": \"Bravo Store\",\n                    \"color\": \"blue\",\n                    \"radiusBound\": null,\n                    \"place\": {\n                        \"id\": \"4c796a4e-8e8d-4044-9463-ea9d2803f3c9\",\n                        \"latitude\": 45.4651629,\n                        \"longitude\": -73.5756481,\n                        \"address\": \"3901 Bannantyne Ave, Verdun, QC H4G 1B9\"\n                    }\n                }\n            ],\n            \"lastLoginAt\": \"2023-03-15T19:13:10.251Z\",\n            \"createdBy\": null,\n            \"updatedAt\": null,\n            \"updatedBy\": null,\n            \"vehicle\": null\n        },\n        {\n            \"id\": \"c6b688ba-03e3-435c-a4dc-2b967f8ec0cf\",\n            \"role\": \"DRIVER\",\n            \"enabled\": true,\n            \"firstName\": \"Edward\",\n            \"lastName\": \"Maxedon\",\n            \"phoneNumber\": \"514 699 7622\",\n            \"email\": \"edward+driver@shuttlecontrol.com\",\n            \"emailVerified\": false,\n            \"language\": \"en\",\n            \"loginToken\": \"7f744b00-ffad-4efa-a6dd-e75470c3c32f\",\n            \"createdAt\": \"2023-03-13T18:05:39.648Z\",\n            \"account\": {\n                \"id\": \"a9d32a39-86e0-4c8f-a69e-6aa2a56f2ac8\",\n                \"enabled\": true,\n                \"name\": \"ACME Inc.\",\n                \"plan\": \"FLEET\",\n                \"uom\": \"METRIC\",\n                \"createdAt\": \"2023-03-13T18:05:39.247Z\",\n                \"country\": \"CA\",\n                \"trialEndAt\": \"2023-03-27T18:05:39.247Z\",\n                \"integrations\": []\n            },\n            \"stores\": [\n                {\n                    \"id\": \"f1a04c8a-dc36-4203-9a9e-698e06cf7cef\",\n                    \"name\": \"Alpha Store\",\n                    \"color\": \"blue\",\n                    \"radiusBound\": null,\n                    \"place\": {\n                        \"id\": \"c60c1e2c-e3af-4e6b-8917-45023225488f\",\n                        \"latitude\": 45.4919122,\n                        \"longitude\": -73.6186555,\n                        \"address\": \"Saint Joseph's Oratory of Mount Royal\"\n                    }\n                },\n                {\n                    \"id\": \"14142b60-0eec-49e5-b7ee-afd0c0b1e8d7\",\n                    \"name\": \"Bravo Store\",\n                    \"color\": \"blue\",\n                    \"radiusBound\": null,\n                    \"place\": {\n                        \"id\": \"4c796a4e-8e8d-4044-9463-ea9d2803f3c9\",\n                        \"latitude\": 45.4651629,\n                        \"longitude\": -73.5756481,\n                        \"address\": \"3901 Bannantyne Ave, Verdun, QC H4G 1B9\"\n                    }\n                }\n            ],\n            \"lastLoginAt\": null,\n            \"createdBy\": null,\n            \"updatedAt\": null,\n            \"updatedBy\": null,\n            \"vehicle\": null\n        },\n        {\n            \"id\": \"515e4f0e-fc7a-4484-a1f9-cc7ed568eb76\",\n            \"role\": \"DISPATCHER\",\n            \"enabled\": true,\n            \"firstName\": \"Jamie\",\n            \"lastName\": \"Sky\",\n            \"phoneNumber\": \"555 543 4321\",\n            \"email\": \"jamie.sky@shuttlecontrol.com\",\n            \"emailVerified\": false,\n            \"language\": \"fr\",\n            \"loginToken\": \"229bf334-e845-4ca8-8a0e-c5356bacee41\",\n            \"createdAt\": \"2023-03-16T18:29:14.344Z\",\n            \"account\": {\n                \"id\": \"a9d32a39-86e0-4c8f-a69e-6aa2a56f2ac8\",\n                \"enabled\": true,\n                \"name\": \"ACME Inc.\",\n                \"plan\": \"FLEET\",\n                \"uom\": \"METRIC\",\n                \"createdAt\": \"2023-03-13T18:05:39.247Z\",\n                \"country\": \"CA\",\n                \"trialEndAt\": \"2023-03-27T18:05:39.247Z\",\n                \"integrations\": []\n            },\n            \"stores\": [\n                {\n                    \"id\": \"f1a04c8a-dc36-4203-9a9e-698e06cf7cef\",\n                    \"name\": \"Alpha Store\",\n                    \"color\": \"blue\",\n                    \"radiusBound\": null,\n                    \"place\": {\n                        \"id\": \"c60c1e2c-e3af-4e6b-8917-45023225488f\",\n                        \"latitude\": 45.4919122,\n                        \"longitude\": -73.6186555,\n                        \"address\": \"Saint Joseph's Oratory of Mount Royal\"\n                    }\n                }\n            ],\n            \"lastLoginAt\": null,\n            \"createdBy\": {\n                \"id\": \"7b5f6ea6-7b3a-4437-838a-9a31994aacb3\",\n                \"firstName\": \"Edward\",\n                \"lastName\": \"Maxedon\"\n            },\n            \"updatedAt\": \"2023-03-16T18:53:43.625Z\",\n            \"updatedBy\": {\n                \"id\": \"7b5f6ea6-7b3a-4437-838a-9a31994aacb3\",\n                \"firstName\": \"Edward\",\n                \"lastName\": \"Maxedon\"\n            },\n            \"vehicle\": null\n        }\n    ],\n    \"count\": 9\n}"}],"_postman_id":"04f319fb-d22c-4425-b7f0-10d63da87111"},{"name":"List Deactivated Users","id":"fc709163-cda7-4f33-9fae-7f3a40e98824","request":{"method":"GET","header":[],"url":"{{hostname}}/v2/users/deactivated?page=0&size=10","description":"<p>Returns a paginated list of deactivated users, with the same filters as <strong>List Users</strong>.</p>\n<p><strong>Required role:</strong> <code>ADMIN</code> or higher. An account API key always satisfies this (it authenticates as the account owner).</p>\n<h4 id=\"response\">Response</h4>\n<p>Returns <code>{ items, count }</code>.</p>\n","auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{apiKey}}"}]},"isInherited":true,"source":{"_postman_id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","name":"ShuttleControl Open API","type":"collection"}},"urlObject":{"path":["v2","users","deactivated"],"host":["{{hostname}}"],"query":[{"description":{"content":"<p>Zero-based page index. Default <code>0</code>.</p>\n","type":"text/plain"},"key":"page","value":"0"},{"description":{"content":"<p>Page size, 1–100. Default <code>10</code>.</p>\n","type":"text/plain"},"key":"size","value":"10"},{"disabled":true,"description":{"content":"<p>Repeatable UUID filter: only users assigned to these stores.</p>\n","type":"text/plain"},"key":"storeIds","value":""},{"disabled":true,"description":{"content":"<p>Free-text search (max 100 characters).</p>\n","type":"text/plain"},"key":"search","value":""},{"disabled":true,"description":{"content":"<p>Filter by role.</p>\n","type":"text/plain"},"key":"role","value":""}],"variable":[]}},"response":[],"_postman_id":"fc709163-cda7-4f33-9fae-7f3a40e98824"},{"name":"List All Users","id":"7797f646-10a4-44dc-9225-51eb66d57b6c","request":{"method":"GET","header":[],"url":"{{hostname}}/v2/users?roles=DRIVER","description":"<p>Returns a lightweight, non-paginated list of active users matching the given roles — useful for populating pickers (e.g. all drivers of a store).</p>\n<h4 id=\"response\">Response</h4>\n<p>Returns an array of <code>{ id, firstName, lastName, role }</code>.</p>\n","auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{apiKey}}"}]},"isInherited":true,"source":{"_postman_id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","name":"ShuttleControl Open API","type":"collection"}},"urlObject":{"path":["v2","users"],"host":["{{hostname}}"],"query":[{"description":{"content":"<p>Required, repeatable. One or more of <code>ADMIN</code>, <code>DISPATCHER</code>, <code>DRIVER</code>, <code>OWNER</code>, <code>BILLING</code>.</p>\n","type":"text/plain"},"key":"roles","value":"DRIVER"},{"disabled":true,"description":{"content":"<p>Repeatable UUID filter. Default: every store visible to the caller.</p>\n","type":"text/plain"},"key":"storeIds","value":""},{"disabled":true,"description":{"content":"<p><code>union</code> (member of any listed store, default) or <code>intersection</code> (member of every listed store).</p>\n","type":"text/plain"},"key":"storeIdsMode","value":"union"}],"variable":[]}},"response":[],"_postman_id":"7797f646-10a4-44dc-9225-51eb66d57b6c"},{"name":"Get User","id":"28f0982d-57ff-4945-81ee-9c7670b41da0","request":{"method":"GET","header":[],"url":"{{hostname}}/v2/users/:id","description":"<p>Returns a single user. The user must belong to a store visible to the caller.</p>\n<h4 id=\"response\">Response</h4>\n<p>Returns the user object (id, role, email, names, language, phoneNumber, stores, timestamps, …).</p>\n","auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{apiKey}}"}]},"isInherited":true,"source":{"_postman_id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","name":"ShuttleControl Open API","type":"collection"}},"urlObject":{"path":["v2","users",":id"],"host":["{{hostname}}"],"query":[],"variable":[{"id":"e44ad3b0-a7f3-4b52-bbf4-f5202394e202","description":{"content":"<p>UUID of the user to fetch.</p>\n","type":"text/plain"},"type":"any","value":"","key":"id"}]}},"response":[{"id":"04f3542b-f119-4cd6-953a-7a3642312eb2","name":"Get User response","originalRequest":{"method":"GET","header":[],"url":"{{hostname}}/v2/users/"},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"content-type","value":"application/json; charset=utf-8"}],"cookie":[],"responseTime":null,"body":"{\n    \"id\": \"515e4f0e-fc7a-4484-a1f9-cc7ed568eb76\",\n    \"role\": \"DISPATCHER\",\n    \"enabled\": true,\n    \"firstName\": \"Jamie\",\n    \"lastName\": \"Sky\",\n    \"phoneNumber\": \"555 543 4321\",\n    \"email\": \"jamie.sky@shuttlecontrol.com\",\n    \"emailVerified\": false,\n    \"language\": \"fr\",\n    \"loginToken\": \"229bf334-e845-4ca8-8a0e-c5356bacee41\",\n    \"createdAt\": \"2023-03-16T18:29:14.344Z\",\n    \"account\": {\n        \"id\": \"a9d32a39-86e0-4c8f-a69e-6aa2a56f2ac8\",\n        \"enabled\": true,\n        \"name\": \"ACME Inc.\",\n        \"plan\": \"FLEET\",\n        \"uom\": \"METRIC\",\n        \"createdAt\": \"2023-03-13T18:05:39.247Z\",\n        \"country\": \"CA\",\n        \"trialEndAt\": \"2023-03-27T18:05:39.247Z\",\n        \"integrations\": []\n    },\n    \"stores\": [\n        {\n            \"id\": \"f1a04c8a-dc36-4203-9a9e-698e06cf7cef\",\n            \"name\": \"Alpha Store\",\n            \"color\": \"blue\",\n            \"radiusBound\": null,\n            \"place\": {\n                \"id\": \"c60c1e2c-e3af-4e6b-8917-45023225488f\",\n                \"latitude\": 45.4919122,\n                \"longitude\": -73.6186555,\n                \"address\": \"Saint Joseph's Oratory of Mount Royal\"\n            }\n        }\n    ],\n    \"lastLoginAt\": null,\n    \"createdBy\": {\n        \"id\": \"7b5f6ea6-7b3a-4437-838a-9a31994aacb3\",\n        \"firstName\": \"Edward\",\n        \"lastName\": \"Maxedon\"\n    },\n    \"updatedAt\": \"2023-03-16T18:53:43.625Z\",\n    \"updatedBy\": {\n        \"id\": \"7b5f6ea6-7b3a-4437-838a-9a31994aacb3\",\n        \"firstName\": \"Edward\",\n        \"lastName\": \"Maxedon\"\n    },\n    \"vehicle\": null\n}"}],"_postman_id":"28f0982d-57ff-4945-81ee-9c7670b41da0"},{"name":"Update User","id":"d86757df-28fb-4e76-9dd0-f2fc22365333","request":{"method":"PATCH","header":[],"body":{"mode":"raw","raw":"{\n  \"firstName\": \"Sam\",\n  \"lastName\": \"Lee\",\n  \"role\": \"DISPATCHER\",\n  \"storeIds\": [\n    \"9f2d1c34-0000-0000-0000-000000000000\"\n  ]\n}","options":{"raw":{"language":"json"}}},"url":"{{hostname}}/v2/users/:id","description":"<p>Partially updates a user on your account. All fields are optional — only the fields present are changed. Changing the email resets its verified status.</p>\n<p>Guards: a <code>DRIVER</code> with confirmed trips cannot change role or be removed from a store (<code>400 USER_HAS_CONFIRMED_TRIPS</code>).</p>\n<p><strong>Required role:</strong> <code>ADMIN</code> or higher. An account API key always satisfies this (it authenticates as the account owner).</p>\n<h4 id=\"body-fields\">Body fields</h4>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Field</th>\n<th>Type</th>\n<th>Required</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>role</code></td>\n<td>string</td>\n<td>No</td>\n<td>One of <code>ADMIN</code>, <code>DISPATCHER</code>, <code>DRIVER</code>, <code>OWNER</code>, <code>BILLING</code>.</td>\n</tr>\n<tr>\n<td><code>email</code></td>\n<td>string</td>\n<td>No</td>\n<td>New email address, max 83 characters. <code>409</code> if already taken.</td>\n</tr>\n<tr>\n<td><code>firstName</code></td>\n<td>string</td>\n<td>No</td>\n<td>Max 100 characters.</td>\n</tr>\n<tr>\n<td><code>lastName</code></td>\n<td>string</td>\n<td>No</td>\n<td>Max 100 characters.</td>\n</tr>\n<tr>\n<td><code>phoneNumber</code></td>\n<td>string</td>\n<td>No</td>\n<td>Max 100 characters.</td>\n</tr>\n<tr>\n<td><code>language</code></td>\n<td>string</td>\n<td>No</td>\n<td><code>en</code> or <code>fr</code>.</td>\n</tr>\n<tr>\n<td><code>storeIds</code></td>\n<td>string[] (UUID)</td>\n<td>No</td>\n<td>Full replacement set of store assignments. Omit to leave assignments unchanged.</td>\n</tr>\n</tbody>\n</table>\n</div><h4 id=\"response\">Response</h4>\n<p>Returns the updated user object.</p>\n","auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{apiKey}}"}]},"isInherited":true,"source":{"_postman_id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","name":"ShuttleControl Open API","type":"collection"}},"urlObject":{"path":["v2","users",":id"],"host":["{{hostname}}"],"query":[],"variable":[{"id":"748a2268-f2ee-4ead-ab16-b8405da22e0d","description":{"content":"<p>UUID of the user to update.</p>\n","type":"text/plain"},"type":"any","value":"","key":"id"}]}},"response":[],"_postman_id":"d86757df-28fb-4e76-9dd0-f2fc22365333"},{"name":"Update My Profile","id":"642bd4a6-2d2d-429c-8ad0-7d395bab6c39","request":{"method":"PUT","header":[],"body":{"mode":"raw","raw":"{\n  \"email\": \"jane@example.com\",\n  \"firstName\": \"Jane\",\n  \"lastName\": \"Doe\",\n  \"phoneNumber\": \"+1 514 555 0100\",\n  \"language\": \"en\"\n}","options":{"raw":{"language":"json"}}},"url":"{{hostname}}/v2/users/me","description":"<p>Updates the authenticated user’s own profile. All fields are required (send the current value for anything you don’t want to change).</p>\n<h4 id=\"body-fields\">Body fields</h4>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Field</th>\n<th>Type</th>\n<th>Required</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>email</code></td>\n<td>string</td>\n<td>Yes</td>\n<td>Email address, max 83 characters. <code>409</code> if taken by another user.</td>\n</tr>\n<tr>\n<td><code>firstName</code></td>\n<td>string</td>\n<td>Yes</td>\n<td>Max 100 characters.</td>\n</tr>\n<tr>\n<td><code>lastName</code></td>\n<td>string</td>\n<td>Yes</td>\n<td>Max 100 characters.</td>\n</tr>\n<tr>\n<td><code>phoneNumber</code></td>\n<td>string</td>\n<td>Yes</td>\n<td>Max 100 characters.</td>\n</tr>\n<tr>\n<td><code>language</code></td>\n<td>string</td>\n<td>Yes</td>\n<td><code>en</code> or <code>fr</code>.</td>\n</tr>\n</tbody>\n</table>\n</div><h4 id=\"response\">Response</h4>\n<p>Responds <code>204 No Content</code>.</p>\n","auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{apiKey}}"}]},"isInherited":true,"source":{"_postman_id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","name":"ShuttleControl Open API","type":"collection"}},"urlObject":{"path":["v2","users","me"],"host":["{{hostname}}"],"query":[],"variable":[]}},"response":[],"_postman_id":"642bd4a6-2d2d-429c-8ad0-7d395bab6c39"},{"name":"Change Password","id":"813cb9a3-99f3-4cca-af38-d31e90b6a98a","request":{"method":"PATCH","header":[],"body":{"mode":"raw","raw":"{\n  \"password\": \"a-much-stronger-password\",\n  \"id\": \"4be9f1e0-0000-0000-0000-000000000000\"\n}","options":{"raw":{"language":"json"}}},"url":"{{hostname}}/v2/users/changePassword","description":"<p>Changes a password. Without <code>id</code>, changes the authenticated user’s own password. With <code>id</code>, an <code>OWNER</code> or <code>ADMIN</code> changes another user’s password (the target must be visible to the caller). A confirmation email is sent to the affected user.</p>\n<h4 id=\"body-fields\">Body fields</h4>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Field</th>\n<th>Type</th>\n<th>Required</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>password</code></td>\n<td>string</td>\n<td>Yes</td>\n<td>The new password, 8–100 characters.</td>\n</tr>\n<tr>\n<td><code>id</code></td>\n<td>string (UUID)</td>\n<td>No</td>\n<td>Target user id. Omit to change your own password.</td>\n</tr>\n</tbody>\n</table>\n</div><h4 id=\"response\">Response</h4>\n<p>Responds <code>204 No Content</code>.</p>\n","auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{apiKey}}"}]},"isInherited":true,"source":{"_postman_id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","name":"ShuttleControl Open API","type":"collection"}},"urlObject":{"path":["v2","users","changePassword"],"host":["{{hostname}}"],"query":[],"variable":[]}},"response":[],"_postman_id":"813cb9a3-99f3-4cca-af38-d31e90b6a98a"},{"name":"Transfer Ownership","id":"2f762520-5c7d-4e0a-8fcc-43c708ffbb76","request":{"method":"PATCH","header":[],"body":{"mode":"raw","raw":"{\n  \"id\": \"4be9f1e0-0000-0000-0000-000000000000\"\n}","options":{"raw":{"language":"json"}}},"url":"{{hostname}}/v2/users/transferOwnership","description":"<p>Transfers account ownership to another user. The target becomes <code>OWNER</code> (and is assigned to every store on the account); the caller is demoted to <code>ADMIN</code>. The Stripe customer contact is updated to the new owner.</p>\n<p><strong>Required role:</strong> <code>OWNER</code> or higher. An account API key always satisfies this (it authenticates as the account owner).</p>\n<h4 id=\"body-fields\">Body fields</h4>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Field</th>\n<th>Type</th>\n<th>Required</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>id</code></td>\n<td>string (UUID)</td>\n<td>Yes</td>\n<td>The user who becomes the new owner. Must not be the caller.</td>\n</tr>\n</tbody>\n</table>\n</div><h4 id=\"response\">Response</h4>\n<p>Responds <code>204 No Content</code>.</p>\n","auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{apiKey}}"}]},"isInherited":true,"source":{"_postman_id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","name":"ShuttleControl Open API","type":"collection"}},"urlObject":{"path":["v2","users","transferOwnership"],"host":["{{hostname}}"],"query":[],"variable":[]}},"response":[],"_postman_id":"2f762520-5c7d-4e0a-8fcc-43c708ffbb76"},{"name":"Deactivate User","id":"a0ed9ca3-4bd5-4e61-8fb2-bea7c23958a3","request":{"method":"DELETE","header":[],"url":"{{hostname}}/v2/users/:id","description":"<p>Soft-deletes (deactivates) a user. Drivers with confirmed trips cannot be deactivated (<code>400 USER_HAS_CONFIRMED_TRIPS</code>); a driver’s claimed vehicle is automatically released. Deactivated users can be restored with <strong>Reactivate User</strong> or <strong>Retake User</strong>.</p>\n<p><strong>Required role:</strong> <code>ADMIN</code> or higher. An account API key always satisfies this (it authenticates as the account owner).</p>\n<h4 id=\"response\">Response</h4>\n<p>Returns the deactivated user object.</p>\n","auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{apiKey}}"}]},"isInherited":true,"source":{"_postman_id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","name":"ShuttleControl Open API","type":"collection"}},"urlObject":{"path":["v2","users",":id"],"host":["{{hostname}}"],"query":[],"variable":[{"id":"c926657a-a2cd-41c7-bdfa-b2a1499c65e9","description":{"content":"<p>UUID of the user to deactivate.</p>\n","type":"text/plain"},"type":"any","value":"","key":"id"}]}},"response":[{"id":"bcca6e10-a6e8-4b25-88cb-327496b65d3e","name":"Deactivate User response","originalRequest":{"method":"DELETE","header":[],"url":"{{hostname}}/v2/users/"},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"content-length","value":"151"},{"key":"content-type","value":"application/json; charset=utf-8"}],"cookie":[],"responseTime":null,"body":"{\n    \"id\": \"515e4f0e-fc7a-4484-a1f9-cc7ed568eb76\",\n    \"enabled\": false,\n    \"updatedAt\": \"2023-03-16T19:17:04.345Z\",\n    \"updatedBy\": \"7b5f6ea6-7b3a-4437-838a-9a31994aacb3\"\n}"}],"_postman_id":"a0ed9ca3-4bd5-4e61-8fb2-bea7c23958a3"},{"name":"Reactivate User","id":"f5581524-d8b3-49b9-a09a-b0a8d2bf91f5","request":{"method":"POST","header":[],"url":"{{hostname}}/v2/users/:id/reactivate","description":"<p>Re-enables a deactivated user without changing any of their details. Responds <code>400</code> if the user is already active.</p>\n<p><strong>Required role:</strong> <code>ADMIN</code> or higher. An account API key always satisfies this (it authenticates as the account owner).</p>\n<h4 id=\"response\">Response</h4>\n<p>Returns the reactivated user object.</p>\n","auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{apiKey}}"}]},"isInherited":true,"source":{"_postman_id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","name":"ShuttleControl Open API","type":"collection"}},"urlObject":{"path":["v2","users",":id","reactivate"],"host":["{{hostname}}"],"query":[],"variable":[{"id":"227c2166-e364-498e-a4d9-1620cdc9de3d","description":{"content":"<p>UUID of the user to reactivate.</p>\n","type":"text/plain"},"type":"any","value":"","key":"id"}]}},"response":[{"id":"2350b7fd-74ca-46cd-99aa-e739dc5be022","name":"Reactivate User response","originalRequest":{"method":"POST","header":[],"url":"{{hostname}}/v2/users//reactivate"},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"content-length","value":"150"},{"key":"content-type","value":"application/json; charset=utf-8"}],"cookie":[],"responseTime":null,"body":"{\n    \"id\": \"515e4f0e-fc7a-4484-a1f9-cc7ed568eb76\",\n    \"enabled\": true,\n    \"updatedAt\": \"2023-03-16T19:18:09.219Z\",\n    \"updatedBy\": \"7b5f6ea6-7b3a-4437-838a-9a31994aacb3\"\n}"}],"_postman_id":"f5581524-d8b3-49b9-a09a-b0a8d2bf91f5"},{"name":"Assign Stores","id":"3c8bb523-1518-433d-bbda-c381c2467aba","request":{"method":"POST","header":[],"body":{"mode":"raw","raw":"{\n  \"users\": [\n    \"4be9f1e0-0000-0000-0000-000000000000\"\n  ],\n  \"stores\": [\n    \"9f2d1c34-0000-0000-0000-000000000000\"\n  ]\n}","options":{"raw":{"language":"json"}}},"url":"{{hostname}}/v2/users/assignStores","description":"<p>Bulk-assigns stores to users. Each listed user is <strong>added</strong> to each listed store (existing assignments are kept — this endpoint never removes assignments). All users and stores are validated against the caller’s account before any change is applied.</p>\n<p><strong>Required role:</strong> <code>ADMIN</code> or higher. An account API key always satisfies this (it authenticates as the account owner).</p>\n<h4 id=\"body-fields\">Body fields</h4>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Field</th>\n<th>Type</th>\n<th>Required</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>users</code></td>\n<td>string[] (UUID)</td>\n<td>Yes</td>\n<td>Users to assign.</td>\n</tr>\n<tr>\n<td><code>stores</code></td>\n<td>string[] (UUID)</td>\n<td>Yes</td>\n<td>Stores to add them to.</td>\n</tr>\n</tbody>\n</table>\n</div><h4 id=\"response\">Response</h4>\n<p>Responds <code>204 No Content</code>.</p>\n","auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{apiKey}}"}]},"isInherited":true,"source":{"_postman_id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","name":"ShuttleControl Open API","type":"collection"}},"urlObject":{"path":["v2","users","assignStores"],"host":["{{hostname}}"],"query":[],"variable":[]}},"response":[],"_postman_id":"3c8bb523-1518-433d-bbda-c381c2467aba"},{"name":"Update My Theme","id":"2596dbaf-f4dd-4d9d-ac6f-a5107a14c0b1","request":{"method":"PATCH","header":[],"body":{"mode":"raw","raw":"{\n  \"themePreference\": \"dark\"\n}","options":{"raw":{"language":"json"}}},"url":"{{hostname}}/v2/users/me/theme","description":"<p>Sets the authenticated user’s UI theme preference (used by the ShuttleControl apps).</p>\n<h4 id=\"body-fields\">Body fields</h4>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Field</th>\n<th>Type</th>\n<th>Required</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>themePreference</code></td>\n<td>string</td>\n<td>Yes</td>\n<td><code>light</code> or <code>dark</code>.</td>\n</tr>\n</tbody>\n</table>\n</div><h4 id=\"response\">Response</h4>\n<p>Responds <code>204 No Content</code>.</p>\n","auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{apiKey}}"}]},"isInherited":true,"source":{"_postman_id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","name":"ShuttleControl Open API","type":"collection"}},"urlObject":{"path":["v2","users","me","theme"],"host":["{{hostname}}"],"query":[],"variable":[]}},"response":[],"_postman_id":"2596dbaf-f4dd-4d9d-ac6f-a5107a14c0b1"},{"name":"Register Push Token","id":"3d20ac32-f62f-4a87-9473-46802ef05797","request":{"method":"POST","header":[],"body":{"mode":"raw","raw":"{\n  \"fcmToken\": \"fcm-device-token\"\n}","options":{"raw":{"language":"json"}}},"url":"{{hostname}}/v2/users/me/fcmToken","description":"<p>Registers a Firebase Cloud Messaging token for the authenticated user so they receive mobile push notifications. Used by the ShuttleControl Driver app; each user holds a single token (a new registration replaces the previous one).</p>\n<h4 id=\"body-fields\">Body fields</h4>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Field</th>\n<th>Type</th>\n<th>Required</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>fcmToken</code></td>\n<td>string</td>\n<td>Yes</td>\n<td>The FCM device token.</td>\n</tr>\n</tbody>\n</table>\n</div><h4 id=\"response\">Response</h4>\n<p>Responds <code>204 No Content</code>.</p>\n","auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{apiKey}}"}]},"isInherited":true,"source":{"_postman_id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","name":"ShuttleControl Open API","type":"collection"}},"urlObject":{"path":["v2","users","me","fcmToken"],"host":["{{hostname}}"],"query":[],"variable":[]}},"response":[],"_postman_id":"3d20ac32-f62f-4a87-9473-46802ef05797"},{"name":"Remove Push Token","id":"ea206a17-4800-42f2-9e92-287ead6541e0","request":{"method":"DELETE","header":[],"url":"{{hostname}}/v2/users/me/fcmToken","description":"<p>Clears the authenticated user’s push-notification token (e.g. on sign-out of the mobile app).</p>\n<h4 id=\"response\">Response</h4>\n<p>Responds <code>204 No Content</code>.</p>\n","auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{apiKey}}"}]},"isInherited":true,"source":{"_postman_id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","name":"ShuttleControl Open API","type":"collection"}},"urlObject":{"path":["v2","users","me","fcmToken"],"host":["{{hostname}}"],"query":[],"variable":[]}},"response":[],"_postman_id":"ea206a17-4800-42f2-9e92-287ead6541e0"},{"name":"Upload My Profile Image","id":"639785fd-1997-4a1e-9bde-e210ecc069ff","request":{"method":"POST","header":[],"body":{"mode":"raw","raw":"{\n  \"imageBase64\": \"iVBORw0KGgoAAAANSUhEUg…\",\n  \"fileType\": \"image/png\"\n}","options":{"raw":{"language":"json"}}},"url":"{{hostname}}/v2/users/me/image","description":"<p>Uploads (or replaces) the authenticated user’s profile image.</p>\n<h4 id=\"body-fields\">Body fields</h4>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Field</th>\n<th>Type</th>\n<th>Required</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>imageBase64</code></td>\n<td>string</td>\n<td>Yes</td>\n<td>The image content, base64-encoded.</td>\n</tr>\n<tr>\n<td><code>fileType</code></td>\n<td>string</td>\n<td>Yes</td>\n<td><code>image/png</code> or <code>image/jpeg</code>.</td>\n</tr>\n</tbody>\n</table>\n</div><h4 id=\"response\">Response</h4>\n<p>Returns <code>{ profileUrl }</code> — the stored image path.</p>\n","auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{apiKey}}"}]},"isInherited":true,"source":{"_postman_id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","name":"ShuttleControl Open API","type":"collection"}},"urlObject":{"path":["v2","users","me","image"],"host":["{{hostname}}"],"query":[],"variable":[]}},"response":[],"_postman_id":"639785fd-1997-4a1e-9bde-e210ecc069ff"},{"name":"Remove My Profile Image","id":"188f19ec-a791-4aac-8128-61c6b9dcb1b8","request":{"method":"DELETE","header":[],"url":"{{hostname}}/v2/users/me/image","description":"<p>Deletes the authenticated user’s profile image.</p>\n<h4 id=\"response\">Response</h4>\n<p>Responds <code>204 No Content</code>. <code>404</code> if no image is set.</p>\n","auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{apiKey}}"}]},"isInherited":true,"source":{"_postman_id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","name":"ShuttleControl Open API","type":"collection"}},"urlObject":{"path":["v2","users","me","image"],"host":["{{hostname}}"],"query":[],"variable":[]}},"response":[],"_postman_id":"188f19ec-a791-4aac-8128-61c6b9dcb1b8"},{"name":"Upload User Profile Image","id":"0b2d8449-9764-4998-8eb5-ac33a7e3e89a","request":{"method":"POST","header":[],"body":{"mode":"raw","raw":"{\n  \"imageBase64\": \"iVBORw0KGgoAAAANSUhEUg…\",\n  \"fileType\": \"image/png\"\n}","options":{"raw":{"language":"json"}}},"url":"{{hostname}}/v2/users/:id/image","description":"<p>Uploads (or replaces) another user’s profile image. The target user must be visible to the caller.</p>\n<p><strong>Required role:</strong> <code>ADMIN</code> or higher. An account API key always satisfies this (it authenticates as the account owner).</p>\n<h4 id=\"body-fields\">Body fields</h4>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Field</th>\n<th>Type</th>\n<th>Required</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>imageBase64</code></td>\n<td>string</td>\n<td>Yes</td>\n<td>The image content, base64-encoded.</td>\n</tr>\n<tr>\n<td><code>fileType</code></td>\n<td>string</td>\n<td>Yes</td>\n<td><code>image/png</code> or <code>image/jpeg</code>.</td>\n</tr>\n</tbody>\n</table>\n</div><h4 id=\"response\">Response</h4>\n<p>Returns <code>{ profileUrl }</code>.</p>\n","auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{apiKey}}"}]},"isInherited":true,"source":{"_postman_id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","name":"ShuttleControl Open API","type":"collection"}},"urlObject":{"path":["v2","users",":id","image"],"host":["{{hostname}}"],"query":[],"variable":[{"id":"3f00cf04-acfa-4974-b19b-3366f162df9d","description":{"content":"<p>UUID of the user.</p>\n","type":"text/plain"},"type":"any","value":"","key":"id"}]}},"response":[],"_postman_id":"0b2d8449-9764-4998-8eb5-ac33a7e3e89a"},{"name":"Get User Profile Image","id":"baf5b1dc-e84c-4100-9984-e19dda6c342a","request":{"method":"GET","header":[],"url":"{{hostname}}/v2/users/:id/image","description":"<p>Returns the raw profile image binary for a user. This endpoint is unauthenticated so it can be used directly in <code>&lt;img&gt;</code> tags.</p>\n<h4 id=\"response\">Response</h4>\n<p>Returns the image with its original <code>Content-Type</code> (<code>image/png</code> or <code>image/jpeg</code>). <code>404</code> if the user has no image.</p>\n","auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{apiKey}}"}]},"isInherited":true,"source":{"_postman_id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","name":"ShuttleControl Open API","type":"collection"}},"urlObject":{"path":["v2","users",":id","image"],"host":["{{hostname}}"],"query":[],"variable":[{"id":"b9e85c72-362e-4e94-b550-904edc19544a","description":{"content":"<p>UUID of the user.</p>\n","type":"text/plain"},"type":"any","value":"","key":"id"}]}},"response":[],"_postman_id":"baf5b1dc-e84c-4100-9984-e19dda6c342a"},{"name":"Remove User Profile Image","id":"1aa48416-6cb1-47ff-ad0a-fbce55e3c93a","request":{"method":"DELETE","header":[],"url":"{{hostname}}/v2/users/:id/image","description":"<p>Deletes another user’s profile image. The target user must be visible to the caller.</p>\n<p><strong>Required role:</strong> <code>ADMIN</code> or higher. An account API key always satisfies this (it authenticates as the account owner).</p>\n<h4 id=\"response\">Response</h4>\n<p>Responds <code>204 No Content</code>.</p>\n","auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{apiKey}}"}]},"isInherited":true,"source":{"_postman_id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","name":"ShuttleControl Open API","type":"collection"}},"urlObject":{"path":["v2","users",":id","image"],"host":["{{hostname}}"],"query":[],"variable":[{"id":"2e2b563a-e395-45b2-a25f-9131aac86b82","description":{"content":"<p>UUID of the user.</p>\n","type":"text/plain"},"type":"any","value":"","key":"id"}]}},"response":[],"_postman_id":"1aa48416-6cb1-47ff-ad0a-fbce55e3c93a"}],"id":"d18d3b80-c42f-47ad-adce-322b3dda4ecd","description":"<p>Manage the staff on your account. User roles: <code>ADMIN</code> | <code>DISPATCHER</code> | <code>DRIVER</code> | <code>OWNER</code> | <code>BILLING</code>. Endpoints under <code>/me</code> act on the authenticated caller — when authenticating with an API key, “me” is the account owner.</p>\n","_postman_id":"d18d3b80-c42f-47ad-adce-322b3dda4ecd","auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{apiKey}}"}]},"isInherited":true,"source":{"_postman_id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","name":"ShuttleControl Open API","type":"collection"}}},{"name":"Trips","item":[{"name":"Create Trip","id":"bd8c9f51-11af-461e-8d9e-56e371cc66e2","request":{"method":"POST","header":[],"body":{"mode":"raw","raw":"{\n  \"storeId\": \"9f2d1c34-0000-0000-0000-000000000000\",\n  \"workflowId\": \"7ab30e12-0000-0000-0000-000000000000\",\n  \"state\": \"SCHEDULED\",\n  \"scheduledAt\": \"2026-08-01T14:30:00.000Z\",\n  \"customerId\": null,\n  \"firstName\": \"Jane\",\n  \"lastName\": \"Doe\",\n  \"phoneNumber\": \"+1 514 555 0100\",\n  \"language\": \"en\",\n  \"seats\": 2,\n  \"steps\": [\n    {\n      \"name\": \"Pickup\",\n      \"type\": \"place\",\n      \"position\": 1,\n      \"place\": {\n        \"address\": \"1 Main St, Montreal, QC\"\n      }\n    },\n    {\n      \"name\": \"Dropoff\",\n      \"type\": \"place\",\n      \"position\": 2,\n      \"place\": {\n        \"address\": \"900 Airport Rd, Dorval, QC\"\n      }\n    }\n  ],\n  \"returnTrip\": {\n    \"enabled\": false\n  }\n}","options":{"raw":{"language":"json"}}},"url":"{{hostname}}/v2/trips","description":"<p>Creates a trip for a store and workflow, optionally creating the customer inline and/or a linked return trip.</p>\n<ul>\n<li>If <code>customerId</code> is omitted or <code>null</code>, a customer is created from <code>firstName</code>/<code>lastName</code>/<code>companyName</code>/<code>email</code>/<code>phoneNumber</code>/<code>language</code>.</li>\n<li><code>scheduledAt</code> is <strong>required</strong> when <code>state</code> is <code>SCHEDULED</code>.</li>\n<li>If the store has a radius bound (and does not allow trips outside it), trips whose places fall outside the radius are rejected with <code>400 TRIP_IS_OUTSIDE_STORE_RADIUS</code>.</li>\n<li>When overbooking prevention is enabled on the store, scheduled trips that exceed capacity are rejected; shareable trips are automatically marked as rideshares.</li>\n</ul>\n<p>Each step object: <code>name</code> (string, required), <code>type</code> (string, required — <code>message</code> | <code>place</code> | <code>image</code> | <code>images</code> | <code>task</code> | <code>signature</code> | <code>video</code>), <code>position</code> (integer ≥ 1, required — execution order), <code>messageTemplate</code> (<code>{ id: UUID }</code>, optional — for <code>message</code> steps), <code>place</code> (<code>{ address: string, latitude?: number, longitude?: number }</code>, optional — for <code>place</code> steps; coordinates are geocoded from the address when omitted).</p>\n<h4 id=\"body-fields\">Body fields</h4>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Field</th>\n<th>Type</th>\n<th>Required</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>storeId</code></td>\n<td>string (UUID)</td>\n<td>Yes</td>\n<td>The store the trip belongs to.</td>\n</tr>\n<tr>\n<td><code>workflowId</code></td>\n<td>string (UUID)</td>\n<td>Yes</td>\n<td>The workflow the trip follows.</td>\n</tr>\n<tr>\n<td><code>state</code></td>\n<td>string</td>\n<td>Yes</td>\n<td>Initial state: <code>REQUESTED</code>, <code>SCHEDULED</code>, or <code>PENDING</code>.</td>\n</tr>\n<tr>\n<td><code>steps</code></td>\n<td>object[]</td>\n<td>Yes</td>\n<td>The trip’s steps, in order (see description above for the step object shape).</td>\n</tr>\n<tr>\n<td><code>dispatcher</code></td>\n<td>string (UUID)</td>\n<td>No</td>\n<td>Dispatcher to attribute the trip to. Defaults to the caller.</td>\n</tr>\n<tr>\n<td><code>drivers</code></td>\n<td>string[] (UUID)</td>\n<td>No</td>\n<td>Drivers to pre-assign.</td>\n</tr>\n<tr>\n<td><code>vehicle</code></td>\n<td>string (UUID)</td>\n<td>null</td>\n<td>No</td>\n</tr>\n<tr>\n<td><code>customerId</code></td>\n<td>string (UUID)</td>\n<td>null</td>\n<td>No</td>\n</tr>\n<tr>\n<td><code>language</code></td>\n<td>string</td>\n<td>No</td>\n<td>New customer’s language: <code>en</code>, <code>fr</code>, or <code>es</code>.</td>\n</tr>\n<tr>\n<td><code>firstName</code></td>\n<td>string</td>\n<td>No</td>\n<td>New customer’s first name (max 100). Default <code>\"\"</code>.</td>\n</tr>\n<tr>\n<td><code>lastName</code></td>\n<td>string</td>\n<td>No</td>\n<td>New customer’s last name (max 100). Default <code>\"\"</code>.</td>\n</tr>\n<tr>\n<td><code>companyName</code></td>\n<td>string</td>\n<td>No</td>\n<td>New customer’s company name (max 100). Default <code>\"\"</code>.</td>\n</tr>\n<tr>\n<td><code>email</code></td>\n<td>string</td>\n<td>No</td>\n<td>New customer’s email (max 100). Default <code>\"\"</code>.</td>\n</tr>\n<tr>\n<td><code>phoneNumber</code></td>\n<td>string</td>\n<td>No</td>\n<td>New customer’s phone number (max 100). Default <code>\"\"</code>.</td>\n</tr>\n<tr>\n<td><code>customerNotes</code></td>\n<td>string</td>\n<td>No</td>\n<td>Notes stored on the customer. Default <code>\"\"</code>.</td>\n</tr>\n<tr>\n<td><code>secondaryCustomerId</code></td>\n<td>string (UUID)</td>\n<td>null</td>\n<td>No</td>\n</tr>\n<tr>\n<td><code>secondaryLanguage</code></td>\n<td>string</td>\n<td>No</td>\n<td><code>en</code></td>\n</tr>\n<tr>\n<td><code>secondaryFirstName</code></td>\n<td>string</td>\n<td>No</td>\n<td>Max 100. Default <code>\"\"</code>.</td>\n</tr>\n<tr>\n<td><code>secondaryLastName</code></td>\n<td>string</td>\n<td>No</td>\n<td>Max 100. Default <code>\"\"</code>.</td>\n</tr>\n<tr>\n<td><code>secondaryCompanyName</code></td>\n<td>string</td>\n<td>No</td>\n<td>Max 100. Default <code>\"\"</code>.</td>\n</tr>\n<tr>\n<td><code>secondaryEmail</code></td>\n<td>string</td>\n<td>No</td>\n<td>Default <code>\"\"</code>.</td>\n</tr>\n<tr>\n<td><code>secondaryPhoneNumber</code></td>\n<td>string</td>\n<td>No</td>\n<td>Max 100. Default <code>\"\"</code>.</td>\n</tr>\n<tr>\n<td><code>seats</code></td>\n<td>number</td>\n<td>No</td>\n<td>Seats required, 1–40. Default <code>1</code>.</td>\n</tr>\n<tr>\n<td><code>reference</code></td>\n<td>string</td>\n<td>No</td>\n<td>Free-form external reference (max 100). Default <code>\"\"</code>.</td>\n</tr>\n<tr>\n<td><code>notes</code></td>\n<td>string</td>\n<td>No</td>\n<td>Trip note (max 500 characters).</td>\n</tr>\n<tr>\n<td><code>scheduledAt</code></td>\n<td>string (ISO 8601)</td>\n<td>null</td>\n<td>Conditional</td>\n</tr>\n<tr>\n<td><code>notifyAt</code></td>\n<td>string (ISO 8601)</td>\n<td>null</td>\n<td>No</td>\n</tr>\n<tr>\n<td><code>returnTrip</code></td>\n<td>object</td>\n<td>No</td>\n<td><code>{ enabled: false }</code>, or <code>{ enabled: true, workflowId (UUID, required), state (</code>PENDING`</td>\n</tr>\n<tr>\n<td><code>tripOptimizationHeuristic</code></td>\n<td>string</td>\n<td>No</td>\n<td><code>MINIMIZE_DURATION</code> (default) or <code>MINIMIZE_DISTANCE</code>.</td>\n</tr>\n<tr>\n<td><code>distance</code></td>\n<td>integer</td>\n<td>No</td>\n<td>Pre-computed route distance in meters (used for radius checks).</td>\n</tr>\n<tr>\n<td><code>duration</code></td>\n<td>integer</td>\n<td>No</td>\n<td>Pre-computed route duration in seconds.</td>\n</tr>\n</tbody>\n</table>\n</div><h4 id=\"response\">Response</h4>\n<p>Responds <code>201</code> with the created trip and a <code>Location</code> header.</p>\n","auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{apiKey}}"}]},"isInherited":true,"source":{"_postman_id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","name":"ShuttleControl Open API","type":"collection"}},"urlObject":{"path":["v2","trips"],"host":["{{hostname}}"],"query":[],"variable":[]}},"response":[{"id":"f5e4b86b-8510-458a-998c-601fcf683a32","name":"Create Trip","originalRequest":{"method":"POST","header":[],"body":{"mode":"raw","raw":"{\n    \"storeId\": \"\",\n    \"workflowId\": \"\",\n    \"state\": \"REQUESTED\",\n    \"language\": \"en\",\n    \"firstName\": \"Jamie\",\n    \"lastName\": \"Tremblay\",\n    \"phoneNumber\": \"555 543 6543\",\n    \"seats\": 2,\n    \"steps\": [{\n        \"name\": \"Point A\",\n        \"type\": \"place\",\n        \"position\": 1,\n        \"place\": {\n            \"address\": \"1255 Phillips Square, Montréal, QC H3B 3G1\"\n        }\n    }, {\n        \"name\": \"Point B\",\n        \"type\": \"place\",\n        \"position\": 2,\n        \"place\": {\n            \"address\": \"3901 Rue Bannantyne, Verdun, H4G 1C2\"\n        }\n    }]\n}","options":{"raw":{"language":"json"}}},"url":"{{hostname}}/v2/trips"},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Server","value":"nginx"},{"key":"Date","value":"Thu, 20 Feb 2025 21:35:38 GMT"},{"key":"Content-Type","value":"application/json; charset=utf-8"},{"key":"Transfer-Encoding","value":"chunked"},{"key":"Connection","value":"keep-alive"},{"key":"Access-Control-Allow-Origin","value":"*"},{"key":"Content-Security-Policy","value":"default-src 'self';base-uri 'self';font-src 'self' https: data:;form-action 'self';frame-ancestors 'self';img-src 'self' data:;object-src 'none';script-src 'self';script-src-attr 'none';style-src 'self' https: 'unsafe-inline';upgrade-insecure-requests"},{"key":"Cross-Origin-Embedder-Policy","value":"require-corp"},{"key":"Cross-Origin-Opener-Policy","value":"same-origin"},{"key":"X-DNS-Prefetch-Control","value":"off"},{"key":"X-Frame-Options","value":"SAMEORIGIN"},{"key":"Strict-Transport-Security","value":"max-age=15552000; includeSubDomains"},{"key":"X-Download-Options","value":"noopen"},{"key":"X-Content-Type-Options","value":"nosniff"},{"key":"Origin-Agent-Cluster","value":"?1"},{"key":"X-Permitted-Cross-Domain-Policies","value":"none"},{"key":"Referrer-Policy","value":"no-referrer"},{"key":"X-XSS-Protection","value":"0"},{"key":"Location","value":"https://api.shuttlecontrol.com/v2/trips/390d5507-40cc-4b8c-9132-c3eee0610370"},{"key":"ETag","value":"W/\"baa-DxTukqlQHMD7fpnyWP5cf3dAEoA\""},{"key":"Vary","value":"Accept-Encoding"},{"key":"Content-Encoding","value":"gzip"}],"cookie":[],"responseTime":null,"body":"{\n    \"id\": \"390d5507-40cc-4b8c-9132-c3eee0610370\",\n    \"state\": \"REQUESTED\",\n    \"position\": 1,\n    \"seats\": 2,\n    \"reference\": \"\",\n    \"scheduledAt\": null,\n    \"requestedAt\": \"2025-02-20T21:35:37.476Z\",\n    \"createdAt\": \"2025-02-20T21:35:37.476Z\",\n    \"confirmedAt\": null,\n    \"finishedAt\": null,\n    \"customer\": {\n        \"id\": \"1879e5a6-e0da-4442-b754-eb615dd72672\",\n        \"firstName\": \"Jamie\",\n        \"lastName\": \"Tremblay\",\n        \"companyName\": \"\",\n        \"phoneNumber\": \"555 543 6543\",\n        \"email\": \"\",\n        \"language\": \"en\"\n    },\n    \"secondaryCustomer\": null,\n    \"customerReview\": null,\n    \"workflow\": {\n        \"id\": \"7e1e615e-ae7a-42df-abb8-d08aa18b696d\",\n        \"name\": \"Shuttle Drop-off\",\n        \"enableScheduledTripSms\": true,\n        \"customerReviewsEnabled\": true,\n        \"schedulerStepSize\": 15,\n        \"defaultReturnTripWorkflow\": {\n            \"id\": \"f7da5112-a01c-4ebd-b20c-d9a6561cf9db\",\n            \"name\": \"Shuttle Pickup\"\n        },\n        \"companyNameRequired\": false,\n        \"phoneNumberRequired\": true,\n        \"customerRequired\": true\n    },\n    \"store\": {\n        \"id\": \"5b1cc486-1382-4dfd-9e65-b2fbdddf39df\",\n        \"name\": \"ShuttleControl\",\n        \"place\": {\n            \"id\": \"53169fee-7fe9-416e-90ff-e4cb0e64bbb3\",\n            \"address\": \"General Urquiza, Buenos Aires, Argentina\",\n            \"latitude\": -34.5703983,\n            \"longitude\": -58.49138680000001,\n            \"isFavorite\": true\n        },\n        \"storeBusinessHours\": {\n            \"sundayStartAt\": null,\n            \"sundayEndAt\": null,\n            \"mondayStartAt\": \"2024-10-30T12:00:00.397Z\",\n            \"mondayEndAt\": \"2024-10-30T20:00:00.160Z\",\n            \"tuesdayStartAt\": \"2024-10-30T12:00:00.401Z\",\n            \"tuesdayEndAt\": \"2024-10-30T20:00:00.316Z\",\n            \"wednesdayStartAt\": \"2024-10-30T12:00:00.588Z\",\n            \"wednesdayEndAt\": \"2024-10-30T20:00:00.780Z\",\n            \"thursdayStartAt\": \"2024-10-30T12:00:00.926Z\",\n            \"thursdayEndAt\": \"2024-10-30T20:00:00.042Z\",\n            \"fridayStartAt\": \"2024-10-30T06:00:00.494Z\",\n            \"fridayEndAt\": \"2024-10-31T02:00:00.318Z\",\n            \"saturdayStartAt\": null,\n            \"saturdayEndAt\": null\n        }\n    },\n    \"steps\": [\n        {\n            \"id\": \"9c10cdd8-84f8-4923-8837-0c57e8dde62e\",\n            \"name\": \"Point A\",\n            \"type\": \"place\",\n            \"position\": 1,\n            \"imageUrl\": null,\n            \"videoUrl\": null,\n            \"place\": {\n                \"id\": \"20d7962f-9069-47e7-9472-a253738a68a6\",\n                \"address\": \"1255 Phillips Square, Montréal, QC H3B 3G1\",\n                \"latitude\": 45.5041764,\n                \"longitude\": -73.56834049999999,\n                \"isFavorite\": false\n            },\n            \"driver\": null,\n            \"vehicle\": null,\n            \"finishedAt\": null,\n            \"vehicleCoordinate\": null\n        },\n        {\n            \"id\": \"5a920c88-efe9-4d7a-b2ce-6d39b7bfbf8b\",\n            \"name\": \"Point B\",\n            \"type\": \"place\",\n            \"position\": 2,\n            \"imageUrl\": null,\n            \"videoUrl\": null,\n            \"place\": {\n                \"id\": \"aaa26e45-a3f9-4f93-8ab2-d4a0eb392e17\",\n                \"address\": \"3901 Rue Bannantyne, Verdun, H4G 1C2\",\n                \"latitude\": 45.465069,\n                \"longitude\": -73.575825,\n                \"isFavorite\": false\n            },\n            \"driver\": null,\n            \"vehicle\": null,\n            \"finishedAt\": null,\n            \"vehicleCoordinate\": null\n        }\n    ],\n    \"notes\": [],\n    \"returnTrip\": null,\n    \"returnTripFor\": null,\n    \"createdBy\": {\n        \"id\": \"68eb270f-67b4-49c3-811b-03257c43b4aa\",\n        \"firstName\": \"Edward\",\n        \"lastName\": \"Maxedon\",\n        \"phoneNumber\": \"514 699 7622\"\n    },\n    \"finishedBy\": null,\n    \"drivers\": [\n        {\n            \"id\": \"0d6f6bcf-1eca-4e89-b128-0bc59404d16e\",\n            \"firstName\": \"Jennifer\",\n            \"lastName\": \"Parker\",\n            \"fcmToken\": \"dgibJGoTxkMRqTHMDsvD8j:APA91bGLCY9FxrnwRWoRU5r8GpeKRu5EVrtdlEelxc9jq5kWgQ0pA1r7ugm2VmeobepkinHirSY3iUs7p70i9TbTmspii3miQ85gvXY9ok0InBhs6TFFMlA\",\n            \"language\": \"fr\",\n            \"phoneNumber\": \"\"\n        }\n    ],\n    \"vehicle\": null,\n    \"confirmedBy\": null,\n    \"predictedDistance\": 8515.3,\n    \"actualDistance\": null,\n    \"predictedDuration\": 970.7,\n    \"geometry\": null,\n    \"zone\": null,\n    \"stateEvents\": []\n}"}],"_postman_id":"bd8c9f51-11af-461e-8d9e-56e371cc66e2"},{"name":"Get Trip","id":"ad566a80-b289-4a15-b3b9-61b558f689ec","request":{"method":"GET","header":[],"url":"{{hostname}}/v2/trips/:id","description":"<p>Returns a single trip with its customer, workflow, steps, drivers, vehicle, and state timestamps. The trip’s store must be visible to the caller.</p>\n<h4 id=\"response\">Response</h4>\n<p>Returns the full trip object.</p>\n","auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{apiKey}}"}]},"isInherited":true,"source":{"_postman_id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","name":"ShuttleControl Open API","type":"collection"}},"urlObject":{"path":["v2","trips",":id"],"host":["{{hostname}}"],"query":[],"variable":[{"id":"7c8c1cd9-fb82-41ce-9631-42a84c8de9b8","description":{"content":"<p>UUID of the trip.</p>\n","type":"text/plain"},"type":"any","value":"","key":"id"}]}},"response":[{"id":"8005aca0-ada6-4a16-9bfd-324e90347a2d","name":"Get Trip response","originalRequest":{"method":"GET","header":[],"url":"{{hostname}}/v2/trips/"},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"content-type","value":"application/json; charset=utf-8"}],"cookie":[],"responseTime":null,"body":"{\n    \"id\": \"eca054a0-174d-4ee1-a363-e9a9315adf5b\",\n    \"seats\": 2,\n    \"state\": \"REQUESTED\",\n    \"reference\": \"\",\n    \"customer\": {\n        \"id\": \"dc697ec3-18ef-4479-8670-154b0a4a776a\",\n        \"firstName\": \"Jamie\",\n        \"lastName\": \"Tremblay\",\n        \"phoneNumber\": \"555 543 6543\",\n        \"companyName\": \"\",\n        \"email\": \"\",\n        \"language\": \"en\"\n    },\n    \"workflow\": {\n        \"id\": \"117c7103-275e-4a18-ba2a-0556331fc408\",\n        \"name\": \"Shuttle Pickup\",\n        \"defaultReturnTripWorkflow\": null\n    },\n    \"scheduledAt\": null,\n    \"drivers\": [],\n    \"store\": {\n        \"id\": \"f1a04c8a-dc36-4203-9a9e-698e06cf7cef\",\n        \"name\": \"Alpha Store\",\n        \"place\": {\n            \"id\": \"c60c1e2c-e3af-4e6b-8917-45023225488f\",\n            \"address\": \"Saint Joseph's Oratory of Mount Royal\",\n            \"latitude\": 45.4919122,\n            \"longitude\": -73.6186555,\n            \"isFavorite\": true\n        }\n    },\n    \"notes\": [],\n    \"steps\": [\n        {\n            \"id\": \"6a52bc3a-d2c3-4794-8d08-3632930779af\",\n            \"type\": \"place\",\n            \"place\": {\n                \"id\": \"3cf70dd9-7c01-41df-8cbc-c6933565a70b\",\n                \"address\": \"1255 Phillips Square, Montréal, QC H3B 3G1\",\n                \"latitude\": 45.5041764,\n                \"longitude\": -73.56834049999999,\n                \"isFavorite\": false\n            },\n            \"position\": 1,\n            \"name\": \"Point A\",\n            \"finishedAt\": null,\n            \"imageUrl\": null,\n            \"driver\": null,\n            \"vehicle\": null\n        },\n        {\n            \"id\": \"044f137e-0a1f-49b8-bb36-247377c55dbe\",\n            \"type\": \"place\",\n            \"place\": {\n                \"id\": \"d2ac439a-1aa0-4edb-b889-2ecccb6c42c8\",\n                \"address\": \"3901 Rue Bannantyne, Verdun, H4G 1C2\",\n                \"latitude\": 45.4651011,\n                \"longitude\": -73.5759264,\n                \"isFavorite\": false\n            },\n            \"position\": 2,\n            \"name\": \"Point B\",\n            \"finishedAt\": null,\n            \"imageUrl\": null,\n            \"driver\": null,\n            \"vehicle\": null\n        }\n    ],\n    \"createdAt\": \"2023-03-14T18:47:36.377Z\",\n    \"confirmedAt\": null,\n    \"confirmedBy\": null,\n    \"createdBy\": {\n        \"id\": \"7b5f6ea6-7b3a-4437-838a-9a31994aacb3\",\n        \"firstName\": \"Edward\",\n        \"lastName\": \"Maxedon\",\n        \"phoneNumber\": \"514 699 7622\"\n    },\n    \"finishedAt\": null,\n    \"finishedBy\": null,\n    \"updatedBy\": null,\n    \"vehicle\": null,\n    \"geometry\": null,\n    \"predictedDistance\": 8507,\n    \"predictedDuration\": 912,\n    \"actualDistance\": null\n}"}],"_postman_id":"ad566a80-b289-4a15-b3b9-61b558f689ec"},{"name":"List Trips History","id":"4973aba8-2f41-424d-a540-6a424345d9d6","request":{"method":"GET","header":[],"url":"{{hostname}}/v2/trips/history?startDate=2026-07-01T00:00:00.000Z&endDate=2026-07-31T23:59:59.000Z&page=0&size=10","description":"<p>Returns a paginated list of finished (<code>COMPLETED</code> / <code>CANCELLED</code>) trips whose <code>finishedAt</code> falls between <code>startDate</code> and <code>endDate</code>, with rich filtering.</p>\n<h4 id=\"response\">Response</h4>\n<p>Returns <code>{ items, count }</code>.</p>\n","auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{apiKey}}"}]},"isInherited":true,"source":{"_postman_id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","name":"ShuttleControl Open API","type":"collection"}},"urlObject":{"path":["v2","trips","history"],"host":["{{hostname}}"],"query":[{"description":{"content":"<p>Required. ISO 8601 date; must be in the past. Window start (inclusive), matched against <code>finishedAt</code>.</p>\n","type":"text/plain"},"key":"startDate","value":"2026-07-01T00:00:00.000Z"},{"description":{"content":"<p>Required. ISO 8601 date. Window end (inclusive).</p>\n","type":"text/plain"},"key":"endDate","value":"2026-07-31T23:59:59.000Z"},{"description":{"content":"<p>Zero-based page index. Default <code>0</code>.</p>\n","type":"text/plain"},"key":"page","value":"0"},{"description":{"content":"<p>Page size, 1–100. Default <code>10</code>.</p>\n","type":"text/plain"},"key":"size","value":"10"},{"disabled":true,"description":{"content":"<p>Filter to one store (must be visible to the caller).</p>\n","type":"text/plain"},"key":"storeId","value":""},{"disabled":true,"description":{"content":"<p>Filter by the user who created the trip.</p>\n","type":"text/plain"},"key":"dispatcherId","value":""},{"disabled":true,"description":{"content":"<p>Filter by an assigned driver UUID, or the literal <code>UNASSIGNED</code> for trips with no driver.</p>\n","type":"text/plain"},"key":"driverId","value":""},{"disabled":true,"description":{"content":"<p><code>mostRecent</code> (default) | <code>leastRecent</code> (by scheduled/requested time) | <code>mostRecentEndDate</code> | <code>leastRecentEndDate</code> (by finish time).</p>\n","type":"text/plain"},"key":"sort","value":"mostRecent"},{"disabled":true,"description":{"content":"<p><code>COMPLETED</code> or <code>CANCELLED</code>. Default: both.</p>\n","type":"text/plain"},"key":"state","value":""},{"disabled":true,"description":{"content":"<p><code>SCHEDULED</code> (has a scheduled time) or <code>REQUESTED</code> (asap).</p>\n","type":"text/plain"},"key":"tripType","value":""},{"disabled":true,"description":{"content":"<p>Free-text search (max 100) over reference, customer name/company/phone, and trip notes.</p>\n","type":"text/plain"},"key":"search","value":""},{"disabled":true,"description":{"content":"<p>Filter by workflow.</p>\n","type":"text/plain"},"key":"workflowId","value":""},{"disabled":true,"description":{"content":"<p>Filter by zone.</p>\n","type":"text/plain"},"key":"zoneId","value":""},{"disabled":true,"description":{"content":"<p><code>true</code> (default) for normal trips, <code>false</code> for archived trips.</p>\n","type":"text/plain"},"key":"enabled","value":"true"}],"variable":[]}},"response":[{"id":"7cafc6d3-a5a6-4da8-bd94-7d83a6ce1743","name":"List Trips History response","originalRequest":{"method":"GET","header":[],"url":{"raw":"{{hostname}}/v2/trips/history?startDate=2023-03-17T15:22:20.469Z&endDate=2023-03-20T15:33:20.469Z&page=0&size=5","host":["{{hostname}}"],"path":["v2","trips","history"],"query":[{"key":"startDate","value":"2023-03-17T15:22:20.469Z"},{"key":"endDate","value":"2023-03-20T15:33:20.469Z"},{"key":"page","value":"0"},{"key":"size","value":"5"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"content-type","value":"application/json; charset=utf-8"}],"cookie":[],"responseTime":null,"body":"{\n    \"items\": [\n        {\n            \"id\": \"eca054a0-174d-4ee1-a363-e9a9315adf5b\",\n            \"state\": \"COMPLETED\",\n            \"position\": 1,\n            \"seats\": 2,\n            \"reference\": \"\",\n            \"scheduledAt\": null,\n            \"requestedAt\": \"2023-03-14T18:47:36.377Z\",\n            \"createdAt\": \"2023-03-14T18:47:36.377Z\",\n            \"confirmedAt\": null,\n            \"finishedAt\": \"2023-03-20T15:32:54.461Z\",\n            \"customer\": {\n                \"id\": \"dc697ec3-18ef-4479-8670-154b0a4a776a\",\n                \"firstName\": \"Jamie\",\n                \"lastName\": \"Tremblay\",\n                \"companyName\": \"\",\n                \"phoneNumber\": \"555 543 6543\",\n                \"email\": \"\",\n                \"language\": \"en\"\n            },\n            \"customerReview\": {\n                \"id\": \"a60f3fa6-70b2-4ca6-b349-169ef73dc38a\",\n                \"rating\": 4.5,\n                \"comment\": \"Thank you for such a wonderful shuttle experience!\",\n                \"createdAt\": \"2023-03-16T15:02:21.435Z\"\n            },\n            \"workflow\": {\n                \"id\": \"117c7103-275e-4a18-ba2a-0556331fc408\",\n                \"name\": \"Shuttle Pickup\",\n                \"enableScheduledTripSms\": true,\n                \"customerReviewsEnabled\": true\n            },\n            \"store\": {\n                \"id\": \"f1a04c8a-dc36-4203-9a9e-698e06cf7cef\",\n                \"name\": \"Alpha Store\",\n                \"place\": {\n                    \"id\": \"c60c1e2c-e3af-4e6b-8917-45023225488f\",\n                    \"address\": \"Saint Joseph's Oratory of Mount Royal\",\n                    \"latitude\": 45.4919122,\n                    \"longitude\": -73.6186555,\n                    \"isFavorite\": true\n                }\n            },\n            \"steps\": [\n                {\n                    \"id\": \"6a52bc3a-d2c3-4794-8d08-3632930779af\",\n                    \"type\": \"place\",\n                    \"position\": 1,\n                    \"imageUrl\": null,\n                    \"place\": {\n                        \"id\": \"3cf70dd9-7c01-41df-8cbc-c6933565a70b\",\n                        \"address\": \"1255 Phillips Square, Montréal, QC H3B 3G1\",\n                        \"latitude\": 45.5041764,\n                        \"longitude\": -73.56834049999999,\n                        \"isFavorite\": false\n                    },\n                    \"finishedAt\": null,\n                    \"name\": \"Point A\"\n                },\n                {\n                    \"id\": \"044f137e-0a1f-49b8-bb36-247377c55dbe\",\n                    \"type\": \"place\",\n                    \"position\": 2,\n                    \"imageUrl\": null,\n                    \"place\": {\n                        \"id\": \"d2ac439a-1aa0-4edb-b889-2ecccb6c42c8\",\n                        \"address\": \"3901 Rue Bannantyne, Verdun, H4G 1C2\",\n                        \"latitude\": 45.4651011,\n                        \"longitude\": -73.5759264,\n                        \"isFavorite\": false\n                    },\n                    \"finishedAt\": null,\n                    \"name\": \"Point B\"\n                }\n            ],\n            \"notes\": [],\n            \"returnTrip\": null,\n            \"returnTripFor\": null,\n            \"createdBy\": {\n                \"id\": \"7b5f6ea6-7b3a-4437-838a-9a31994aacb3\",\n                \"firstName\": \"Edward\",\n                \"lastName\": \"Maxedon\",\n                \"phoneNumber\": \"514 699 7622\"\n            },\n            \"drivers\": [],\n            \"vehicle\": null,\n            \"confirmedBy\": null,\n            \"predictedDistance\": 8507,\n            \"actualDistance\": null,\n            \"predictedDuration\": 912,\n            \"zone\": null\n        }\n    ],\n    \"count\": 1\n}"}],"_postman_id":"4973aba8-2f41-424d-a540-6a424345d9d6"},{"name":"Trip Heatmaps","id":"59ffb3f3-b4fe-4a5d-8e39-3bb2d79588a1","request":{"method":"GET","header":[],"url":"{{hostname}}/v2/trips/heatmaps?startDate=2026-07-01T00:00:00.000Z&endDate=2026-07-31T23:59:59.000Z","description":"<p>Returns finished trips’ step coordinates for the given window, intended for rendering pickup/dropoff heatmaps. Accepts the same filters as <strong>List Trips History</strong> (minus pagination and sort).</p>\n<h4 id=\"response\">Response</h4>\n<p>Returns an array of trips, each with <code>scheduledAt</code>, <code>requestedAt</code>, and <code>steps[].place</code> (<code>latitude</code>, <code>longitude</code>, <code>address</code>).</p>\n","auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{apiKey}}"}]},"isInherited":true,"source":{"_postman_id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","name":"ShuttleControl Open API","type":"collection"}},"urlObject":{"path":["v2","trips","heatmaps"],"host":["{{hostname}}"],"query":[{"description":{"content":"<p>Required. ISO 8601; must be in the past.</p>\n","type":"text/plain"},"key":"startDate","value":"2026-07-01T00:00:00.000Z"},{"description":{"content":"<p>Required. ISO 8601.</p>\n","type":"text/plain"},"key":"endDate","value":"2026-07-31T23:59:59.000Z"},{"disabled":true,"description":{"content":"<p>Filter to one store.</p>\n","type":"text/plain"},"key":"storeId","value":""},{"disabled":true,"description":{"content":"<p>Filter by creating dispatcher.</p>\n","type":"text/plain"},"key":"dispatcherId","value":""},{"disabled":true,"description":{"content":"<p>Driver UUID or <code>UNASSIGNED</code>.</p>\n","type":"text/plain"},"key":"driverId","value":""},{"disabled":true,"description":{"content":"<p><code>COMPLETED</code> or <code>CANCELLED</code>. Default: both.</p>\n","type":"text/plain"},"key":"state","value":""},{"disabled":true,"description":{"content":"<p>Free-text search (max 100).</p>\n","type":"text/plain"},"key":"search","value":""},{"disabled":true,"description":{"content":"<p>Filter by workflow.</p>\n","type":"text/plain"},"key":"workflowId","value":""},{"disabled":true,"description":{"content":"<p>Filter by zone.</p>\n","type":"text/plain"},"key":"zoneId","value":""}],"variable":[]}},"response":[],"_postman_id":"59ffb3f3-b4fe-4a5d-8e39-3bb2d79588a1"},{"name":"Store Trip Analytics","id":"6b805ae7-afb0-4543-b53a-70e40f4df916","request":{"method":"GET","header":[],"url":"{{hostname}}/v2/trips/analytics/store?startDate=2026-07-01T00:00:00.000Z&endDate=2026-07-31T23:59:59.000Z&granularity=day&timezoneOffset=-240","description":"<p>Returns per-store trip-volume time series (bucketed by the chosen granularity) plus an aggregate, for the given window.</p>\n<h4 id=\"response\">Response</h4>\n<p>Returns <code>{ stores: [{ name, color, data }], aggregate }</code>.</p>\n","auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{apiKey}}"}]},"isInherited":true,"source":{"_postman_id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","name":"ShuttleControl Open API","type":"collection"}},"urlObject":{"path":["v2","trips","analytics","store"],"host":["{{hostname}}"],"query":[{"description":{"content":"<p>Required. ISO 8601 window start (matched on trip creation time).</p>\n","type":"text/plain"},"key":"startDate","value":"2026-07-01T00:00:00.000Z"},{"description":{"content":"<p>Required. ISO 8601 window end.</p>\n","type":"text/plain"},"key":"endDate","value":"2026-07-31T23:59:59.000Z"},{"description":{"content":"<p>Required. Bucket size: <code>day</code> | <code>week</code> | <code>month</code>.</p>\n","type":"text/plain"},"key":"granularity","value":"day"},{"description":{"content":"<p>Required. Caller’s UTC offset in minutes, used to align buckets to local days.</p>\n","type":"text/plain"},"key":"timezoneOffset","value":"-240"},{"disabled":true,"description":{"content":"<p>Filter to one store. Default: all visible stores.</p>\n","type":"text/plain"},"key":"storeId","value":""},{"disabled":true,"description":{"content":"<p>Filter by creating dispatcher.</p>\n","type":"text/plain"},"key":"dispatcherId","value":""},{"disabled":true,"description":{"content":"<p>Repeatable driver UUID filter.</p>\n","type":"text/plain"},"key":"driverIds","value":""},{"disabled":true,"description":{"content":"<p>Filter by workflow.</p>\n","type":"text/plain"},"key":"workflowId","value":""},{"disabled":true,"description":{"content":"<p><code>COMPLETED</code> or <code>CANCELLED</code>.</p>\n","type":"text/plain"},"key":"state","value":""}],"variable":[]}},"response":[],"_postman_id":"6b805ae7-afb0-4543-b53a-70e40f4df916"},{"name":"Driver Trip Analytics","id":"2433142c-c1fb-433c-b6ee-52379e7b189b","request":{"method":"GET","header":[],"url":"{{hostname}}/v2/trips/analytics/driver?startDate=2026-07-01T00:00:00.000Z&endDate=2026-07-31T23:59:59.000Z&granularity=day&timezoneOffset=-240","description":"<p>Returns per-driver trip-volume time series plus an aggregate, for the given window. Same parameters as <strong>Store Trip Analytics</strong>; when <code>driverIds</code> is omitted, every driver of the visible stores is included.</p>\n<h4 id=\"response\">Response</h4>\n<p>Returns <code>{ drivers: [{ name, data }], aggregate }</code>.</p>\n","auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{apiKey}}"}]},"isInherited":true,"source":{"_postman_id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","name":"ShuttleControl Open API","type":"collection"}},"urlObject":{"path":["v2","trips","analytics","driver"],"host":["{{hostname}}"],"query":[{"description":{"content":"<p>Required. ISO 8601 window start.</p>\n","type":"text/plain"},"key":"startDate","value":"2026-07-01T00:00:00.000Z"},{"description":{"content":"<p>Required. ISO 8601 window end.</p>\n","type":"text/plain"},"key":"endDate","value":"2026-07-31T23:59:59.000Z"},{"description":{"content":"<p>Required. <code>day</code> | <code>week</code> | <code>month</code>.</p>\n","type":"text/plain"},"key":"granularity","value":"day"},{"description":{"content":"<p>Required. Caller’s UTC offset in minutes.</p>\n","type":"text/plain"},"key":"timezoneOffset","value":"-240"},{"disabled":true,"description":{"content":"<p>Filter to one store.</p>\n","type":"text/plain"},"key":"storeId","value":""},{"disabled":true,"description":{"content":"<p>Filter by creating dispatcher.</p>\n","type":"text/plain"},"key":"dispatcherId","value":""},{"disabled":true,"description":{"content":"<p>Repeatable driver UUID filter. Default: all drivers.</p>\n","type":"text/plain"},"key":"driverIds","value":""},{"disabled":true,"description":{"content":"<p>Filter by workflow.</p>\n","type":"text/plain"},"key":"workflowId","value":""},{"disabled":true,"description":{"content":"<p><code>COMPLETED</code> or <code>CANCELLED</code>.</p>\n","type":"text/plain"},"key":"state","value":""}],"variable":[]}},"response":[],"_postman_id":"2433142c-c1fb-433c-b6ee-52379e7b189b"},{"name":"Make Trip Pending","id":"77218e63-38a0-40af-a01e-27729766ede4","request":{"method":"POST","header":[],"url":"{{hostname}}/v2/trips/:id/makePending","description":"<p>Moves a trip into the <code>PENDING</code> state (parked for later dispatch), unassigning it from active dispatch.</p>\n<h4 id=\"response\">Response</h4>\n<p>Responds <code>204 No Content</code>.</p>\n","auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{apiKey}}"}]},"isInherited":true,"source":{"_postman_id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","name":"ShuttleControl Open API","type":"collection"}},"urlObject":{"path":["v2","trips",":id","makePending"],"host":["{{hostname}}"],"query":[],"variable":[{"id":"a4f26f21-3237-496c-9186-e0672d893b7f","description":{"content":"<p>UUID of the trip.</p>\n","type":"text/plain"},"type":"any","value":"","key":"id"}]}},"response":[],"_postman_id":"77218e63-38a0-40af-a01e-27729766ede4"},{"name":"Create Trip Step Geostamp","id":"0ff8507a-6afd-47bb-9de1-e9be1f008bea","request":{"method":"POST","header":[],"body":{"mode":"raw","raw":"{\n  \"coords\": {\n    \"latitude\": 45.5019,\n    \"longitude\": -73.5674,\n    \"altitude\": 35,\n    \"accuracy\": 5,\n    \"altitude_accuracy\": 8,\n    \"heading\": 90,\n    \"speed\": 11.2\n  }\n}","options":{"raw":{"language":"json"}}},"url":"{{hostname}}/v2/trips/:id/steps/:stepId/geostamp","description":"<p>Records the trip vehicle’s GPS fix against a trip step (a “geostamp” proving where the step happened). The trip must have a vehicle assigned (<code>400</code> otherwise).</p>\n<h4 id=\"body-fields\">Body fields</h4>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Field</th>\n<th>Type</th>\n<th>Required</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>coords.latitude</code></td>\n<td>number</td>\n<td>Yes</td>\n<td>Latitude in decimal degrees.</td>\n</tr>\n<tr>\n<td><code>coords.longitude</code></td>\n<td>number</td>\n<td>Yes</td>\n<td>Longitude in decimal degrees.</td>\n</tr>\n<tr>\n<td><code>coords.altitude</code></td>\n<td>number</td>\n<td>Yes</td>\n<td>Altitude in meters.</td>\n</tr>\n<tr>\n<td><code>coords.accuracy</code></td>\n<td>number</td>\n<td>Yes</td>\n<td>Horizontal accuracy in meters.</td>\n</tr>\n<tr>\n<td><code>coords.altitude_accuracy</code></td>\n<td>number</td>\n<td>Yes</td>\n<td>Vertical accuracy in meters.</td>\n</tr>\n<tr>\n<td><code>coords.heading</code></td>\n<td>number</td>\n<td>Yes</td>\n<td>Heading in degrees.</td>\n</tr>\n<tr>\n<td><code>coords.speed</code></td>\n<td>number</td>\n<td>Yes</td>\n<td>Speed in m/s.</td>\n</tr>\n</tbody>\n</table>\n</div><h4 id=\"response\">Response</h4>\n<p>Responds <code>204 No Content</code>.</p>\n","auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{apiKey}}"}]},"isInherited":true,"source":{"_postman_id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","name":"ShuttleControl Open API","type":"collection"}},"urlObject":{"path":["v2","trips",":id","steps",":stepId","geostamp"],"host":["{{hostname}}"],"query":[],"variable":[{"id":"6e93fb82-47a6-43a9-8dfc-48da2897c24f","description":{"content":"<p>UUID of the trip.</p>\n","type":"text/plain"},"type":"any","value":"","key":"id"},{"id":"3e062adf-ed72-45d7-b1fb-69f93faf47ad","description":{"content":"<p>UUID of the trip step to stamp.</p>\n","type":"text/plain"},"type":"any","value":"","key":"stepId"}]}},"response":[],"_postman_id":"0ff8507a-6afd-47bb-9de1-e9be1f008bea"},{"name":"Download Trip PDF","id":"596be0fe-bff5-437f-99cb-b4542a0997c9","request":{"method":"GET","header":[],"url":"{{hostname}}/v2/trips/:id/pdf","description":"<p>Generates and returns a PDF summary of the trip (customer, steps, timestamps, signatures).</p>\n<h4 id=\"response\">Response</h4>\n<p>Returns the PDF binary with <code>Content-Type: application/pdf</code>.</p>\n","auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{apiKey}}"}]},"isInherited":true,"source":{"_postman_id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","name":"ShuttleControl Open API","type":"collection"}},"urlObject":{"path":["v2","trips",":id","pdf"],"host":["{{hostname}}"],"query":[],"variable":[{"id":"3a469311-f6f3-4623-b8ab-77e2138f9436","description":{"content":"<p>UUID of the trip.</p>\n","type":"text/plain"},"type":"any","value":"","key":"id"}]}},"response":[],"_postman_id":"596be0fe-bff5-437f-99cb-b4542a0997c9"}],"id":"725c983c-9187-4873-bafb-685d679d1f0d","description":"<p>Create and inspect trips. Trip states: <code>REQUESTED</code> (asap), <code>SCHEDULED</code> (for a specific time), <code>PENDING</code> (parked for later dispatch), <code>CONFIRMED</code> (accepted by a driver), <code>COMPLETED</code>, <code>CANCELLED</code>.</p>\n","_postman_id":"725c983c-9187-4873-bafb-685d679d1f0d","auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{apiKey}}"}]},"isInherited":true,"source":{"_postman_id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","name":"ShuttleControl Open API","type":"collection"}}},{"name":"Workflows","item":[{"name":"Create Workflow","id":"d4088dd2-5c07-4e24-99c1-a1437f5a1d59","request":{"method":"POST","header":[],"body":{"mode":"raw","raw":"{\n  \"workflowType\": \"SHUTTLE_PICKUP\",\n  \"storeId\": \"9f2d1c34-0000-0000-0000-000000000000\",\n  \"placeId\": \"5cd41a90-0000-0000-0000-000000000000\",\n  \"name\": \"Airport pickup\",\n  \"customerReviewsEnabled\": true,\n  \"schedulerStepSize\": 15,\n  \"defaultScheduledNotificationLeadTime\": 30\n}","options":{"raw":{"language":"json"}}},"url":"{{hostname}}/v2/workflows","description":"<p>Creates a workflow. The shape of the body depends on <code>workflowType</code>:</p>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>workflowType</th>\n<th>Notes</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>CUSTOM</code></td>\n<td><code>name</code> is <strong>required</strong>; the workflow starts with no steps (add them in-app).</td>\n</tr>\n<tr>\n<td><code>TASK</code></td>\n<td>An internal task workflow; no customer or place needed.</td>\n</tr>\n<tr>\n<td><code>SHUTTLE_PICKUP</code> / <code>SHUTTLE_DROPOFF</code> / <code>VALET_PICKUP</code> / <code>VALET_DROPOFF</code></td>\n<td>Pre-built templates; <code>placeId</code> is <strong>required</strong> (the store-side place). <code>VALET_DROPOFF</code> also <strong>requires</strong> <code>messageTemplateId</code>.</td>\n</tr>\n<tr>\n<td><code>PART_PICKUP</code> / <code>PART_DELIVERY</code></td>\n<td>Pre-built delivery templates; <code>placeId</code> is <strong>required</strong>.</td>\n</tr>\n</tbody>\n</table>\n</div><p>When <code>emailRequired</code> / <code>phoneNumberRequired</code> are omitted, defaults depend on the account country: North American accounts default to phone-number-required, others to email-required.</p>\n<p><strong>Required role:</strong> <code>ADMIN</code> or higher. An account API key always satisfies this (it authenticates as the account owner).</p>\n<h4 id=\"body-fields\">Body fields</h4>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Field</th>\n<th>Type</th>\n<th>Required</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>workflowType</code></td>\n<td>string</td>\n<td>Yes</td>\n<td><code>CUSTOM</code></td>\n</tr>\n<tr>\n<td><code>storeId</code></td>\n<td>string (UUID)</td>\n<td>Yes</td>\n<td>The store the workflow belongs to.</td>\n</tr>\n<tr>\n<td><code>name</code></td>\n<td>string</td>\n<td>Conditional</td>\n<td>Workflow name, 1–100 characters. Required for <code>CUSTOM</code>; optional for template types (a default name is used).</td>\n</tr>\n<tr>\n<td><code>placeId</code></td>\n<td>string (UUID)</td>\n<td>Conditional</td>\n<td>Store-side place for the template’s place step. Required for shuttle/valet/part types.</td>\n</tr>\n<tr>\n<td><code>messageTemplateId</code></td>\n<td>string (UUID)</td>\n<td>Conditional</td>\n<td>Message template for the workflow’s message step. Required for <code>VALET_DROPOFF</code>.</td>\n</tr>\n<tr>\n<td><code>description</code></td>\n<td>string</td>\n<td>No</td>\n<td>Max 100 characters. Default <code>\"\"</code>.</td>\n</tr>\n<tr>\n<td><code>customerRequired</code></td>\n<td>boolean</td>\n<td>No</td>\n<td>Whether a customer must be attached to trips. Default <code>true</code>.</td>\n</tr>\n<tr>\n<td><code>emailRequired</code></td>\n<td>boolean</td>\n<td>No</td>\n<td>Whether the customer email is mandatory. Default: country-based (see above).</td>\n</tr>\n<tr>\n<td><code>phoneNumberRequired</code></td>\n<td>boolean</td>\n<td>No</td>\n<td>Whether the customer phone is mandatory. Default: country-based.</td>\n</tr>\n<tr>\n<td><code>companyNameRequired</code></td>\n<td>boolean</td>\n<td>No</td>\n<td>Whether a company name is mandatory. Default <code>false</code>.</td>\n</tr>\n<tr>\n<td><code>customerReviewsEnabled</code></td>\n<td>boolean</td>\n<td>No</td>\n<td>Ask customers for a review after completion. Default <code>true</code>.</td>\n</tr>\n<tr>\n<td><code>customerCancellationEnabled</code></td>\n<td>boolean</td>\n<td>No</td>\n<td>Let customers cancel from the tracking page. Default <code>false</code>.</td>\n</tr>\n<tr>\n<td><code>schedulerStepSize</code></td>\n<td>number</td>\n<td>No</td>\n<td>Scheduling picker granularity in minutes, 5–30. Default <code>15</code>.</td>\n</tr>\n<tr>\n<td><code>defaultScheduledNotificationLeadTime</code></td>\n<td>number</td>\n<td>No</td>\n<td>Minutes before a scheduled trip to notify, 0–60. Default <code>30</code>.</td>\n</tr>\n<tr>\n<td><code>maximumScheduledAtDays</code></td>\n<td>number</td>\n<td>No</td>\n<td>How many days ahead trips may be scheduled, 0–365 (<code>0</code> = unlimited). Default <code>0</code>.</td>\n</tr>\n<tr>\n<td><code>allowActivateByDriver</code></td>\n<td>boolean</td>\n<td>No</td>\n<td>Whether drivers can activate pending trips themselves. Default <code>true</code>.</td>\n</tr>\n<tr>\n<td><code>rideshareEnabled</code></td>\n<td>boolean</td>\n<td>No</td>\n<td>Whether trips on this workflow can be combined into rideshares. Default <code>true</code>.</td>\n</tr>\n<tr>\n<td><code>scheduledTripMessageTemplateId</code></td>\n<td>string (UUID)</td>\n<td>null</td>\n<td>No</td>\n</tr>\n<tr>\n<td><code>requestedTripMessageTemplateId</code></td>\n<td>string (UUID)</td>\n<td>null</td>\n<td>No</td>\n</tr>\n<tr>\n<td><code>cancelledTripMessageTemplateId</code></td>\n<td>string (UUID)</td>\n<td>null</td>\n<td>No</td>\n</tr>\n<tr>\n<td><code>pendingTripMessageTemplateId</code></td>\n<td>string (UUID)</td>\n<td>null</td>\n<td>No</td>\n</tr>\n<tr>\n<td><code>confirmedTripMessageTemplateId</code></td>\n<td>string (UUID)</td>\n<td>null</td>\n<td>No</td>\n</tr>\n</tbody>\n</table>\n</div><h4 id=\"response\">Response</h4>\n<p>Responds <code>201</code> with the created workflow (including its generated steps for template types).</p>\n","auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{apiKey}}"}]},"isInherited":true,"source":{"_postman_id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","name":"ShuttleControl Open API","type":"collection"}},"urlObject":{"path":["v2","workflows"],"host":["{{hostname}}"],"query":[],"variable":[]}},"response":[{"id":"53254968-25c0-4616-aa9f-1e0aa29ed871","name":"Create Workflow response","originalRequest":{"method":"POST","header":[],"body":{"mode":"raw","raw":"{\n    \"storeId\": \"\",\n    \"name\": \"Shuttle Pickup\",\n    \"description\": \"To bring the customer to the store.\",\n    \"customerRequired\": true,\n    \"emailRequired\": false,\n    \"companyNameRequired\": false,\n    \"enableScheduledTripSms\": true,\n    \"customerReviewsEnabled\": false,\n    \"phoneNumberRequired\": true,\n    \"tripOptimizationHeuristic\": \"MINIMIZE_DURATION\"\n}","options":{"raw":{"language":"json"}}},"url":"{{hostname}}/v2/workflows"},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"content-length","value":"561"},{"key":"content-type","value":"application/json; charset=utf-8"}],"cookie":[],"responseTime":null,"body":"{\n    \"tripOptimizationHeuristic\": \"MINIMIZE_DURATION\",\n    \"description\": \"To bring the customer to the store.\",\n    \"enableScheduledTripSms\": true,\n    \"enabled\": true,\n    \"store\": \"f1a04c8a-dc36-4203-9a9e-698e06cf7cef\",\n    \"id\": \"117c7103-275e-4a18-ba2a-0556331fc408\",\n    \"defaultReturnTripWorkflow\": null,\n    \"customerRequired\": true,\n    \"steps\": [],\n    \"phoneNumberRequired\": true,\n    \"companyNameRequired\": false,\n    \"customerReviewsEnabled\": false,\n    \"name\": \"Shuttle Pickup\",\n    \"updatedAt\": null,\n    \"createdAt\": \"2023-03-14T15:30:01.534Z\",\n    \"createdBy\": \"7b5f6ea6-7b3a-4437-838a-9a31994aacb3\",\n    \"updatedBy\": null,\n    \"emailRequired\": false\n}"}],"_postman_id":"d4088dd2-5c07-4e24-99c1-a1437f5a1d59"},{"name":"List Workflows","id":"a21394af-eb20-4a17-a023-886ad3c5eb19","request":{"method":"GET","header":[],"url":"{{hostname}}/v2/workflows/list?page=0&size=10","description":"<p>Returns a paginated list of active workflows for the caller’s stores, including their notification template assignments.</p>\n<h4 id=\"response\">Response</h4>\n<p>Returns <code>{ items, count }</code>.</p>\n","auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{apiKey}}"}]},"isInherited":true,"source":{"_postman_id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","name":"ShuttleControl Open API","type":"collection"}},"urlObject":{"path":["v2","workflows","list"],"host":["{{hostname}}"],"query":[{"description":{"content":"<p>Zero-based page index. Default <code>0</code>.</p>\n","type":"text/plain"},"key":"page","value":"0"},{"description":{"content":"<p>Page size, 1–100. Default <code>10</code>.</p>\n","type":"text/plain"},"key":"size","value":"10"},{"disabled":true,"description":{"content":"<p>Filter to one store (must be visible to the caller).</p>\n","type":"text/plain"},"key":"storeId","value":""}],"variable":[]}},"response":[{"id":"f95dabb4-e324-44ef-af8b-01479084d49e","name":"List Workflows response","originalRequest":{"method":"GET","header":[],"url":{"raw":"{{hostname}}/v2/workflows/list?page=0&size=5","host":["{{hostname}}"],"path":["v2","workflows","list"],"query":[{"key":"page","value":"0"},{"key":"size","value":"5"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"content-type","value":"application/json; charset=utf-8"}],"cookie":[],"responseTime":null,"body":"{\n    \"items\": [\n        {\n            \"id\": \"c1885ec0-f5cf-4922-a294-741911257065\",\n            \"name\": \"Shuttle Drop-off\",\n            \"description\": \"\",\n            \"defaultReturnTripWorkflow\": {\n                \"id\": \"a8e2c634-0ab4-46f6-85dc-ada9cda81331\",\n                \"name\": \"Shuttle Pickup\"\n            },\n            \"store\": {\n                \"id\": \"f1a04c8a-dc36-4203-9a9e-698e06cf7cef\",\n                \"name\": \"Alpha Store\"\n            },\n            \"createdAt\": \"2023-03-13T18:05:39.920Z\"\n        },\n        {\n            \"id\": \"a8e2c634-0ab4-46f6-85dc-ada9cda81331\",\n            \"name\": \"Shuttle Pickup\",\n            \"description\": \"\",\n            \"defaultReturnTripWorkflow\": {\n                \"id\": \"c1885ec0-f5cf-4922-a294-741911257065\",\n                \"name\": \"Shuttle Drop-off\"\n            },\n            \"store\": {\n                \"id\": \"f1a04c8a-dc36-4203-9a9e-698e06cf7cef\",\n                \"name\": \"Alpha Store\"\n            },\n            \"createdAt\": \"2023-03-13T18:05:39.936Z\"\n        },\n        {\n            \"id\": \"28d88bad-9128-42ba-a5c7-a94ba35b20c2\",\n            \"name\": \"Part Delivery\",\n            \"description\": \"\",\n            \"defaultReturnTripWorkflow\": null,\n            \"store\": {\n                \"id\": \"f1a04c8a-dc36-4203-9a9e-698e06cf7cef\",\n                \"name\": \"Alpha Store\"\n            },\n            \"createdAt\": \"2023-03-13T18:05:39.951Z\"\n        },\n        {\n            \"id\": \"3f3f90af-705e-4673-96c8-b93b6b271085\",\n            \"name\": \"Part Pickup\",\n            \"description\": \"\",\n            \"defaultReturnTripWorkflow\": null,\n            \"store\": {\n                \"id\": \"f1a04c8a-dc36-4203-9a9e-698e06cf7cef\",\n                \"name\": \"Alpha Store\"\n            },\n            \"createdAt\": \"2023-03-13T18:05:39.959Z\"\n        },\n        {\n            \"id\": \"ae2e1537-b365-415e-b5f7-13f7f9327c55\",\n            \"name\": \"Valet Pickup\",\n            \"description\": \"\",\n            \"defaultReturnTripWorkflow\": {\n                \"id\": \"ab24e1a9-e8bc-4796-a511-a03dc4afecda\",\n                \"name\": \"Valet Drop-off\"\n            },\n            \"store\": {\n                \"id\": \"f1a04c8a-dc36-4203-9a9e-698e06cf7cef\",\n                \"name\": \"Alpha Store\"\n            },\n            \"createdAt\": \"2023-03-13T18:05:39.966Z\"\n        }\n    ],\n    \"count\": 16\n}"}],"_postman_id":"a21394af-eb20-4a17-a023-886ad3c5eb19"},{"name":"List All Workflows","id":"28491bed-6e2a-4d16-8e3a-e8a291b0a6e9","request":{"method":"GET","header":[],"url":"{{hostname}}/v2/workflows","description":"<p>Returns all active workflows <strong>that have at least one step</strong>, grouped by store — the set a trip can actually be created against.</p>\n<h4 id=\"response\">Response</h4>\n<p>Returns an array of stores, each with <code>id</code>, <code>name</code>, and <code>workflows</code> (id, name, description, color, <code>allowActivateByDriver</code>, <code>defaultReturnTripWorkflow</code>).</p>\n","auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{apiKey}}"}]},"isInherited":true,"source":{"_postman_id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","name":"ShuttleControl Open API","type":"collection"}},"urlObject":{"path":["v2","workflows"],"host":["{{hostname}}"],"query":[{"disabled":true,"description":{"content":"<p>Repeatable UUID filter. Default: all stores visible to the caller.</p>\n","type":"text/plain"},"key":"storeIds","value":""}],"variable":[]}},"response":[{"id":"063a34c1-fcc7-4f03-9792-ecb02e0a86ca","name":"List All Workflows response","originalRequest":{"method":"GET","header":[],"url":"{{hostname}}/v2/workflows"},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Access-Control-Allow-Origin","value":"*"},{"key":"Content-Security-Policy","value":"default-src 'self';base-uri 'self';font-src 'self' https: data:;form-action 'self';frame-ancestors 'self';img-src 'self' data:;object-src 'none';script-src 'self';script-src-attr 'none';style-src 'self' https: 'unsafe-inline';upgrade-insecure-requests"},{"key":"Cross-Origin-Embedder-Policy","value":"require-corp"},{"key":"Cross-Origin-Opener-Policy","value":"same-origin"},{"key":"X-DNS-Prefetch-Control","value":"off"},{"key":"X-Frame-Options","value":"SAMEORIGIN"},{"key":"Strict-Transport-Security","value":"max-age=15552000; includeSubDomains"},{"key":"X-Download-Options","value":"noopen"},{"key":"X-Content-Type-Options","value":"nosniff"},{"key":"Origin-Agent-Cluster","value":"?1"},{"key":"X-Permitted-Cross-Domain-Policies","value":"none"},{"key":"Referrer-Policy","value":"no-referrer"},{"key":"X-XSS-Protection","value":"0"},{"key":"Content-Type","value":"application/json; charset=utf-8"},{"key":"ETag","value":"W/\"1081-lGYexp0wPPrLQT16mMWXhxEBgIU\""},{"key":"Vary","value":"Accept-Encoding"},{"key":"Content-Encoding","value":"gzip"},{"key":"Date","value":"Tue, 02 Apr 2024 17:39:18 GMT"},{"key":"Connection","value":"keep-alive"},{"key":"Keep-Alive","value":"timeout=5"},{"key":"Transfer-Encoding","value":"chunked"}],"cookie":[],"responseTime":null,"body":"[\n    {\n        \"id\": \"e81f65c4-5cf7-4339-b6f8-437bc9cd42b7\",\n        \"name\": \"Alpha Store\",\n        \"workflows\": [\n            {\n                \"id\": \"f3cb7fdf-9802-491c-bb5c-2e1d55520524\",\n                \"name\": \"Shuttle Drop-off\",\n                \"kioskEnabled\": false,\n                \"description\": \"\",\n                \"defaultReturnTripWorkflow\": {\n                    \"id\": \"32bf654e-ce9b-49a2-a11b-f58e266559cc\",\n                    \"name\": \"Shuttle Pickup\"\n                },\n                \"store\": {\n                    \"id\": \"e81f65c4-5cf7-4339-b6f8-437bc9cd42b7\",\n                    \"name\": \"Alpha Store\"\n                },\n                \"createdAt\": \"2024-03-14T19:06:04.376Z\"\n            },\n            {\n                \"id\": \"32bf654e-ce9b-49a2-a11b-f58e266559cc\",\n                \"name\": \"Shuttle Pickup\",\n                \"kioskEnabled\": false,\n                \"description\": \"\",\n                \"defaultReturnTripWorkflow\": {\n                    \"id\": \"f3cb7fdf-9802-491c-bb5c-2e1d55520524\",\n                    \"name\": \"Shuttle Drop-off\"\n                },\n                \"store\": {\n                    \"id\": \"e81f65c4-5cf7-4339-b6f8-437bc9cd42b7\",\n                    \"name\": \"Alpha Store\"\n                },\n                \"createdAt\": \"2024-03-14T19:06:04.420Z\"\n            },\n            {\n                \"id\": \"9ef2ebc1-ec03-4802-ad94-eb0d389b033c\",\n                \"name\": \"Part Delivery\",\n                \"kioskEnabled\": false,\n                \"description\": \"\",\n                \"defaultReturnTripWorkflow\": null,\n                \"store\": {\n                    \"id\": \"e81f65c4-5cf7-4339-b6f8-437bc9cd42b7\",\n                    \"name\": \"Alpha Store\"\n                },\n                \"createdAt\": \"2024-03-14T19:06:04.449Z\"\n            },\n            {\n                \"id\": \"2db32e36-38c4-415b-888a-5e6732732b82\",\n                \"name\": \"Part Pickup\",\n                \"kioskEnabled\": false,\n                \"description\": \"\",\n                \"defaultReturnTripWorkflow\": null,\n                \"store\": {\n                    \"id\": \"e81f65c4-5cf7-4339-b6f8-437bc9cd42b7\",\n                    \"name\": \"Alpha Store\"\n                },\n                \"createdAt\": \"2024-03-14T19:06:04.470Z\"\n            },\n            {\n                \"id\": \"cba24cf8-fa71-4bb7-b344-dc31f0d0cae7\",\n                \"name\": \"Valet Pickup\",\n                \"kioskEnabled\": false,\n                \"description\": \"\",\n                \"defaultReturnTripWorkflow\": {\n                    \"id\": \"d9416fde-d95c-4ce0-b469-f14b327a9ff2\",\n                    \"name\": \"Valet Drop-off\"\n                },\n                \"store\": {\n                    \"id\": \"e81f65c4-5cf7-4339-b6f8-437bc9cd42b7\",\n                    \"name\": \"Alpha Store\"\n                },\n                \"createdAt\": \"2024-03-14T19:06:04.487Z\"\n            },\n            {\n                \"id\": \"d9416fde-d95c-4ce0-b469-f14b327a9ff2\",\n                \"name\": \"Valet Drop-off\",\n                \"kioskEnabled\": false,\n                \"description\": \"\",\n                \"defaultReturnTripWorkflow\": {\n                    \"id\": \"cba24cf8-fa71-4bb7-b344-dc31f0d0cae7\",\n                    \"name\": \"Valet Pickup\"\n                },\n                \"store\": {\n                    \"id\": \"e81f65c4-5cf7-4339-b6f8-437bc9cd42b7\",\n                    \"name\": \"Alpha Store\"\n                },\n                \"createdAt\": \"2024-03-14T19:06:04.509Z\"\n            },\n            {\n                \"id\": \"b77fee16-89e8-4c97-a560-920aa637b13c\",\n                \"name\": \"Task\",\n                \"kioskEnabled\": false,\n                \"description\": \"\",\n                \"defaultReturnTripWorkflow\": null,\n                \"store\": {\n                    \"id\": \"e81f65c4-5cf7-4339-b6f8-437bc9cd42b7\",\n                    \"name\": \"Alpha Store\"\n                },\n                \"createdAt\": \"2024-03-14T19:06:04.534Z\"\n            }\n        ]\n    },\n    {\n        \"id\": \"487a1223-7300-4001-ba1f-086f5a0b12a6\",\n        \"name\": \"Bravo Store\",\n        \"workflows\": [\n            {\n                \"id\": \"a205af77-9195-451e-b3ce-f22c5d5016de\",\n                \"name\": \"Shuttle Drop-off\",\n                \"kioskEnabled\": false,\n                \"description\": \"\",\n                \"defaultReturnTripWorkflow\": {\n                    \"id\": \"b3b18080-37f9-4e88-a1fd-2d975d0fdae1\",\n                    \"name\": \"Shuttle Pickup\"\n                },\n                \"store\": {\n                    \"id\": \"487a1223-7300-4001-ba1f-086f5a0b12a6\",\n                    \"name\": \"Bravo Store\"\n                },\n                \"createdAt\": \"2024-03-14T19:06:04.564Z\"\n            },\n            {\n                \"id\": \"b3b18080-37f9-4e88-a1fd-2d975d0fdae1\",\n                \"name\": \"Shuttle Pickup\",\n                \"kioskEnabled\": false,\n                \"description\": \"\",\n                \"defaultReturnTripWorkflow\": {\n                    \"id\": \"a205af77-9195-451e-b3ce-f22c5d5016de\",\n                    \"name\": \"Shuttle Drop-off\"\n                },\n                \"store\": {\n                    \"id\": \"487a1223-7300-4001-ba1f-086f5a0b12a6\",\n                    \"name\": \"Bravo Store\"\n                },\n                \"createdAt\": \"2024-03-14T19:06:04.585Z\"\n            },\n            {\n                \"id\": \"667de300-da5f-4d4f-bdb2-482761f813b6\",\n                \"name\": \"Part Delivery\",\n                \"kioskEnabled\": false,\n                \"description\": \"\",\n                \"defaultReturnTripWorkflow\": null,\n                \"store\": {\n                    \"id\": \"487a1223-7300-4001-ba1f-086f5a0b12a6\",\n                    \"name\": \"Bravo Store\"\n                },\n                \"createdAt\": \"2024-03-14T19:06:04.610Z\"\n            },\n            {\n                \"id\": \"a0bb0bf2-5bf4-4635-95f0-3a88a7808e88\",\n                \"name\": \"Part Pickup\",\n                \"kioskEnabled\": false,\n                \"description\": \"\",\n                \"defaultReturnTripWorkflow\": null,\n                \"store\": {\n                    \"id\": \"487a1223-7300-4001-ba1f-086f5a0b12a6\",\n                    \"name\": \"Bravo Store\"\n                },\n                \"createdAt\": \"2024-03-14T19:06:04.625Z\"\n            },\n            {\n                \"id\": \"df33d31c-c0ec-4718-95ab-d6515cfd9cdc\",\n                \"name\": \"Valet Pickup\",\n                \"kioskEnabled\": false,\n                \"description\": \"\",\n                \"defaultReturnTripWorkflow\": {\n                    \"id\": \"9220bfc1-fb28-4004-9e9f-09a598252a7a\",\n                    \"name\": \"Valet Drop-off\"\n                },\n                \"store\": {\n                    \"id\": \"487a1223-7300-4001-ba1f-086f5a0b12a6\",\n                    \"name\": \"Bravo Store\"\n                },\n                \"createdAt\": \"2024-03-14T19:06:04.645Z\"\n            },\n            {\n                \"id\": \"9220bfc1-fb28-4004-9e9f-09a598252a7a\",\n                \"name\": \"Valet Drop-off\",\n                \"kioskEnabled\": false,\n                \"description\": \"\",\n                \"defaultReturnTripWorkflow\": {\n                    \"id\": \"df33d31c-c0ec-4718-95ab-d6515cfd9cdc\",\n                    \"name\": \"Valet Pickup\"\n                },\n                \"store\": {\n                    \"id\": \"487a1223-7300-4001-ba1f-086f5a0b12a6\",\n                    \"name\": \"Bravo Store\"\n                },\n                \"createdAt\": \"2024-03-14T19:06:04.666Z\"\n            },\n            {\n                \"id\": \"61148baf-ec7b-4b72-8f75-00281f1d2912\",\n                \"name\": \"Task\",\n                \"kioskEnabled\": false,\n                \"description\": \"\",\n                \"defaultReturnTripWorkflow\": null,\n                \"store\": {\n                    \"id\": \"487a1223-7300-4001-ba1f-086f5a0b12a6\",\n                    \"name\": \"Bravo Store\"\n                },\n                \"createdAt\": \"2024-03-14T19:06:04.690Z\"\n            }\n        ]\n    }\n]"}],"_postman_id":"28491bed-6e2a-4d16-8e3a-e8a291b0a6e9"},{"name":"Get Workflow","id":"5e487c1e-84bb-4abc-ad6c-32e53dde4c16","request":{"method":"GET","header":[],"url":"{{hostname}}/v2/workflows/:id","description":"<p>Returns a single workflow with its steps and settings.</p>\n<h4 id=\"response\">Response</h4>\n<p>Returns the workflow object, plus <code>isUsedAsReturnTripWorkflow</code> (boolean) indicating whether another workflow uses it as its default return-trip workflow.</p>\n","auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{apiKey}}"}]},"isInherited":true,"source":{"_postman_id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","name":"ShuttleControl Open API","type":"collection"}},"urlObject":{"path":["v2","workflows",":id"],"host":["{{hostname}}"],"query":[],"variable":[{"id":"51a6249a-18eb-4433-abae-595e4af0d487","description":{"content":"<p>UUID of the workflow.</p>\n","type":"text/plain"},"type":"any","value":"","key":"id"}]}},"response":[{"id":"3cc77cce-f561-4e70-b73b-826407f2c887","name":"Get Workflow response","originalRequest":{"method":"GET","header":[],"url":"{{hostname}}/v2/workflows/"},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"content-type","value":"application/json; charset=utf-8"}],"cookie":[],"responseTime":null,"body":"{\n    \"id\": \"a8e2c634-0ab4-46f6-85dc-ada9cda81331\",\n    \"name\": \"Shuttle Pickup\",\n    \"description\": \"\",\n    \"enabled\": true,\n    \"customerReviewsEnabled\": false,\n    \"customerRequired\": true,\n    \"emailRequired\": false,\n    \"companyNameRequired\": false,\n    \"phoneNumberRequired\": true,\n    \"enableScheduledTripSms\": true,\n    \"tripOptimizationHeuristic\": \"MINIMIZE_DURATION\",\n    \"defaultReturnTripWorkflow\": {\n        \"id\": \"c1885ec0-f5cf-4922-a294-741911257065\"\n    },\n    \"store\": {\n        \"id\": \"f1a04c8a-dc36-4203-9a9e-698e06cf7cef\",\n        \"name\": \"Alpha Store\",\n        \"place\": {\n            \"id\": \"c60c1e2c-e3af-4e6b-8917-45023225488f\",\n            \"address\": \"Saint Joseph's Oratory of Mount Royal\",\n            \"latitude\": 45.4919122,\n            \"longitude\": -73.6186555\n        }\n    },\n    \"steps\": [\n        {\n            \"id\": \"ba58ad87-a5b7-49ab-bf22-fd0ebe87c1b8\",\n            \"type\": \"message\",\n            \"name\": \"Send tracking link\",\n            \"place\": null,\n            \"position\": 1,\n            \"messageTemplate\": {\n                \"id\": \"c8bbb1cd-7c53-42fa-9f8f-595b313b94ee\",\n                \"name\": \"Send Tracking Link\",\n                \"type\": \"SMS\",\n                \"locales\": [\n                    {\n                        \"language\": \"en\",\n                        \"template\": \"Hi {{{customerName}}}, your driver is on the way! Track your driver: {{{trackingLink}}}\"\n                    },\n                    {\n                        \"language\": \"fr\",\n                        \"template\": \"Bonjour {{{customerName}}}, votre chauffeur est on route! {{{trackingLink}}}\"\n                    }\n                ]\n            },\n            \"createdAt\": \"2023-03-13T18:05:39.941Z\",\n            \"createdBy\": {\n                \"id\": \"7b5f6ea6-7b3a-4437-838a-9a31994aacb3\",\n                \"firstName\": \"Edward\",\n                \"lastName\": \"Maxedon\"\n            },\n            \"updatedAt\": null,\n            \"updatedBy\": null\n        },\n        {\n            \"id\": \"ca88a4d3-9813-469e-916a-fe61f6d669e0\",\n            \"type\": \"place\",\n            \"name\": \"Pickup customer\",\n            \"place\": null,\n            \"position\": 2,\n            \"messageTemplate\": null,\n            \"createdAt\": \"2023-03-13T18:05:39.944Z\",\n            \"createdBy\": {\n                \"id\": \"7b5f6ea6-7b3a-4437-838a-9a31994aacb3\",\n                \"firstName\": \"Edward\",\n                \"lastName\": \"Maxedon\"\n            },\n            \"updatedAt\": null,\n            \"updatedBy\": null\n        },\n        {\n            \"id\": \"3b80e7bb-85fe-452e-bc9f-e1d7256a12be\",\n            \"type\": \"place\",\n            \"name\": \"Bring customer to store\",\n            \"place\": {\n                \"id\": \"c60c1e2c-e3af-4e6b-8917-45023225488f\",\n                \"address\": \"Saint Joseph's Oratory of Mount Royal\",\n                \"latitude\": 45.4919122,\n                \"longitude\": -73.6186555\n            },\n            \"position\": 3,\n            \"messageTemplate\": null,\n            \"createdAt\": \"2023-03-13T18:05:39.947Z\",\n            \"createdBy\": {\n                \"id\": \"7b5f6ea6-7b3a-4437-838a-9a31994aacb3\",\n                \"firstName\": \"Edward\",\n                \"lastName\": \"Maxedon\"\n            },\n            \"updatedAt\": null,\n            \"updatedBy\": null\n        }\n    ],\n    \"createdAt\": \"2023-03-13T18:05:39.936Z\",\n    \"createdBy\": {\n        \"id\": \"7b5f6ea6-7b3a-4437-838a-9a31994aacb3\",\n        \"firstName\": \"Edward\",\n        \"lastName\": \"Maxedon\"\n    },\n    \"updatedAt\": null,\n    \"updatedBy\": null\n}"}],"_postman_id":"5e487c1e-84bb-4abc-ad6c-32e53dde4c16"},{"name":"Update Workflow","id":"2957e14d-303d-40f8-90ad-483936e87bd0","request":{"method":"PATCH","header":[],"body":{"mode":"raw","raw":"{\n  \"name\": \"Airport pickup\",\n  \"customerReviewsEnabled\": true,\n  \"maximumScheduledAtDays\": 30\n}","options":{"raw":{"language":"json"}}},"url":"{{hostname}}/v2/workflows/:id","description":"<p>Partially updates a workflow’s settings. All fields are optional — only the fields present are changed.</p>\n<p><strong>Required role:</strong> <code>ADMIN</code> or higher. An account API key always satisfies this (it authenticates as the account owner).</p>\n<h4 id=\"body-fields\">Body fields</h4>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Field</th>\n<th>Type</th>\n<th>Required</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>name</code></td>\n<td>string</td>\n<td>No</td>\n<td>Max 100 characters.</td>\n</tr>\n<tr>\n<td><code>description</code></td>\n<td>string</td>\n<td>No</td>\n<td>Max 100 characters.</td>\n</tr>\n<tr>\n<td><code>color</code></td>\n<td>string</td>\n<td>No</td>\n<td>Display color (hex).</td>\n</tr>\n<tr>\n<td><code>customerRequired</code></td>\n<td>boolean</td>\n<td>No</td>\n<td>Whether a customer must be attached to trips.</td>\n</tr>\n<tr>\n<td><code>emailRequired</code></td>\n<td>boolean</td>\n<td>No</td>\n<td>Whether the customer email is mandatory.</td>\n</tr>\n<tr>\n<td><code>phoneNumberRequired</code></td>\n<td>boolean</td>\n<td>No</td>\n<td>Whether the customer phone is mandatory.</td>\n</tr>\n<tr>\n<td><code>companyNameRequired</code></td>\n<td>boolean</td>\n<td>No</td>\n<td>Whether a company name is mandatory.</td>\n</tr>\n<tr>\n<td><code>customerReviewsEnabled</code></td>\n<td>boolean</td>\n<td>No</td>\n<td>Ask customers for a review after completion.</td>\n</tr>\n<tr>\n<td><code>customerCancellationEnabled</code></td>\n<td>boolean</td>\n<td>No</td>\n<td>Let customers cancel from the tracking page.</td>\n</tr>\n<tr>\n<td><code>defaultReturnTripWorkflow</code></td>\n<td>string (UUID)</td>\n<td>null</td>\n<td>No</td>\n</tr>\n<tr>\n<td><code>schedulerStepSize</code></td>\n<td>number</td>\n<td>No</td>\n<td>5–30 minutes.</td>\n</tr>\n<tr>\n<td><code>defaultScheduledNotificationLeadTime</code></td>\n<td>number</td>\n<td>No</td>\n<td>0–60 minutes.</td>\n</tr>\n<tr>\n<td><code>maximumScheduledAtDays</code></td>\n<td>number</td>\n<td>No</td>\n<td>0–365 days (<code>0</code> = unlimited).</td>\n</tr>\n<tr>\n<td><code>allowActivateByDriver</code></td>\n<td>boolean</td>\n<td>No</td>\n<td>Whether drivers can activate pending trips.</td>\n</tr>\n<tr>\n<td><code>rideshareEnabled</code></td>\n<td>boolean</td>\n<td>No</td>\n<td>Whether trips can be combined into rideshares.</td>\n</tr>\n<tr>\n<td><code>chatEnabled</code></td>\n<td>boolean</td>\n<td>No</td>\n<td>Whether customer↔driver chat is enabled on trips.</td>\n</tr>\n</tbody>\n</table>\n</div><h4 id=\"response\">Response</h4>\n<p>Returns the updated workflow object.</p>\n","auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{apiKey}}"}]},"isInherited":true,"source":{"_postman_id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","name":"ShuttleControl Open API","type":"collection"}},"urlObject":{"path":["v2","workflows",":id"],"host":["{{hostname}}"],"query":[],"variable":[{"id":"4ea89310-4d71-4229-a166-8c65f648871b","description":{"content":"<p>UUID of the workflow.</p>\n","type":"text/plain"},"type":"any","value":"","key":"id"}]}},"response":[{"id":"c2beeaab-5719-4b6b-9d19-30a13e60463d","name":"Update Workflow response","originalRequest":{"method":"PUT","header":[],"body":{"mode":"raw","raw":"{\n    \"name\": \"Shuttle Pickup\",\n    \"description\": \"To bring the customer to the store.\",\n    \"customerRequired\": true,\n    \"emailRequired\": false,\n    \"defaultReturnTripWorkflow\": null,\n    \"enableScheduledTripSms\": true,\n    \"customerReviewsEnabled\": true,\n    \"phoneNumberRequired\": true,\n    \"tripOptimizationHeuristic\": \"MINIMIZE_DURATION\"\n}","options":{"raw":{"language":"json"}}},"url":"{{hostname}}/v2/workflows/"},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"content-length","value":"425"},{"key":"content-type","value":"application/json; charset=utf-8"}],"cookie":[],"responseTime":null,"body":"{\n    \"tripOptimizationHeuristic\": \"MINIMIZE_DURATION\",\n    \"description\": \"To bring the customer to the store.\",\n    \"enableScheduledTripSms\": true,\n    \"id\": \"117c7103-275e-4a18-ba2a-0556331fc408\",\n    \"defaultReturnTripWorkflow\": null,\n    \"customerRequired\": true,\n    \"phoneNumberRequired\": true,\n    \"customerReviewsEnabled\": true,\n    \"name\": \"Shuttle Pickup\",\n    \"updatedAt\": \"2023-03-14T19:18:37.174Z\",\n    \"updatedBy\": \"7b5f6ea6-7b3a-4437-838a-9a31994aacb3\",\n    \"emailRequired\": false\n}"}],"_postman_id":"2957e14d-303d-40f8-90ad-483936e87bd0"},{"name":"Delete Workflow","id":"fc397241-77bc-4a5b-aadd-be73352f3152","request":{"method":"DELETE","header":[],"url":"{{hostname}}/v2/workflows/:id","description":"<p>Soft-deletes (disables) a workflow. Any other workflow using it as a default return-trip workflow is automatically disassociated.</p>\n<p><strong>Required role:</strong> <code>ADMIN</code> or higher. An account API key always satisfies this (it authenticates as the account owner).</p>\n<h4 id=\"response\">Response</h4>\n<p>Responds <code>204 No Content</code>.</p>\n","auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{apiKey}}"}]},"isInherited":true,"source":{"_postman_id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","name":"ShuttleControl Open API","type":"collection"}},"urlObject":{"path":["v2","workflows",":id"],"host":["{{hostname}}"],"query":[],"variable":[{"id":"279810de-ee5a-4ac5-b977-89e10c701db3","description":{"content":"<p>UUID of the workflow.</p>\n","type":"text/plain"},"type":"any","value":"","key":"id"}]}},"response":[{"id":"1210492a-f704-4404-a5ac-85d23f318e68","name":"Delete Workflow response","originalRequest":{"method":"DELETE","header":[],"url":"{{hostname}}/v2/workflows/"},"status":"No Content","code":204,"_postman_previewlanguage":"plain","header":[],"cookie":[],"responseTime":null,"body":null}],"_postman_id":"fc397241-77bc-4a5b-aadd-be73352f3152"}],"id":"4571a5ab-132e-4cc7-9803-ba1998d7d4c2","description":"<p>Workflows define the shape of a trip: its steps, required customer fields, scheduling rules, and the message templates used to notify customers at each state change.</p>\n","_postman_id":"4571a5ab-132e-4cc7-9803-ba1998d7d4c2","auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{apiKey}}"}]},"isInherited":true,"source":{"_postman_id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","name":"ShuttleControl Open API","type":"collection"}}},{"name":"Vehicles","item":[{"name":"Create Vehicle","id":"024118bf-daba-43e2-84f6-e7205987643d","request":{"method":"POST","header":[],"body":{"mode":"raw","raw":"{\n  \"type\": \"VAN\",\n  \"make\": \"Ford\",\n  \"model\": \"Transit\",\n  \"licensePlate\": \"ABC 123\",\n  \"seats\": 8,\n  \"color\": \"White\",\n  \"storeId\": \"9f2d1c34-0000-0000-0000-000000000000\",\n  \"description\": \"Courtesy shuttle #1\"\n}","options":{"raw":{"language":"json"}}},"url":"{{hostname}}/v2/vehicles","description":"<p>Creates a vehicle in a store.</p>\n<p><strong>Required role:</strong> <code>ADMIN</code> or higher. An account API key always satisfies this (it authenticates as the account owner).</p>\n<h4 id=\"body-fields\">Body fields</h4>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Field</th>\n<th>Type</th>\n<th>Required</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>type</code></td>\n<td>string</td>\n<td>Yes</td>\n<td><code>CAR</code></td>\n</tr>\n<tr>\n<td><code>make</code></td>\n<td>string</td>\n<td>Yes</td>\n<td>Manufacturer, max 50 characters.</td>\n</tr>\n<tr>\n<td><code>model</code></td>\n<td>string</td>\n<td>Yes</td>\n<td>Model, max 50 characters.</td>\n</tr>\n<tr>\n<td><code>licensePlate</code></td>\n<td>string</td>\n<td>Yes</td>\n<td>Max 50 characters.</td>\n</tr>\n<tr>\n<td><code>seats</code></td>\n<td>integer</td>\n<td>Yes</td>\n<td>Passenger capacity, 1–100.</td>\n</tr>\n<tr>\n<td><code>color</code></td>\n<td>string</td>\n<td>Yes</td>\n<td>Max 20 characters.</td>\n</tr>\n<tr>\n<td><code>storeId</code></td>\n<td>string (UUID)</td>\n<td>Yes</td>\n<td>The store the vehicle belongs to.</td>\n</tr>\n<tr>\n<td><code>description</code></td>\n<td>string</td>\n<td>No</td>\n<td>Max 100 characters.</td>\n</tr>\n</tbody>\n</table>\n</div><h4 id=\"response\">Response</h4>\n<p>Responds <code>201</code> with the created vehicle and a <code>Location</code> header.</p>\n","auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{apiKey}}"}]},"isInherited":true,"source":{"_postman_id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","name":"ShuttleControl Open API","type":"collection"}},"urlObject":{"path":["v2","vehicles"],"host":["{{hostname}}"],"query":[],"variable":[]}},"response":[{"id":"93a0b01d-897c-4f6d-8480-4748b9b89b73","name":"Create Vehicle response","originalRequest":{"method":"POST","header":[],"body":{"mode":"raw","raw":"{\n    \"type\": \"CAR\",\n    \"make\": \"Honda\",\n    \"model\": \"Civic\",\n    \"licensePlate\": \"ABC 123\",\n    \"seats\": 4,\n    \"color\": \"black\",\n    \"storeId\": \"\"\n}","options":{"raw":{"language":"json"}}},"url":"{{hostname}}/v2/vehicles"},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"content-length","value":"365"},{"key":"content-type","value":"application/json; charset=utf-8"}],"cookie":[],"responseTime":null,"body":"{\n    \"model\": \"Civic\",\n    \"enabled\": true,\n    \"store\": \"f1a04c8a-dc36-4203-9a9e-698e06cf7cef\",\n    \"color\": \"black\",\n    \"id\": \"584fe92f-8bd8-4424-b94a-437585badd13\",\n    \"driver\": null,\n    \"licensePlate\": \"ABC 123\",\n    \"make\": \"Honda\",\n    \"type\": \"CAR\",\n    \"updatedAt\": null,\n    \"vehicleCoordinate\": null,\n    \"createdAt\": \"2023-03-15T15:22:28.982Z\",\n    \"createdBy\": \"7b5f6ea6-7b3a-4437-838a-9a31994aacb3\",\n    \"seats\": 4,\n    \"updatedBy\": null\n}"}],"_postman_id":"024118bf-daba-43e2-84f6-e7205987643d"},{"name":"List Vehicles","id":"569c2df6-6448-4d6a-b18e-4fcb757c7bda","request":{"method":"GET","header":[],"url":"{{hostname}}/v2/vehicles/list?page=0&size=10","description":"<p>Returns a paginated list of active vehicles for the caller’s stores.</p>\n<h4 id=\"response\">Response</h4>\n<p>Returns <code>{ items, count, total, vehicleLimit }</code> — <code>total</code> is the account-wide vehicle count and <code>vehicleLimit</code> your plan’s cap.</p>\n","auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{apiKey}}"}]},"isInherited":true,"source":{"_postman_id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","name":"ShuttleControl Open API","type":"collection"}},"urlObject":{"path":["v2","vehicles","list"],"host":["{{hostname}}"],"query":[{"description":{"content":"<p>Zero-based page index. Default <code>0</code>.</p>\n","type":"text/plain"},"key":"page","value":"0"},{"description":{"content":"<p>Page size, 1–100. Default <code>10</code>.</p>\n","type":"text/plain"},"key":"size","value":"10"},{"disabled":true,"description":{"content":"<p>Repeatable UUID filter.</p>\n","type":"text/plain"},"key":"storeIds","value":""},{"disabled":true,"description":{"content":"<p>Free-text search over make/model/plate.</p>\n","type":"text/plain"},"key":"search","value":""}],"variable":[]}},"response":[{"id":"639d60ad-cf6c-4fb5-a0c8-0ada4c69ae19","name":"List Vehicles response","originalRequest":{"method":"GET","header":[],"url":{"raw":"{{hostname}}/v2/vehicles?page=0&size=5","host":["{{hostname}}"],"path":["v2","vehicles"],"query":[{"key":"page","value":"0"},{"key":"size","value":"5"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"content-length","value":"948"},{"key":"content-type","value":"application/json; charset=utf-8"}],"cookie":[],"responseTime":null,"body":"{\n    \"items\": [\n        {\n            \"id\": \"584fe92f-8bd8-4424-b94a-437585badd13\",\n            \"driver\": null,\n            \"type\": \"CAR\",\n            \"enabled\": true,\n            \"seats\": 4,\n            \"make\": \"Honda\",\n            \"model\": \"Civic\",\n            \"color\": \"black\",\n            \"licensePlate\": \"ABC 123\",\n            \"store\": {\n                \"id\": \"f1a04c8a-dc36-4203-9a9e-698e06cf7cef\",\n                \"name\": \"Alpha Store\"\n            },\n            \"vehicleCoordinate\": null,\n            \"createdAt\": \"2023-03-15T15:22:28.982Z\"\n        },\n        {\n            \"id\": \"ba2961cc-978e-4ae3-a969-b35fc18caf0c\",\n            \"driver\": null,\n            \"type\": \"CAR\",\n            \"enabled\": true,\n            \"seats\": 4,\n            \"make\": \"Honda\",\n            \"model\": \"Civic\",\n            \"color\": \"black\",\n            \"licensePlate\": \"ABC 123\",\n            \"store\": {\n                \"id\": \"f1a04c8a-dc36-4203-9a9e-698e06cf7cef\",\n                \"name\": \"Alpha Store\"\n            },\n            \"vehicleCoordinate\": null,\n            \"createdAt\": \"2023-03-15T15:20:08.356Z\"\n        },\n        {\n            \"id\": \"3f932af4-8440-4fd1-a581-3a68d2160d04\",\n            \"driver\": null,\n            \"type\": \"CAR\",\n            \"enabled\": true,\n            \"seats\": 4,\n            \"make\": \"Honda\",\n            \"model\": \"Civic\",\n            \"color\": \"black\",\n            \"licensePlate\": \"123 ABC\",\n            \"store\": {\n                \"id\": \"f1a04c8a-dc36-4203-9a9e-698e06cf7cef\",\n                \"name\": \"Alpha Store\"\n            },\n            \"vehicleCoordinate\": null,\n            \"createdAt\": \"2023-03-13T18:05:39.872Z\"\n        }\n    ],\n    \"count\": 3\n}"}],"_postman_id":"569c2df6-6448-4d6a-b18e-4fcb757c7bda"},{"name":"List All Vehicles","id":"42cd8361-a878-4423-8177-ec61c0013ed8","request":{"method":"GET","header":[],"url":"{{hostname}}/v2/vehicles","description":"<p>Returns all active vehicles for the caller’s stores (non-paginated), including their current driver and last known coordinates.</p>\n<h4 id=\"response\">Response</h4>\n<p>Returns an array of vehicle objects.</p>\n","auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{apiKey}}"}]},"isInherited":true,"source":{"_postman_id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","name":"ShuttleControl Open API","type":"collection"}},"urlObject":{"path":["v2","vehicles"],"host":["{{hostname}}"],"query":[{"disabled":true,"description":{"content":"<p>Repeatable UUID filter. Default: all visible stores.</p>\n","type":"text/plain"},"key":"storeIds","value":""}],"variable":[]}},"response":[{"id":"ac514095-8a51-4ad5-b1f4-b339e1817480","name":"List All Vehicles response","originalRequest":{"method":"GET","header":[],"url":"{{hostname}}/v2/vehicles"},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Access-Control-Allow-Origin","value":"*"},{"key":"Content-Security-Policy","value":"default-src 'self';base-uri 'self';font-src 'self' https: data:;form-action 'self';frame-ancestors 'self';img-src 'self' data:;object-src 'none';script-src 'self';script-src-attr 'none';style-src 'self' https: 'unsafe-inline';upgrade-insecure-requests"},{"key":"Cross-Origin-Embedder-Policy","value":"require-corp"},{"key":"Cross-Origin-Opener-Policy","value":"same-origin"},{"key":"X-DNS-Prefetch-Control","value":"off"},{"key":"X-Frame-Options","value":"SAMEORIGIN"},{"key":"Strict-Transport-Security","value":"max-age=15552000; includeSubDomains"},{"key":"X-Download-Options","value":"noopen"},{"key":"X-Content-Type-Options","value":"nosniff"},{"key":"Origin-Agent-Cluster","value":"?1"},{"key":"X-Permitted-Cross-Domain-Policies","value":"none"},{"key":"Referrer-Policy","value":"no-referrer"},{"key":"X-XSS-Protection","value":"0"},{"key":"Content-Type","value":"application/json; charset=utf-8"},{"key":"Content-Length","value":"706"},{"key":"ETag","value":"W/\"2c2-to9SwEXO8HLt1t/4+gVfD/MPlbg\""},{"key":"Vary","value":"Accept-Encoding"},{"key":"Date","value":"Wed, 27 Mar 2024 17:58:06 GMT"},{"key":"Connection","value":"keep-alive"},{"key":"Keep-Alive","value":"timeout=5"}],"cookie":[],"responseTime":null,"body":"[\n    {\n        \"id\": \"be1a09db-871e-4ada-89c3-4bacc4d69e50\",\n        \"driver\": null,\n        \"type\": \"CAR\",\n        \"enabled\": true,\n        \"seats\": 4,\n        \"make\": \"Audi\",\n        \"model\": \"A3\",\n        \"color\": \"yellow\",\n        \"licensePlate\": \"123 ABD\",\n        \"store\": {\n            \"id\": \"495fd56c-6484-4198-bac2-d3ffd4455f4a\",\n            \"name\": \"Alpha Store\",\n            \"color\": \"blue\"\n        },\n        \"vehicleCoordinate\": null,\n        \"createdAt\": \"2024-03-27T17:56:31.432Z\",\n        \"passengers\": [\n            {\n                \"count\": null\n            }\n        ]\n    },\n    {\n        \"id\": \"3dc64756-b13b-448c-97a1-ce0ba609098b\",\n        \"driver\": null,\n        \"type\": \"CAR\",\n        \"enabled\": true,\n        \"seats\": 4,\n        \"make\": \"Honda\",\n        \"model\": \"Civic\",\n        \"color\": \"black\",\n        \"licensePlate\": \"123 ABC\",\n        \"store\": {\n            \"id\": \"495fd56c-6484-4198-bac2-d3ffd4455f4a\",\n            \"name\": \"Alpha Store\",\n            \"color\": \"blue\"\n        },\n        \"vehicleCoordinate\": null,\n        \"createdAt\": \"2024-03-27T17:56:31.412Z\",\n        \"passengers\": [\n            {\n                \"count\": null\n            }\n        ]\n    }\n]"}],"_postman_id":"42cd8361-a878-4423-8177-ec61c0013ed8"},{"name":"Get Vehicle","id":"95c32f71-80b0-49f0-9adf-36287c1daa72","request":{"method":"GET","header":[],"url":"{{hostname}}/v2/vehicles/:id","description":"<p>Returns a single vehicle.</p>\n<h4 id=\"response\">Response</h4>\n<p>Returns the vehicle object (type, make, model, seats, color, licensePlate, store, driver, …).</p>\n","auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{apiKey}}"}]},"isInherited":true,"source":{"_postman_id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","name":"ShuttleControl Open API","type":"collection"}},"urlObject":{"path":["v2","vehicles",":id"],"host":["{{hostname}}"],"query":[],"variable":[{"id":"e3372933-f6c3-4284-88b0-2798fbb8db73","description":{"content":"<p>UUID of the vehicle.</p>\n","type":"text/plain"},"type":"any","value":"","key":"id"}]}},"response":[{"id":"c60b6e3b-a2a3-4c9c-afa3-dd2a72ba086a","name":"Get Vehicle response","originalRequest":{"method":"GET","header":[],"url":"{{hostname}}/v2/vehicles/"},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"content-length","value":"428"},{"key":"content-type","value":"application/json; charset=utf-8"}],"cookie":[],"responseTime":null,"body":"{\n    \"id\": \"3f932af4-8440-4fd1-a581-3a68d2160d04\",\n    \"type\": \"CAR\",\n    \"make\": \"Honda\",\n    \"model\": \"Civic\",\n    \"seats\": 4,\n    \"licensePlate\": \"123 ABC\",\n    \"color\": \"black\",\n    \"enabled\": true,\n    \"store\": {\n        \"id\": \"f1a04c8a-dc36-4203-9a9e-698e06cf7cef\",\n        \"name\": \"Alpha Store\"\n    },\n    \"createdAt\": \"2023-03-13T18:05:39.872Z\",\n    \"createdBy\": {\n        \"id\": \"c6b688ba-03e3-435c-a4dc-2b967f8ec0cf\",\n        \"firstName\": \"Edward\",\n        \"lastName\": \"Maxedon\"\n    },\n    \"updatedAt\": null,\n    \"updatedBy\": null,\n    \"vehicleCoordinate\": null\n}"}],"_postman_id":"95c32f71-80b0-49f0-9adf-36287c1daa72"},{"name":"Update Vehicle","id":"0d5f5124-bb0a-4c87-b9ab-bd890a6f291e","request":{"method":"PUT","header":[],"body":{"mode":"raw","raw":"{\n  \"seats\": 10,\n  \"color\": \"Blue\"\n}","options":{"raw":{"language":"json"}}},"url":"{{hostname}}/v2/vehicles/:id","description":"<p>Updates a vehicle. All fields are optional — only the fields present are changed. Moving a vehicle to a different store is rejected while it has confirmed trips (<code>400 VEHICLE_HAS_ACTIVE_TRIPS</code>).</p>\n<p><strong>Required role:</strong> <code>ADMIN</code> or higher. An account API key always satisfies this (it authenticates as the account owner).</p>\n<h4 id=\"body-fields\">Body fields</h4>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Field</th>\n<th>Type</th>\n<th>Required</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>type</code></td>\n<td>string</td>\n<td>No</td>\n<td><code>CAR</code></td>\n</tr>\n<tr>\n<td><code>make</code></td>\n<td>string</td>\n<td>No</td>\n<td>Max 50 characters.</td>\n</tr>\n<tr>\n<td><code>model</code></td>\n<td>string</td>\n<td>No</td>\n<td>Max 50 characters.</td>\n</tr>\n<tr>\n<td><code>licensePlate</code></td>\n<td>string</td>\n<td>No</td>\n<td>Max 50 characters.</td>\n</tr>\n<tr>\n<td><code>seats</code></td>\n<td>integer</td>\n<td>No</td>\n<td>1–100.</td>\n</tr>\n<tr>\n<td><code>color</code></td>\n<td>string</td>\n<td>No</td>\n<td>Max 20 characters.</td>\n</tr>\n<tr>\n<td><code>storeId</code></td>\n<td>string (UUID)</td>\n<td>No</td>\n<td>Move the vehicle to another store.</td>\n</tr>\n<tr>\n<td><code>description</code></td>\n<td>string</td>\n<td>No</td>\n<td>Max 100 characters.</td>\n</tr>\n</tbody>\n</table>\n</div><h4 id=\"response\">Response</h4>\n<p>Returns the updated vehicle object.</p>\n","auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{apiKey}}"}]},"isInherited":true,"source":{"_postman_id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","name":"ShuttleControl Open API","type":"collection"}},"urlObject":{"path":["v2","vehicles",":id"],"host":["{{hostname}}"],"query":[],"variable":[{"id":"bb8d227d-9f8e-4b05-8806-bc2a7a846a58","description":{"content":"<p>UUID of the vehicle.</p>\n","type":"text/plain"},"type":"any","value":"","key":"id"}]}},"response":[{"id":"890dc7ff-1033-4513-be5f-603d490a45fc","name":"Update Vehicle response","originalRequest":{"method":"PUT","header":[],"body":{"mode":"raw","raw":"{\n    \"type\": \"VAN\",\n    \"make\": \"Honda\",\n    \"model\": \"Accord\",\n    \"licensePlate\": \"123 ABC\",\n    \"seats\": 5,\n    \"color\": \"blue\",\n    \"storeId\": \"\"\n}","options":{"raw":{"language":"json"}}},"url":"{{hostname}}/v2/vehicles/"},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"content-length","value":"277"},{"key":"content-type","value":"application/json; charset=utf-8"}],"cookie":[],"responseTime":null,"body":"{\n    \"id\": \"3f932af4-8440-4fd1-a581-3a68d2160d04\",\n    \"type\": \"VAN\",\n    \"make\": \"Honda\",\n    \"model\": \"Accord\",\n    \"licensePlate\": \"123 ABC\",\n    \"seats\": 5,\n    \"color\": \"blue\",\n    \"store\": \"f1a04c8a-dc36-4203-9a9e-698e06cf7cef\",\n    \"updatedBy\": \"7b5f6ea6-7b3a-4437-838a-9a31994aacb3\",\n    \"updatedAt\": \"2023-03-15T19:20:34.209Z\"\n}"}],"_postman_id":"0d5f5124-bb0a-4c87-b9ab-bd890a6f291e"},{"name":"Archive Vehicle","id":"94c50493-7872-4ff3-a7d8-ac96ff728e3c","request":{"method":"DELETE","header":[],"url":"{{hostname}}/v2/vehicles/:id","description":"<p>Soft-deletes (archives) a vehicle. Rejected while the vehicle is claimed by a driver (<code>400 VEHICLE_HAS_DRIVER</code>) or has confirmed trips (<code>400 VEHICLE_HAS_ACTIVE_TRIPS</code>).</p>\n<p><strong>Required role:</strong> <code>ADMIN</code> or higher. An account API key always satisfies this (it authenticates as the account owner).</p>\n<h4 id=\"response\">Response</h4>\n<p>Responds <code>204 No Content</code>.</p>\n","auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{apiKey}}"}]},"isInherited":true,"source":{"_postman_id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","name":"ShuttleControl Open API","type":"collection"}},"urlObject":{"path":["v2","vehicles",":id"],"host":["{{hostname}}"],"query":[],"variable":[{"id":"0b338e8d-faad-4ecb-90f0-6fdee0d36644","description":{"content":"<p>UUID of the vehicle.</p>\n","type":"text/plain"},"type":"any","value":"","key":"id"}]}},"response":[],"_postman_id":"94c50493-7872-4ff3-a7d8-ac96ff728e3c"},{"name":"Assign Driver","id":"2eef45a4-35da-470d-b4e0-7cbf327b78f1","request":{"method":"POST","header":[],"body":{"mode":"raw","raw":"{\n  \"driverId\": \"4be9f1e0-0000-0000-0000-000000000000\"\n}","options":{"raw":{"language":"json"}}},"url":"{{hostname}}/v2/vehicles/:id/assignDriver","description":"<p>Assigns (claims) a vehicle for a driver on the driver’s behalf. Rejected if the vehicle already has a driver (<code>400 VEHICLE_HAS_DRIVER</code>) or the driver already holds a vehicle (<code>400 USER_HAS_VEHICLE</code>).</p>\n<p><strong>Required role:</strong> <code>DISPATCHER</code> or higher. An account API key always satisfies this (it authenticates as the account owner).</p>\n<h4 id=\"body-fields\">Body fields</h4>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Field</th>\n<th>Type</th>\n<th>Required</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>driverId</code></td>\n<td>string (UUID)</td>\n<td>Yes</td>\n<td>The driver to assign.</td>\n</tr>\n</tbody>\n</table>\n</div><h4 id=\"response\">Response</h4>\n<p>Responds <code>204 No Content</code>.</p>\n","auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{apiKey}}"}]},"isInherited":true,"source":{"_postman_id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","name":"ShuttleControl Open API","type":"collection"}},"urlObject":{"path":["v2","vehicles",":id","assignDriver"],"host":["{{hostname}}"],"query":[],"variable":[{"id":"8459d204-9b78-4cc9-b25d-f6aec4658258","description":{"content":"<p>UUID of the vehicle.</p>\n","type":"text/plain"},"type":"any","value":"","key":"id"}]}},"response":[],"_postman_id":"2eef45a4-35da-470d-b4e0-7cbf327b78f1"}],"id":"009a804d-e610-470d-a72b-efa97c4ebc93","description":"<p>Manage your fleet. Vehicle types: <code>CAR</code> | <code>VAN</code> | <code>BUS</code> | <code>BICYCLE</code> | <code>SUV</code>.</p>\n","_postman_id":"009a804d-e610-470d-a72b-efa97c4ebc93","auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{apiKey}}"}]},"isInherited":true,"source":{"_postman_id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","name":"ShuttleControl Open API","type":"collection"}}},{"name":"MessageTemplates","item":[{"name":"Create MessageTemplate","id":"7bdbe595-465e-426e-a29d-329ed46f99d7","request":{"method":"POST","header":[],"body":{"mode":"raw","raw":"{\n  \"type\": \"SMS\",\n  \"name\": \"Driver on the way\",\n  \"storeId\": \"9f2d1c34-0000-0000-0000-000000000000\",\n  \"locales\": [\n    {\n      \"language\": \"en\",\n      \"template\": \"Your driver is on the way!\"\n    },\n    {\n      \"language\": \"fr\",\n      \"template\": \"Votre chauffeur est en route !\"\n    }\n  ]\n}","options":{"raw":{"language":"json"}}},"url":"{{hostname}}/v2/messageTemplates","description":"<p>Creates a message template in a store. Locale rows for <code>en</code>, <code>fr</code>, and <code>es</code> are always created — pass <code>locales</code> to seed their contents (missing languages start empty). The name must be unique within the store (<code>409 MESSAGE_TEMPLATE_NAME_TAKEN</code>).</p>\n<p><strong>Required role:</strong> <code>ADMIN</code> or higher. An account API key always satisfies this (it authenticates as the account owner).</p>\n<h4 id=\"body-fields\">Body fields</h4>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Field</th>\n<th>Type</th>\n<th>Required</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>type</code></td>\n<td>string</td>\n<td>Yes</td>\n<td><code>SMS</code> or <code>EMAIL</code>.</td>\n</tr>\n<tr>\n<td><code>name</code></td>\n<td>string</td>\n<td>Yes</td>\n<td>Template name, max 100 characters. Unique per store.</td>\n</tr>\n<tr>\n<td><code>storeId</code></td>\n<td>string (UUID)</td>\n<td>Yes</td>\n<td>The store the template belongs to.</td>\n</tr>\n<tr>\n<td><code>locales</code></td>\n<td>object[]</td>\n<td>No</td>\n<td>Initial contents: `[{ language: \"en\"</td>\n</tr>\n</tbody>\n</table>\n</div><h4 id=\"response\">Response</h4>\n<p>Responds <code>201</code> with the created template including its three <code>locales</code>.</p>\n","auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{apiKey}}"}]},"isInherited":true,"source":{"_postman_id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","name":"ShuttleControl Open API","type":"collection"}},"urlObject":{"path":["v2","messageTemplates"],"host":["{{hostname}}"],"query":[],"variable":[]}},"response":[{"id":"9a5b30c5-2b13-46e6-8230-5045b62048f0","name":"Create MessageTemplate response","originalRequest":{"method":"POST","header":[],"body":{"mode":"raw","raw":"{\n    \"type\": \"SMS\",\n    \"name\": \"Driver confirmed message\",\n    \"storeId\": \"\"\n}","options":{"raw":{"language":"json"}}},"url":"{{hostname}}/v2/messageTemplates"},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Access-Control-Allow-Origin","value":"*"},{"key":"Content-Security-Policy","value":"default-src 'self';base-uri 'self';font-src 'self' https: data:;form-action 'self';frame-ancestors 'self';img-src 'self' data:;object-src 'none';script-src 'self';script-src-attr 'none';style-src 'self' https: 'unsafe-inline';upgrade-insecure-requests"},{"key":"Cross-Origin-Embedder-Policy","value":"require-corp"},{"key":"Cross-Origin-Opener-Policy","value":"same-origin"},{"key":"X-DNS-Prefetch-Control","value":"off"},{"key":"X-Frame-Options","value":"SAMEORIGIN"},{"key":"Strict-Transport-Security","value":"max-age=15552000; includeSubDomains"},{"key":"X-Download-Options","value":"noopen"},{"key":"X-Content-Type-Options","value":"nosniff"},{"key":"Origin-Agent-Cluster","value":"?1"},{"key":"X-Permitted-Cross-Domain-Policies","value":"none"},{"key":"Referrer-Policy","value":"no-referrer"},{"key":"X-XSS-Protection","value":"0"},{"key":"Location","value":"https://api.shuttlecontrol.com/v2/messageTemplates/18913b74-17e7-4b15-b112-7dce94e5b04d"},{"key":"Content-Type","value":"application/json; charset=utf-8"},{"key":"ETag","value":"W/\"51e-8/N4WLl2BGGSLXmCSLa+olKQgow\""},{"key":"Vary","value":"Accept-Encoding"},{"key":"Content-Encoding","value":"gzip"},{"key":"Date","value":"Tue, 27 Feb 2024 15:27:34 GMT"},{"key":"Connection","value":"keep-alive"},{"key":"Keep-Alive","value":"timeout=5"},{"key":"Transfer-Encoding","value":"chunked"}],"cookie":[],"responseTime":null,"body":"{\n    \"id\": \"18913b74-17e7-4b15-b112-7dce94e5b04d\",\n    \"name\": \"Driver confirmed message\",\n    \"type\": \"SMS\",\n    \"store\": \"5ad63d0d-1e67-42d1-828c-69b709d2a196\",\n    \"createdBy\": \"c1fbae73-1a37-43ab-ad76-f78a1f7b9d4e\",\n    \"enabled\": true,\n    \"createdAt\": \"2024-02-27T15:27:34.208Z\",\n    \"updatedAt\": null,\n    \"updatedBy\": null,\n    \"locales\": [\n        {\n            \"id\": \"e33f9559-1440-4f87-ae53-b6f7a0fe20e1\",\n            \"messageTemplate\": {\n                \"id\": \"18913b74-17e7-4b15-b112-7dce94e5b04d\",\n                \"name\": \"Driver confirmed message\",\n                \"type\": \"SMS\",\n                \"store\": \"5ad63d0d-1e67-42d1-828c-69b709d2a196\",\n                \"createdBy\": \"c1fbae73-1a37-43ab-ad76-f78a1f7b9d4e\",\n                \"enabled\": true,\n                \"createdAt\": \"2024-02-27T15:27:34.208Z\",\n                \"updatedAt\": null,\n                \"updatedBy\": null,\n                \"locales\": []\n            },\n            \"language\": \"en\",\n            \"template\": \"\",\n            \"createdBy\": \"c1fbae73-1a37-43ab-ad76-f78a1f7b9d4e\",\n            \"createdAt\": \"2024-02-27T15:27:34.222Z\",\n            \"updatedAt\": null,\n            \"updatedBy\": null\n        },\n        {\n            \"id\": \"1cdc7e68-2b24-4fee-a065-7df26a4a946d\",\n            \"messageTemplate\": {\n                \"id\": \"18913b74-17e7-4b15-b112-7dce94e5b04d\",\n                \"name\": \"Driver confirmed message\",\n                \"type\": \"SMS\",\n                \"store\": \"5ad63d0d-1e67-42d1-828c-69b709d2a196\",\n                \"createdBy\": \"c1fbae73-1a37-43ab-ad76-f78a1f7b9d4e\",\n                \"enabled\": true,\n                \"createdAt\": \"2024-02-27T15:27:34.208Z\",\n                \"updatedAt\": null,\n                \"updatedBy\": null,\n                \"locales\": []\n            },\n            \"language\": \"fr\",\n            \"template\": \"\",\n            \"createdBy\": \"c1fbae73-1a37-43ab-ad76-f78a1f7b9d4e\",\n            \"createdAt\": \"2024-02-27T15:27:34.222Z\",\n            \"updatedAt\": null,\n            \"updatedBy\": null\n        }\n    ]\n}"}],"_postman_id":"7bdbe595-465e-426e-a29d-329ed46f99d7"},{"name":"List MessageTemplates","id":"cc7b2987-3212-4225-a58a-437298f934a2","request":{"method":"GET","header":[],"url":"{{hostname}}/v2/messageTemplates/list?page=0&size=10","description":"<p>Returns a paginated list of active message templates for the caller’s stores.</p>\n<p><strong>Required role:</strong> <code>ADMIN</code> or higher. An account API key always satisfies this (it authenticates as the account owner).</p>\n<h4 id=\"response\">Response</h4>\n<p>Returns <code>{ items, count }</code>.</p>\n","auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{apiKey}}"}]},"isInherited":true,"source":{"_postman_id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","name":"ShuttleControl Open API","type":"collection"}},"urlObject":{"path":["v2","messageTemplates","list"],"host":["{{hostname}}"],"query":[{"description":{"content":"<p>Zero-based page index. Default <code>0</code>.</p>\n","type":"text/plain"},"key":"page","value":"0"},{"description":{"content":"<p>Page size, 1–100. Default <code>10</code>.</p>\n","type":"text/plain"},"key":"size","value":"10"},{"disabled":true,"description":{"content":"<p>Filter to one store.</p>\n","type":"text/plain"},"key":"storeId","value":""}],"variable":[]}},"response":[{"id":"9a6b7051-b01d-4b2b-bb0d-37581048475b","name":"List MessageTemplates response","originalRequest":{"method":"GET","header":[],"url":{"raw":"{{hostname}}/v2/messageTemplates?page=0&size=5&storeId=","host":["{{hostname}}"],"path":["v2","messageTemplates"],"query":[{"key":"page","value":"0"},{"key":"size","value":"5"},{"key":"storeId","value":""}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"content-length","value":"459"},{"key":"content-type","value":"application/json; charset=utf-8"}],"cookie":[],"responseTime":null,"body":"{\n    \"items\": [\n        {\n            \"id\": \"eabc3a35-b9d0-4854-b2e9-7e72269c2dff\",\n            \"type\": \"SMS\",\n            \"name\": \"Driver confirmed message\",\n            \"enabled\": true,\n            \"store\": {\n                \"id\": \"0b8a26d9-14f3-40ae-8d44-681e0b5c381a\",\n                \"name\": \"Alpha Store\"\n            },\n            \"createdAt\": \"2023-04-05T16:56:14.692Z\"\n        },\n        {\n            \"id\": \"9b9d2dab-688d-42b3-a660-c52a07fa3fe2\",\n            \"type\": \"SMS\",\n            \"name\": \"Send Tracking Link\",\n            \"enabled\": true,\n            \"store\": {\n                \"id\": \"0b8a26d9-14f3-40ae-8d44-681e0b5c381a\",\n                \"name\": \"Alpha Store\"\n            },\n            \"createdAt\": \"2023-04-05T14:18:12.041Z\"\n        }\n    ],\n    \"count\": 2\n}"}],"_postman_id":"cc7b2987-3212-4225-a58a-437298f934a2"},{"name":"List All MessageTemplates","id":"d79da7c1-d5b0-48fb-96b2-6fd25290fc04","request":{"method":"GET","header":[],"url":"{{hostname}}/v2/messageTemplates?storeId=","description":"<p>Returns all active message templates of a store (non-paginated).</p>\n<p><strong>Required role:</strong> <code>ADMIN</code> or higher. An account API key always satisfies this (it authenticates as the account owner).</p>\n<h4 id=\"response\">Response</h4>\n<p>Returns an array of template objects with their <code>locales</code>.</p>\n","auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{apiKey}}"}]},"isInherited":true,"source":{"_postman_id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","name":"ShuttleControl Open API","type":"collection"}},"urlObject":{"path":["v2","messageTemplates"],"host":["{{hostname}}"],"query":[{"description":{"content":"<p>Required. The store whose templates to return.</p>\n","type":"text/plain"},"key":"storeId","value":""}],"variable":[]}},"response":[],"_postman_id":"d79da7c1-d5b0-48fb-96b2-6fd25290fc04"},{"name":"Get MessageTemplate","id":"5f7fdef9-4263-4e03-8658-b08088a5b094","request":{"method":"GET","header":[],"url":"{{hostname}}/v2/messageTemplates/:id","description":"<p>Returns a single message template with its locales.</p>\n<p><strong>Required role:</strong> <code>ADMIN</code> or higher. An account API key always satisfies this (it authenticates as the account owner).</p>\n<h4 id=\"response\">Response</h4>\n<p>Returns the template object.</p>\n","auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{apiKey}}"}]},"isInherited":true,"source":{"_postman_id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","name":"ShuttleControl Open API","type":"collection"}},"urlObject":{"path":["v2","messageTemplates",":id"],"host":["{{hostname}}"],"query":[],"variable":[{"id":"bb3f1642-a99f-43d7-8501-85c79dd84a3c","description":{"content":"<p>UUID of the template.</p>\n","type":"text/plain"},"type":"any","value":"","key":"id"}]}},"response":[{"id":"d1269a3b-de5f-4fa2-a5d6-1fa544fb40e2","name":"Get MessageTemplate response","originalRequest":{"method":"GET","header":[],"url":"{{hostname}}/v2/messageTemplates/"},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"content-length","value":"676"},{"key":"content-type","value":"application/json; charset=utf-8"}],"cookie":[],"responseTime":null,"body":"{\n    \"id\": \"9b9d2dab-688d-42b3-a660-c52a07fa3fe2\",\n    \"type\": \"SMS\",\n    \"name\": \"Send Tracking Link\",\n    \"enabled\": true,\n    \"store\": {\n        \"id\": \"0b8a26d9-14f3-40ae-8d44-681e0b5c381a\",\n        \"name\": \"Alpha Store\"\n    },\n    \"locales\": [\n        {\n            \"id\": \"975f4fcf-1b17-418b-947d-2811ebf18705\",\n            \"language\": \"en\",\n            \"template\": \"Hi {{{customerName}}}, your driver is on the way! Track your driver: {{{trackingLink}}}\"\n        },\n        {\n            \"id\": \"f9ac787c-5ba7-44be-8291-14014ebd496d\",\n            \"language\": \"fr\",\n            \"template\": \"Bonjour {{{customerName}}}, votre chauffeur est on route! {{{trackingLink}}}\"\n        }\n    ],\n    \"createdAt\": \"2023-04-05T14:18:12.041Z\",\n    \"createdBy\": {\n        \"id\": \"b2eeb765-8c35-4ef1-b307-e0c47eda1e78\",\n        \"firstName\": \"Edward\",\n        \"lastName\": \"Maxedon\"\n    },\n    \"updatedAt\": null,\n    \"updatedBy\": null\n}"}],"_postman_id":"5f7fdef9-4263-4e03-8658-b08088a5b094"},{"name":"Update MessageTemplate","id":"0b8815bd-f6a9-4d4d-a2a8-412bf5206106","request":{"method":"PUT","header":[],"body":{"mode":"raw","raw":"{\n  \"name\": \"Driver on the way\",\n  \"locales\": [\n    {\n      \"id\": \"0d1e2f30-0000-0000-0000-000000000000\",\n      \"template\": \"Your driver is on the way!\"\n    }\n  ]\n}","options":{"raw":{"language":"json"}}},"url":"{{hostname}}/v2/messageTemplates/:id","description":"<p>Updates a template’s type, name, and/or locale contents. All fields are optional. Locale updates are addressed by the <strong>locale row id</strong> (from <strong>Get MessageTemplate</strong>), not by language.</p>\n<p><strong>Required role:</strong> <code>ADMIN</code> or higher. An account API key always satisfies this (it authenticates as the account owner).</p>\n<h4 id=\"body-fields\">Body fields</h4>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Field</th>\n<th>Type</th>\n<th>Required</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>type</code></td>\n<td>string</td>\n<td>No</td>\n<td><code>SMS</code> or <code>EMAIL</code>.</td>\n</tr>\n<tr>\n<td><code>name</code></td>\n<td>string</td>\n<td>No</td>\n<td>Max 100 characters. Unique per store (<code>409</code> on conflict).</td>\n</tr>\n<tr>\n<td><code>locales</code></td>\n<td>object[]</td>\n<td>No</td>\n<td><code>[{ id: UUID (locale row id), template: string (max 500) }]</code>.</td>\n</tr>\n</tbody>\n</table>\n</div><h4 id=\"response\">Response</h4>\n<p>Returns the updated template object.</p>\n","auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{apiKey}}"}]},"isInherited":true,"source":{"_postman_id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","name":"ShuttleControl Open API","type":"collection"}},"urlObject":{"path":["v2","messageTemplates",":id"],"host":["{{hostname}}"],"query":[],"variable":[{"id":"8ef97923-e93c-49d4-9b01-fdff21bd4378","description":{"content":"<p>UUID of the template.</p>\n","type":"text/plain"},"type":"any","value":"","key":"id"}]}},"response":[{"id":"20f9fb7f-a9cc-4760-a5ac-f40b018821dd","name":"Update MessageTemplate response","originalRequest":{"method":"PUT","header":[],"body":{"mode":"raw","raw":"{\n    \"type\": \"SMS\",\n    \"name\": \"Driver confirmed message\",\n    \"locales\": [{\n            \"id\": \"975f4fcf-1b17-418b-947d-2811ebf18705\",\n            \"template\": \"Hi {{{customerName}}}, your driver is on the way! Track your driver: {{{trackingLink}}}\"\n        },\n        {\n            \"id\": \"f9ac787c-5ba7-44be-8291-14014ebd496d\",\n            \"template\": \"Bonjour {{{customerName}}}, votre chauffeur est on route! {{{trackingLink}}}\"\n    }]\n}","options":{"raw":{"language":"json"}}},"url":"{{hostname}}/v2/messageTemplates/"},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"content-length","value":"787"},{"key":"content-type","value":"application/json; charset=utf-8"}],"cookie":[],"responseTime":null,"body":"{\n    \"id\": \"9b9d2dab-688d-42b3-a660-c52a07fa3fe2\",\n    \"type\": \"SMS\",\n    \"name\": \"Driver confirmed message\",\n    \"enabled\": true,\n    \"store\": {\n        \"id\": \"0b8a26d9-14f3-40ae-8d44-681e0b5c381a\",\n        \"name\": \"Alpha Store\"\n    },\n    \"locales\": [\n        {\n            \"id\": \"975f4fcf-1b17-418b-947d-2811ebf18705\",\n            \"language\": \"en\",\n            \"template\": \"Hi {{{customerName}}}, your driver is on the way! Track your driver: {{{trackingLink}}}\"\n        },\n        {\n            \"id\": \"f9ac787c-5ba7-44be-8291-14014ebd496d\",\n            \"language\": \"fr\",\n            \"template\": \"Bonjour {{{customerName}}}, votre chauffeur est on route! {{{trackingLink}}}\"\n        }\n    ],\n    \"createdAt\": \"2023-04-05T14:18:12.041Z\",\n    \"createdBy\": {\n        \"id\": \"b2eeb765-8c35-4ef1-b307-e0c47eda1e78\",\n        \"firstName\": \"Edward\",\n        \"lastName\": \"Maxedon\"\n    },\n    \"updatedAt\": \"2023-04-05T17:07:46.509Z\",\n    \"updatedBy\": {\n        \"id\": \"b2eeb765-8c35-4ef1-b307-e0c47eda1e78\",\n        \"firstName\": \"Edward\",\n        \"lastName\": \"Maxedon\"\n    }\n}"}],"_postman_id":"0b8815bd-f6a9-4d4d-a2a8-412bf5206106"},{"name":"Delete MessageTemplate","id":"f422dde9-339d-4dd6-8b27-3519be7a1537","request":{"method":"DELETE","header":[],"url":"{{hostname}}/v2/messageTemplates/:id","description":"<p>Soft-deletes a message template. Rejected while any active workflow or workflow step still references it (<code>400 MESSAGE_TEMPLATE_IS_IN_USE</code>).</p>\n<p><strong>Required role:</strong> <code>ADMIN</code> or higher. An account API key always satisfies this (it authenticates as the account owner).</p>\n<h4 id=\"response\">Response</h4>\n<p>Responds <code>204 No Content</code>.</p>\n","auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{apiKey}}"}]},"isInherited":true,"source":{"_postman_id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","name":"ShuttleControl Open API","type":"collection"}},"urlObject":{"path":["v2","messageTemplates",":id"],"host":["{{hostname}}"],"query":[],"variable":[{"id":"28613f5e-d1b9-42b2-b733-cc71a3ada6db","description":{"content":"<p>UUID of the template.</p>\n","type":"text/plain"},"type":"any","value":"","key":"id"}]}},"response":[{"id":"4404056d-a5a5-495e-8ec4-a3130d9c6f51","name":"Delete MessageTemplate response","originalRequest":{"method":"DELETE","header":[],"url":"{{hostname}}/v2/messageTemplates/"},"status":"No Content","code":204,"_postman_previewlanguage":"plain","header":[],"cookie":[],"responseTime":null,"body":null}],"_postman_id":"f422dde9-339d-4dd6-8b27-3519be7a1537"}],"id":"3f8a83c7-287a-49e0-915b-a6d3c772ba70","description":"<p>Reusable SMS/email message bodies, localized in <code>en</code>, <code>fr</code>, and <code>es</code>, referenced by workflows to notify customers.</p>\n","_postman_id":"3f8a83c7-287a-49e0-915b-a6d3c772ba70","auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{apiKey}}"}]},"isInherited":true,"source":{"_postman_id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","name":"ShuttleControl Open API","type":"collection"}}},{"name":"Customers","item":[{"name":"Create Customer","id":"38c97f35-7edd-455e-8fd4-15bc5d2111c5","request":{"method":"POST","header":[],"body":{"mode":"raw","raw":"{\n  \"firstName\": \"Jane\",\n  \"lastName\": \"Doe\",\n  \"language\": \"en\",\n  \"phoneNumber\": \"+1 514 555 0100\",\n  \"email\": \"jane@example.com\",\n  \"address\": \"1 Main St, Montreal, QC\",\n  \"storeId\": \"9f2d1c34-0000-0000-0000-000000000000\"\n}","options":{"raw":{"language":"json"}}},"url":"{{hostname}}/v2/customers","description":"<p>Creates a customer in a store and geocodes + attaches the given address as their first place. Either <code>companyName</code> or both <code>firstName</code> and <code>lastName</code> must be provided (<code>400 CUSTOMER_COMPANY_NAME_OR_FIRST_NAME_REQUIRED</code>).</p>\n<h4 id=\"body-fields\">Body fields</h4>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Field</th>\n<th>Type</th>\n<th>Required</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>language</code></td>\n<td>string</td>\n<td>Yes</td>\n<td><code>en</code>, <code>fr</code>, or <code>es</code> — used for customer notifications.</td>\n</tr>\n<tr>\n<td><code>address</code></td>\n<td>string</td>\n<td>Yes</td>\n<td>The customer’s address, max 100 characters. Geocoded server-side.</td>\n</tr>\n<tr>\n<td><code>storeId</code></td>\n<td>string (UUID)</td>\n<td>Yes</td>\n<td>The store the customer belongs to.</td>\n</tr>\n<tr>\n<td><code>firstName</code></td>\n<td>string</td>\n<td>Conditional</td>\n<td>Max 100. Required together with <code>lastName</code> when <code>companyName</code> is absent.</td>\n</tr>\n<tr>\n<td><code>lastName</code></td>\n<td>string</td>\n<td>Conditional</td>\n<td>Max 100. Required together with <code>firstName</code> when <code>companyName</code> is absent.</td>\n</tr>\n<tr>\n<td><code>companyName</code></td>\n<td>string</td>\n<td>Conditional</td>\n<td>Max 100. Required when first/last name are absent.</td>\n</tr>\n<tr>\n<td><code>email</code></td>\n<td>string</td>\n<td>null</td>\n<td>No</td>\n</tr>\n<tr>\n<td><code>phoneNumber</code></td>\n<td>string</td>\n<td>No</td>\n<td>Max 100 characters.</td>\n</tr>\n</tbody>\n</table>\n</div><h4 id=\"response\">Response</h4>\n<p>Responds <code>201</code> with the created customer and a <code>Location</code> header.</p>\n","auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{apiKey}}"}]},"isInherited":true,"source":{"_postman_id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","name":"ShuttleControl Open API","type":"collection"}},"urlObject":{"path":["v2","customers"],"host":["{{hostname}}"],"query":[],"variable":[]}},"response":[{"id":"1215cd7e-b0dd-4ada-a7cc-acd4fb88485a","name":"Create Customer response","originalRequest":{"method":"POST","header":[],"body":{"mode":"raw","raw":"{\n    \"firstName\": \"Noel\",\n    \"lastName\": \"Sky\",\n    \"language\": \"en\",\n    \"address\": \"3901 Bannantyne, Verdun, QC H4G 1C2\",\n    \"phoneNumber\": \"555 123 1234\",\n    \"storeId\": \"\"\n}","options":{"raw":{"language":"json"}}},"url":"{{hostname}}/v2/customers"},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"content-length","value":"367"},{"key":"content-type","value":"application/json; charset=utf-8"}],"cookie":[],"responseTime":null,"body":"{\n    \"updatedAt\": null,\n    \"phoneNumber\": \"555 123 1234\",\n    \"email\": \"\",\n    \"enabled\": true,\n    \"store\": \"f1a04c8a-dc36-4203-9a9e-698e06cf7cef\",\n    \"lastName\": \"Sky\",\n    \"updatedBy\": null,\n    \"phoneType\": \"\",\n    \"places\": [],\n    \"firstName\": \"Noel\",\n    \"id\": \"802096bb-8a82-4d8b-86a9-72069ac6705e\",\n    \"language\": \"en\",\n    \"companyName\": \"\",\n    \"createdAt\": \"2023-03-14T15:32:01.226Z\",\n    \"createdBy\": \"7b5f6ea6-7b3a-4437-838a-9a31994aacb3\"\n}"}],"_postman_id":"38c97f35-7edd-455e-8fd4-15bc5d2111c5"},{"name":"List Customers","id":"15cd6b60-2b8a-4fa4-ab2a-1d3f9d8e2e60","request":{"method":"GET","header":[],"url":"{{hostname}}/v2/customers?page=0&size=10","description":"<p>Returns a paginated list of active customers for the caller’s stores.</p>\n<h4 id=\"response\">Response</h4>\n<p>Returns <code>{ items, count }</code>.</p>\n","auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{apiKey}}"}]},"isInherited":true,"source":{"_postman_id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","name":"ShuttleControl Open API","type":"collection"}},"urlObject":{"path":["v2","customers"],"host":["{{hostname}}"],"query":[{"description":{"content":"<p>Zero-based page index. Default <code>0</code>.</p>\n","type":"text/plain"},"key":"page","value":"0"},{"description":{"content":"<p>Page size, 1–100. Default <code>10</code>.</p>\n","type":"text/plain"},"key":"size","value":"10"},{"disabled":true,"description":{"content":"<p>Free-text search (max 100) over names, company, phone, and email.</p>\n","type":"text/plain"},"key":"search","value":""},{"disabled":true,"description":{"content":"<p>Repeatable UUID filter.</p>\n","type":"text/plain"},"key":"storeIds","value":""}],"variable":[]}},"response":[{"id":"4d24f569-7198-4237-914e-a604c866ab1a","name":"List Customers response","originalRequest":{"method":"GET","header":[],"url":{"raw":"{{hostname}}/v2/customers?page=0&size=5","host":["{{hostname}}"],"path":["v2","customers"],"query":[{"key":"page","value":"0"},{"key":"size","value":"5"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"content-length","value":"854"},{"key":"content-type","value":"application/json; charset=utf-8"}],"cookie":[],"responseTime":null,"body":"{\n    \"items\": [\n        {\n            \"id\": \"dc697ec3-18ef-4479-8670-154b0a4a776a\",\n            \"firstName\": \"Jamie\",\n            \"lastName\": \"Tremblay\",\n            \"companyName\": \"\",\n            \"email\": \"\",\n            \"language\": \"en\",\n            \"phoneNumber\": \"555 543 6543\",\n            \"store\": {\n                \"id\": \"f1a04c8a-dc36-4203-9a9e-698e06cf7cef\",\n                \"name\": \"Alpha Store\"\n            },\n            \"createdAt\": \"2023-03-14T18:47:36.344Z\"\n        },\n        {\n            \"id\": \"e332506d-a290-4ddc-acca-0200d3eae63d\",\n            \"firstName\": \"Charlie\",\n            \"lastName\": \"Adams\",\n            \"companyName\": \"ACME Inc.\",\n            \"email\": \"\",\n            \"language\": \"en\",\n            \"phoneNumber\": \"555 123 3456\",\n            \"store\": {\n                \"id\": \"f1a04c8a-dc36-4203-9a9e-698e06cf7cef\",\n                \"name\": \"Alpha Store\"\n            },\n            \"createdAt\": \"2023-03-13T18:05:39.903Z\"\n        },\n        {\n            \"id\": \"37a3df2b-df7a-4c11-8046-49d041900300\",\n            \"firstName\": \"Edward\",\n            \"lastName\": \"Maxedon\",\n            \"companyName\": \"\",\n            \"email\": \"\",\n            \"language\": \"en\",\n            \"phoneNumber\": \"514 699 7622\",\n            \"store\": {\n                \"id\": \"f1a04c8a-dc36-4203-9a9e-698e06cf7cef\",\n                \"name\": \"Alpha Store\"\n            },\n            \"createdAt\": \"2023-03-13T18:05:39.892Z\"\n        }\n    ],\n    \"count\": 3\n}"}],"_postman_id":"15cd6b60-2b8a-4fa4-ab2a-1d3f9d8e2e60"},{"name":"List Archived Customers","id":"a1670ae1-60cd-4c76-914b-89088afd6c41","request":{"method":"GET","header":[],"url":"{{hostname}}/v2/customers/archived?page=0&size=10","description":"<p>Returns a paginated list of archived customers, with the same parameters as <strong>List Customers</strong>.</p>\n<h4 id=\"response\">Response</h4>\n<p>Returns <code>{ items, count }</code>.</p>\n","auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{apiKey}}"}]},"isInherited":true,"source":{"_postman_id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","name":"ShuttleControl Open API","type":"collection"}},"urlObject":{"path":["v2","customers","archived"],"host":["{{hostname}}"],"query":[{"description":{"content":"<p>Zero-based page index. Default <code>0</code>.</p>\n","type":"text/plain"},"key":"page","value":"0"},{"description":{"content":"<p>Page size, 1–100. Default <code>10</code>.</p>\n","type":"text/plain"},"key":"size","value":"10"},{"disabled":true,"description":{"content":"<p>Free-text search (max 100).</p>\n","type":"text/plain"},"key":"search","value":""},{"disabled":true,"description":{"content":"<p>Repeatable UUID filter.</p>\n","type":"text/plain"},"key":"storeIds","value":""}],"variable":[]}},"response":[],"_postman_id":"a1670ae1-60cd-4c76-914b-89088afd6c41"},{"name":"Search Customers","id":"843c5493-741c-4cd9-9754-7f439f122a07","request":{"method":"GET","header":[],"url":"{{hostname}}/v2/customers/search?phoneNumber=555","description":"<p>Quick lookup returning at most <strong>5</strong> matching active customers, newest first. At least one search field is required.</p>\n<h4 id=\"response\">Response</h4>\n<p>Returns an array of up to 5 customers: <code>id</code>, <code>firstName</code>, <code>lastName</code>, <code>companyName</code>, <code>email</code>, <code>language</code>, <code>phoneNumber</code>, <code>notes</code>, <code>smsEnabled</code>.</p>\n","auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{apiKey}}"}]},"isInherited":true,"source":{"_postman_id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","name":"ShuttleControl Open API","type":"collection"}},"urlObject":{"path":["v2","customers","search"],"host":["{{hostname}}"],"query":[{"description":{"content":"<p>Substring match on phone number.</p>\n","type":"text/plain"},"key":"phoneNumber","value":"555"},{"disabled":true,"description":{"content":"<p>Case-insensitive substring match.</p>\n","type":"text/plain"},"key":"companyName","value":""},{"disabled":true,"description":{"content":"<p>Case-insensitive substring match.</p>\n","type":"text/plain"},"key":"firstName","value":""},{"disabled":true,"description":{"content":"<p>Case-insensitive substring match.</p>\n","type":"text/plain"},"key":"lastName","value":""},{"disabled":true,"description":{"content":"<p>Substring match.</p>\n","type":"text/plain"},"key":"email","value":""}],"variable":[]}},"response":[{"id":"8c6d7181-25f7-4fe6-a7dc-9efd50560578","name":"Search Customers response","originalRequest":{"method":"GET","header":[],"url":{"raw":"{{hostname}}/v2/customers/search?phoneNumber=555&companyName&firstName&lastName","host":["{{hostname}}"],"path":["v2","customers","search"],"query":[{"key":"phoneNumber","value":"555","description":"Optional customer phone number"},{"key":"companyName","value":null,"description":"Optional customer company name"},{"key":"firstName","value":null,"description":"Optional customer first name"},{"key":"lastName","value":null,"description":"Optional customer last name"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Access-Control-Allow-Origin","value":"*"},{"key":"Content-Security-Policy","value":"default-src 'self';base-uri 'self';font-src 'self' https: data:;form-action 'self';frame-ancestors 'self';img-src 'self' data:;object-src 'none';script-src 'self';script-src-attr 'none';style-src 'self' https: 'unsafe-inline';upgrade-insecure-requests"},{"key":"Cross-Origin-Embedder-Policy","value":"require-corp"},{"key":"Cross-Origin-Opener-Policy","value":"same-origin"},{"key":"X-DNS-Prefetch-Control","value":"off"},{"key":"X-Frame-Options","value":"SAMEORIGIN"},{"key":"Strict-Transport-Security","value":"max-age=15552000; includeSubDomains"},{"key":"X-Download-Options","value":"noopen"},{"key":"X-Content-Type-Options","value":"nosniff"},{"key":"Origin-Agent-Cluster","value":"?1"},{"key":"X-Permitted-Cross-Domain-Policies","value":"none"},{"key":"Referrer-Policy","value":"no-referrer"},{"key":"X-XSS-Protection","value":"0"},{"key":"Content-Type","value":"application/json; charset=utf-8"},{"key":"Content-Length","value":"202"},{"key":"ETag","value":"W/\"ca-2BlwQuo7mGYxK8WKtzVIpUPaw9U\""},{"key":"Vary","value":"Accept-Encoding"},{"key":"Date","value":"Tue, 12 Mar 2024 16:33:23 GMT"},{"key":"Connection","value":"keep-alive"},{"key":"Keep-Alive","value":"timeout=5"}],"cookie":[],"responseTime":null,"body":"[\n    {\n        \"id\": \"66d6c31b-c499-413f-8ad4-cb227ff9f631\",\n        \"firstName\": \"Alex\",\n        \"lastName\": \"Johnson\",\n        \"companyName\": \"\",\n        \"email\": \"alex.johnson@example.com\",\n        \"language\": \"en\",\n        \"phoneNumber\": \"555 123 4567\",\n        \"smsEnabled\": true\n    }\n]"}],"_postman_id":"843c5493-741c-4cd9-9754-7f439f122a07"},{"name":"Get Customer","id":"533cb49f-6b44-4c15-a271-cc0a95fbc3d0","request":{"method":"GET","header":[],"url":"{{hostname}}/v2/customers/:id","description":"<p>Returns a single customer with their saved places.</p>\n<h4 id=\"response\">Response</h4>\n<p>Returns the customer object.</p>\n","auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{apiKey}}"}]},"isInherited":true,"source":{"_postman_id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","name":"ShuttleControl Open API","type":"collection"}},"urlObject":{"path":["v2","customers",":id"],"host":["{{hostname}}"],"query":[],"variable":[{"id":"3e161fcd-0e82-4968-b7e8-2f8328ecc726","description":{"content":"<p>UUID of the customer.</p>\n","type":"text/plain"},"type":"any","value":"","key":"id"}]}},"response":[{"id":"53573a08-e06d-4f02-ae20-535c60a0976f","name":"Get Customer response","originalRequest":{"method":"GET","header":[],"url":"{{hostname}}/v2/customers/"},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"content-length","value":"546"},{"key":"content-type","value":"application/json; charset=utf-8"}],"cookie":[],"responseTime":null,"body":"{\n    \"id\": \"802096bb-8a82-4d8b-86a9-72069ac6705e\",\n    \"firstName\": \"Noel\",\n    \"lastName\": \"Sky\",\n    \"email\": \"\",\n    \"language\": \"en\",\n    \"companyName\": \"\",\n    \"phoneNumber\": \"555 123 1234\",\n    \"store\": {\n        \"id\": \"f1a04c8a-dc36-4203-9a9e-698e06cf7cef\",\n        \"name\": \"Alpha Store\"\n    },\n    \"createdAt\": \"2023-03-14T15:32:01.226Z\",\n    \"createdBy\": {\n        \"id\": \"7b5f6ea6-7b3a-4437-838a-9a31994aacb3\",\n        \"firstName\": \"Edward\",\n        \"lastName\": \"Maxedon\"\n    },\n    \"updatedAt\": null,\n    \"updatedBy\": null,\n    \"places\": [\n        {\n            \"id\": \"82afc9d1-bc18-4bc9-af3a-65015456ee95\",\n            \"address\": \"3901 Bannantyne, Verdun, QC H4G 1C2\",\n            \"createdAt\": \"2023-03-13T19:57:55.972Z\"\n        }\n    ]\n}"}],"_postman_id":"533cb49f-6b44-4c15-a271-cc0a95fbc3d0"},{"name":"Update Customer","id":"1deea88e-0a5f-4b86-9820-9293a775141c","request":{"method":"PUT","header":[],"body":{"mode":"raw","raw":"{\n  \"phoneNumber\": \"+1 514 555 0199\",\n  \"notes\": \"Prefers front seat.\"\n}","options":{"raw":{"language":"json"}}},"url":"{{hostname}}/v2/customers/:id","description":"<p>Updates a customer. All fields are optional — only the fields present are changed.</p>\n<h4 id=\"body-fields\">Body fields</h4>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Field</th>\n<th>Type</th>\n<th>Required</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>firstName</code></td>\n<td>string</td>\n<td>No</td>\n<td>Max 100 characters.</td>\n</tr>\n<tr>\n<td><code>lastName</code></td>\n<td>string</td>\n<td>No</td>\n<td>Max 100 characters.</td>\n</tr>\n<tr>\n<td><code>companyName</code></td>\n<td>string</td>\n<td>No</td>\n<td>Max 100 characters.</td>\n</tr>\n<tr>\n<td><code>email</code></td>\n<td>string</td>\n<td>null</td>\n<td>No</td>\n</tr>\n<tr>\n<td><code>language</code></td>\n<td>string</td>\n<td>No</td>\n<td><code>en</code>, <code>fr</code>, or <code>es</code>.</td>\n</tr>\n<tr>\n<td><code>phoneNumber</code></td>\n<td>string</td>\n<td>No</td>\n<td>Max 100 characters.</td>\n</tr>\n<tr>\n<td><code>notes</code></td>\n<td>string</td>\n<td>No</td>\n<td>Free-form notes shown to dispatchers.</td>\n</tr>\n</tbody>\n</table>\n</div><h4 id=\"response\">Response</h4>\n<p>Returns the updated customer object.</p>\n","auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{apiKey}}"}]},"isInherited":true,"source":{"_postman_id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","name":"ShuttleControl Open API","type":"collection"}},"urlObject":{"path":["v2","customers",":id"],"host":["{{hostname}}"],"query":[],"variable":[{"id":"113e5bf2-89ee-433b-bc68-445d9d4ea85f","description":{"content":"<p>UUID of the customer.</p>\n","type":"text/plain"},"type":"any","value":"","key":"id"}]}},"response":[{"id":"a8dadcd4-e199-48c6-9774-e4ae034e3c22","name":"Update Customer response","originalRequest":{"method":"PUT","header":[],"body":{"mode":"raw","raw":"{\n    \"firstName\": \"Charlie\",\n    \"lastName\": \"Adams\",\n    \"companyName\": \"ACME Inc.\",\n    \"language\": \"en\",\n    \"email\": \"\",\n    \"phoneNumber\": \"555 123 3456\"\n}","options":{"raw":{"language":"json"}}},"url":"{{hostname}}/v2/customers/"},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"content-length","value":"258"},{"key":"content-type","value":"application/json; charset=utf-8"}],"cookie":[],"responseTime":null,"body":"{\n    \"id\": \"e332506d-a290-4ddc-acca-0200d3eae63d\",\n    \"firstName\": \"Charlie\",\n    \"lastName\": \"Adams\",\n    \"companyName\": \"ACME Inc.\",\n    \"email\": \"\",\n    \"language\": \"en\",\n    \"phoneNumber\": \"555 123 3456\",\n    \"updatedBy\": \"7b5f6ea6-7b3a-4437-838a-9a31994aacb3\",\n    \"updatedAt\": \"2023-03-15T15:31:20.048Z\"\n}"}],"_postman_id":"1deea88e-0a5f-4b86-9820-9293a775141c"},{"name":"Archive Customer","id":"712568d4-31ff-492c-9104-2d591220103c","request":{"method":"DELETE","header":[],"url":"{{hostname}}/v2/customers/:id","description":"<p>Soft-deletes (archives) a customer. Responds <code>400</code> if the customer is already archived.</p>\n<p><strong>Required role:</strong> <code>ADMIN</code> or higher. An account API key always satisfies this (it authenticates as the account owner).</p>\n<h4 id=\"response\">Response</h4>\n<p>Responds <code>204 No Content</code>.</p>\n","auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{apiKey}}"}]},"isInherited":true,"source":{"_postman_id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","name":"ShuttleControl Open API","type":"collection"}},"urlObject":{"path":["v2","customers",":id"],"host":["{{hostname}}"],"query":[],"variable":[{"id":"81bd3704-dfe2-434d-8314-59f4d2c429f8","description":{"content":"<p>UUID of the customer.</p>\n","type":"text/plain"},"type":"any","value":"","key":"id"}]}},"response":[],"_postman_id":"712568d4-31ff-492c-9104-2d591220103c"},{"name":"Batch Archive Customers","id":"2855caca-6134-4f99-9f24-213d490cf1e0","request":{"method":"POST","header":[],"body":{"mode":"raw","raw":"{\n  \"customerIds\": [\n    \"e1f2a3b4-0000-0000-0000-000000000000\"\n  ]\n}","options":{"raw":{"language":"json"}}},"url":"{{hostname}}/v2/customers/batchArchive","description":"<p>Archives up to 50 customers in one call.</p>\n<p><strong>Required role:</strong> <code>ADMIN</code> or higher. An account API key always satisfies this (it authenticates as the account owner).</p>\n<h4 id=\"body-fields\">Body fields</h4>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Field</th>\n<th>Type</th>\n<th>Required</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>customerIds</code></td>\n<td>string[] (UUID)</td>\n<td>Yes</td>\n<td>1–50 customer ids to archive.</td>\n</tr>\n</tbody>\n</table>\n</div><h4 id=\"response\">Response</h4>\n<p>Responds <code>204 No Content</code>.</p>\n","auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{apiKey}}"}]},"isInherited":true,"source":{"_postman_id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","name":"ShuttleControl Open API","type":"collection"}},"urlObject":{"path":["v2","customers","batchArchive"],"host":["{{hostname}}"],"query":[],"variable":[]}},"response":[],"_postman_id":"2855caca-6134-4f99-9f24-213d490cf1e0"},{"name":"Batch Restore Customers","id":"742584ed-5d03-4d76-8aeb-31c933f8cc74","request":{"method":"POST","header":[],"body":{"mode":"raw","raw":"{\n  \"customerIds\": [\n    \"e1f2a3b4-0000-0000-0000-000000000000\"\n  ]\n}","options":{"raw":{"language":"json"}}},"url":"{{hostname}}/v2/customers/batchRestore","description":"<p>Restores up to 50 archived customers in one call.</p>\n<p><strong>Required role:</strong> <code>ADMIN</code> or higher. An account API key always satisfies this (it authenticates as the account owner).</p>\n<h4 id=\"body-fields\">Body fields</h4>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Field</th>\n<th>Type</th>\n<th>Required</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>customerIds</code></td>\n<td>string[] (UUID)</td>\n<td>Yes</td>\n<td>1–50 customer ids to restore.</td>\n</tr>\n</tbody>\n</table>\n</div><h4 id=\"response\">Response</h4>\n<p>Responds <code>204 No Content</code>.</p>\n","auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{apiKey}}"}]},"isInherited":true,"source":{"_postman_id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","name":"ShuttleControl Open API","type":"collection"}},"urlObject":{"path":["v2","customers","batchRestore"],"host":["{{hostname}}"],"query":[],"variable":[]}},"response":[],"_postman_id":"742584ed-5d03-4d76-8aeb-31c933f8cc74"},{"name":"Import Customers","id":"b8d825cf-41e6-4f90-951a-58bdaad409d5","request":{"method":"POST","header":[],"body":{"mode":"raw","raw":"{\n  \"storeId\": \"9f2d1c34-0000-0000-0000-000000000000\",\n  \"customers\": [\n    {\n      \"firstName\": \"Jane\",\n      \"lastName\": \"Doe\",\n      \"phoneNumber\": \"+1 514 555 0100\",\n      \"language\": \"en\",\n      \"email\": \"jane@example.com\",\n      \"address\": \"1 Main St, Montreal, QC\"\n    }\n  ]\n}","options":{"raw":{"language":"json"}}},"url":"{{hostname}}/v2/customers/import","description":"<p>Bulk-imports 1–10 000 customers into a store. The import runs asynchronously — the request returns immediately.</p>\n<p><strong>Required role:</strong> <code>ADMIN</code> or higher. An account API key always satisfies this (it authenticates as the account owner).</p>\n<h4 id=\"body-fields\">Body fields</h4>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Field</th>\n<th>Type</th>\n<th>Required</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>storeId</code></td>\n<td>string (UUID)</td>\n<td>Yes</td>\n<td>Target store.</td>\n</tr>\n<tr>\n<td><code>customers</code></td>\n<td>object[]</td>\n<td>Yes</td>\n<td>1–10 000 rows. Each row: <code>firstName</code> (required, ≤100), <code>lastName</code> (required, ≤100), <code>phoneNumber</code> (required, ≤100), <code>language</code> (required — <code>en</code></td>\n</tr>\n</tbody>\n</table>\n</div><h4 id=\"response\">Response</h4>\n<p>Responds <code>204 No Content</code>; the import continues in the background.</p>\n","auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{apiKey}}"}]},"isInherited":true,"source":{"_postman_id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","name":"ShuttleControl Open API","type":"collection"}},"urlObject":{"path":["v2","customers","import"],"host":["{{hostname}}"],"query":[],"variable":[]}},"response":[],"_postman_id":"b8d825cf-41e6-4f90-951a-58bdaad409d5"},{"name":"Start Customer Deduplication","id":"c1170f23-9c9f-494c-a1e2-0ddaba78d246","request":{"method":"POST","header":[],"body":{"mode":"raw","raw":"{\n  \"storeId\": \"9f2d1c34-0000-0000-0000-000000000000\"\n}","options":{"raw":{"language":"json"}}},"url":"{{hostname}}/v2/customers/deduplication","description":"<p>Starts a background scan that merges duplicate customers in a store and emails the caller a CSV report when done. Rate-limited: one run per user every 5 minutes (<code>429 CUSTOMER_DEDUPLICATION_COOLDOWN</code>).</p>\n<p><strong>Required role:</strong> <code>ADMIN</code> or higher. An account API key always satisfies this (it authenticates as the account owner).</p>\n<h4 id=\"body-fields\">Body fields</h4>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Field</th>\n<th>Type</th>\n<th>Required</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>storeId</code></td>\n<td>string (UUID)</td>\n<td>Yes</td>\n<td>The store to deduplicate.</td>\n</tr>\n</tbody>\n</table>\n</div><h4 id=\"response\">Response</h4>\n<p>Responds <code>202 Accepted</code> with a confirmation message.</p>\n","auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{apiKey}}"}]},"isInherited":true,"source":{"_postman_id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","name":"ShuttleControl Open API","type":"collection"}},"urlObject":{"path":["v2","customers","deduplication"],"host":["{{hostname}}"],"query":[],"variable":[]}},"response":[],"_postman_id":"c1170f23-9c9f-494c-a1e2-0ddaba78d246"},{"name":"Create Customer Place","id":"f1a39957-bd58-4b18-aed1-3c4f0676e915","request":{"method":"POST","header":[],"body":{"mode":"raw","raw":"{\n  \"customerId\": \"e1f2a3b4-0000-0000-0000-000000000000\",\n  \"address\": \"1 Main St, Montreal, QC\"\n}","options":{"raw":{"language":"json"}}},"url":"{{hostname}}/v2/customers/places","description":"<p>Saves an address as a place on a customer. The address is geocoded (or matched to an existing place of the store) and linked to the customer.</p>\n<h4 id=\"body-fields\">Body fields</h4>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Field</th>\n<th>Type</th>\n<th>Required</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>customerId</code></td>\n<td>string (UUID)</td>\n<td>Yes</td>\n<td>The customer to attach the place to.</td>\n</tr>\n<tr>\n<td><code>address</code></td>\n<td>string</td>\n<td>Yes</td>\n<td>The address, max 100 characters.</td>\n</tr>\n</tbody>\n</table>\n</div><h4 id=\"response\">Response</h4>\n<p>Responds <code>201</code> with the place when newly linked, or <code>204</code> when the customer already had it.</p>\n","auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{apiKey}}"}]},"isInherited":true,"source":{"_postman_id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","name":"ShuttleControl Open API","type":"collection"}},"urlObject":{"path":["v2","customers","places"],"host":["{{hostname}}"],"query":[],"variable":[]}},"response":[{"id":"fe92cf18-0212-4b80-b6ea-fb8c734a5d0d","name":"Create Customer Place response","originalRequest":{"method":"POST","header":[],"body":{"mode":"raw","raw":"{\n    \"customerId\": \"66d6c31b-c499-413f-8ad4-cb227ff9f631\",\n    \"address\": \"1234 Rue Du Fort, Montréal, Quebec H3H 2B3, Canada\"\n}","options":{"raw":{"language":"json"}}},"url":"{{hostname}}/v2/customers/places"},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Access-Control-Allow-Origin","value":"*"},{"key":"Content-Security-Policy","value":"default-src 'self';base-uri 'self';font-src 'self' https: data:;form-action 'self';frame-ancestors 'self';img-src 'self' data:;object-src 'none';script-src 'self';script-src-attr 'none';style-src 'self' https: 'unsafe-inline';upgrade-insecure-requests"},{"key":"Cross-Origin-Embedder-Policy","value":"require-corp"},{"key":"Cross-Origin-Opener-Policy","value":"same-origin"},{"key":"X-DNS-Prefetch-Control","value":"off"},{"key":"X-Frame-Options","value":"SAMEORIGIN"},{"key":"Strict-Transport-Security","value":"max-age=15552000; includeSubDomains"},{"key":"X-Download-Options","value":"noopen"},{"key":"X-Content-Type-Options","value":"nosniff"},{"key":"Origin-Agent-Cluster","value":"?1"},{"key":"X-Permitted-Cross-Domain-Policies","value":"none"},{"key":"Referrer-Policy","value":"no-referrer"},{"key":"X-XSS-Protection","value":"0"},{"key":"Location","value":"https://api.shuttlecontrol.com/v2/places/5df30529-3a04-4fed-9c07-6836ac1db11d"},{"key":"Content-Type","value":"application/json; charset=utf-8"},{"key":"Content-Length","value":"148"},{"key":"ETag","value":"W/\"94-ur3QlWO57GyxCALKWb5EOi83E/8\""},{"key":"Vary","value":"Accept-Encoding"},{"key":"Date","value":"Tue, 12 Mar 2024 17:47:08 GMT"},{"key":"Connection","value":"keep-alive"},{"key":"Keep-Alive","value":"timeout=5"}],"cookie":[],"responseTime":null,"body":"{\n    \"id\": \"5df30529-3a04-4fed-9c07-6836ac1db11d\",\n    \"address\": \"1234 Rue Du Fort, Montréal, Quebec H3H 2B3, Canada\",\n    \"createdAt\": \"2024-03-12T17:09:09.907Z\"\n}"}],"_postman_id":"f1a39957-bd58-4b18-aed1-3c4f0676e915"},{"name":"Delete Customer Place","id":"64cf1724-a29b-4846-b605-f36bfacea377","request":{"method":"DELETE","header":[],"url":"{{hostname}}/v2/customers/:customerId/places/:placeId","description":"<p>Unlinks a saved place from a customer. The place itself is not deleted.</p>\n<h4 id=\"response\">Response</h4>\n<p>Responds <code>204 No Content</code>.</p>\n","auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{apiKey}}"}]},"isInherited":true,"source":{"_postman_id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","name":"ShuttleControl Open API","type":"collection"}},"urlObject":{"path":["v2","customers",":customerId","places",":placeId"],"host":["{{hostname}}"],"query":[],"variable":[{"id":"06a1868f-e761-4f41-bb19-3380856988ac","description":{"content":"<p>UUID of the customer.</p>\n","type":"text/plain"},"type":"any","value":"","key":"customerId"},{"id":"c4e8ecce-666b-45db-97c0-7fd03ce0c0ff","description":{"content":"<p>UUID of the place to unlink.</p>\n","type":"text/plain"},"type":"any","value":"","key":"placeId"}]}},"response":[{"id":"badfcd13-e958-4649-9e04-07338bd8c6ef","name":"Delete Customer Place response","originalRequest":{"method":"DELETE","header":[],"url":"{{hostname}}/v2/customers//places/"},"status":"No Content","code":204,"_postman_previewlanguage":"plain","header":[{"key":"Access-Control-Allow-Origin","value":"*"},{"key":"Content-Security-Policy","value":"default-src 'self';base-uri 'self';font-src 'self' https: data:;form-action 'self';frame-ancestors 'self';img-src 'self' data:;object-src 'none';script-src 'self';script-src-attr 'none';style-src 'self' https: 'unsafe-inline';upgrade-insecure-requests"},{"key":"Cross-Origin-Embedder-Policy","value":"require-corp"},{"key":"Cross-Origin-Opener-Policy","value":"same-origin"},{"key":"X-DNS-Prefetch-Control","value":"off"},{"key":"X-Frame-Options","value":"SAMEORIGIN"},{"key":"Strict-Transport-Security","value":"max-age=15552000; includeSubDomains"},{"key":"X-Download-Options","value":"noopen"},{"key":"X-Content-Type-Options","value":"nosniff"},{"key":"Origin-Agent-Cluster","value":"?1"},{"key":"X-Permitted-Cross-Domain-Policies","value":"none"},{"key":"Referrer-Policy","value":"no-referrer"},{"key":"X-XSS-Protection","value":"0"},{"key":"Date","value":"Tue, 12 Mar 2024 17:58:12 GMT"},{"key":"Connection","value":"keep-alive"},{"key":"Keep-Alive","value":"timeout=5"}],"cookie":[],"responseTime":null,"body":null}],"_postman_id":"64cf1724-a29b-4846-b605-f36bfacea377"}],"id":"c240f06f-2c5e-45ae-9987-7e3431d831ca","description":"<p>The people you shuttle. Customers belong to a store and can hold multiple saved places.</p>\n","_postman_id":"c240f06f-2c5e-45ae-9987-7e3431d831ca","auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{apiKey}}"}]},"isInherited":true,"source":{"_postman_id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","name":"ShuttleControl Open API","type":"collection"}}},{"name":"CustomerReviews","item":[{"name":"List CustomerReviews","id":"3e259b60-71df-48f1-9887-712d3a7ebac2","request":{"method":"GET","header":[],"url":"{{hostname}}/v2/customerReviews?page=0&size=10","description":"<p>Returns a paginated list of reviews for the caller’s stores, with rich filtering and sorting.</p>\n<h4 id=\"response\">Response</h4>\n<p>Returns <code>{ items, count }</code> — each item includes <code>rating</code>, <code>comment</code>, <code>createdAt</code>, and the associated trip (customer, store, drivers, workflow, dispatcher).</p>\n","auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{apiKey}}"}]},"isInherited":true,"source":{"_postman_id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","name":"ShuttleControl Open API","type":"collection"}},"urlObject":{"path":["v2","customerReviews"],"host":["{{hostname}}"],"query":[{"description":{"content":"<p>Zero-based page index. Default <code>0</code>.</p>\n","type":"text/plain"},"key":"page","value":"0"},{"description":{"content":"<p>Page size, 1–100. Default <code>10</code>.</p>\n","type":"text/plain"},"key":"size","value":"10"},{"disabled":true,"description":{"content":"<p>Filter to one store.</p>\n","type":"text/plain"},"key":"storeId","value":""},{"disabled":true,"description":{"content":"<p>ISO 8601 window start (with <code>endDate</code>).</p>\n","type":"text/plain"},"key":"startDate","value":""},{"disabled":true,"description":{"content":"<p>ISO 8601 window end (with <code>startDate</code>).</p>\n","type":"text/plain"},"key":"endDate","value":""},{"disabled":true,"description":{"content":"<p>Filter by the dispatcher who created the trip.</p>\n","type":"text/plain"},"key":"dispatcherId","value":""},{"disabled":true,"description":{"content":"<p>Filter by an assigned driver.</p>\n","type":"text/plain"},"key":"driverId","value":""},{"disabled":true,"description":{"content":"<p>Filter by workflow.</p>\n","type":"text/plain"},"key":"workflowId","value":""},{"disabled":true,"description":{"content":"<p>Free-text search (max 100) over trip reference, customer name/phone, and review comment.</p>\n","type":"text/plain"},"key":"search","value":""},{"disabled":true,"description":{"content":"<p>Exact rating filter, 1–5.</p>\n","type":"text/plain"},"key":"rating","value":""},{"disabled":true,"description":{"content":"<p><code>recent</code> (default) | <code>highest</code> | <code>lowest</code>.</p>\n","type":"text/plain"},"key":"sort","value":"recent"}],"variable":[]}},"response":[{"id":"c6474edb-15c7-4e28-b338-aac1e242e8e3","name":"List CustomerReviews response","originalRequest":{"method":"GET","header":[],"url":{"raw":"{{hostname}}/v2/customerReviews?page=0&size=5","host":["{{hostname}}"],"path":["v2","customerReviews"],"query":[{"key":"page","value":"0"},{"key":"size","value":"5"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"content-length","value":"622"},{"key":"content-type","value":"application/json; charset=utf-8"}],"cookie":[],"responseTime":null,"body":"{\n    \"items\": [\n        {\n            \"customer\": {\n                \"id\": \"dc697ec3-18ef-4479-8670-154b0a4a776a\",\n                \"firstName\": \"Jamie\",\n                \"lastName\": \"Tremblay\",\n                \"email\": \"\"\n            },\n            \"store\": {\n                \"id\": \"f1a04c8a-dc36-4203-9a9e-698e06cf7cef\",\n                \"name\": \"Alpha Store\"\n            },\n            \"workflow\": {\n                \"id\": \"117c7103-275e-4a18-ba2a-0556331fc408\",\n                \"name\": \"Shuttle Pickup\"\n            },\n            \"customerReview\": {\n                \"id\": \"a60f3fa6-70b2-4ca6-b349-169ef73dc38a\",\n                \"rating\": 4.5,\n                \"comment\": \"Thank you for such a wonderful shuttle experience!\",\n                \"createdAt\": \"2023-03-16T15:02:21.435Z\"\n            },\n            \"drivers\": [],\n            \"createdBy\": {\n                \"id\": \"7b5f6ea6-7b3a-4437-838a-9a31994aacb3\",\n                \"firstName\": \"Edward\",\n                \"lastName\": \"Maxedon\",\n                \"email\": \"edward+owner@shuttlecontrol.com\"\n            }\n        }\n    ],\n    \"count\": 1\n}"}],"_postman_id":"3e259b60-71df-48f1-9887-712d3a7ebac2"},{"name":"Get Customer Review","id":"722ea09f-807d-42cf-8691-9d4a7a66cfdb","request":{"method":"GET","header":[],"url":"{{hostname}}/v2/customerReviews/:id","description":"<p>Returns a single review.</p>\n<h4 id=\"response\">Response</h4>\n<p>Returns <code>{ id, trip: { id }, rating, comment, createdAt }</code>.</p>\n","auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{apiKey}}"}]},"isInherited":true,"source":{"_postman_id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","name":"ShuttleControl Open API","type":"collection"}},"urlObject":{"path":["v2","customerReviews",":id"],"host":["{{hostname}}"],"query":[],"variable":[{"id":"d8782182-c3dd-4909-a910-bf79d803b61e","description":{"content":"<p>UUID of the review.</p>\n","type":"text/plain"},"type":"any","value":"","key":"id"}]}},"response":[{"id":"56f66523-0bba-4528-828b-6b1475d998a4","name":"Get Customer Review","originalRequest":{"method":"GET","header":[],"url":"{{hostname}}/v2/customerReviews/"},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Access-Control-Allow-Origin","value":"*"},{"key":"Content-Security-Policy","value":"default-src 'self';base-uri 'self';font-src 'self' https: data:;form-action 'self';frame-ancestors 'self';img-src 'self' data:;object-src 'none';script-src 'self';script-src-attr 'none';style-src 'self' https: 'unsafe-inline';upgrade-insecure-requests"},{"key":"Cross-Origin-Embedder-Policy","value":"require-corp"},{"key":"Cross-Origin-Opener-Policy","value":"same-origin"},{"key":"X-DNS-Prefetch-Control","value":"off"},{"key":"X-Frame-Options","value":"SAMEORIGIN"},{"key":"Strict-Transport-Security","value":"max-age=15552000; includeSubDomains"},{"key":"X-Download-Options","value":"noopen"},{"key":"X-Content-Type-Options","value":"nosniff"},{"key":"Origin-Agent-Cluster","value":"?1"},{"key":"X-Permitted-Cross-Domain-Policies","value":"none"},{"key":"Referrer-Policy","value":"no-referrer"},{"key":"X-XSS-Protection","value":"0"},{"key":"Content-Type","value":"application/json; charset=utf-8"},{"key":"Content-Length","value":"213"},{"key":"ETag","value":"W/\"d5-7xXAVndLZ3s/l98j1l6g1u3xXLA\""},{"key":"Vary","value":"Accept-Encoding"},{"key":"Date","value":"Fri, 15 Mar 2024 13:31:14 GMT"},{"key":"Connection","value":"keep-alive"},{"key":"Keep-Alive","value":"timeout=5"}],"cookie":[],"responseTime":null,"body":"{\n    \"id\": \"b4fe0812-c81e-42b7-a07e-d2a9a22df085\",\n    \"trip\": {\n        \"id\": \"5b223143-15a1-47d5-aacf-8164ddb030eb\"\n    },\n    \"rating\": 4.5,\n    \"comment\": \"Thank you for such a wonderful shuttle experience!\",\n    \"createdAt\": \"2024-03-15T13:25:42.597Z\"\n}"}],"_postman_id":"722ea09f-807d-42cf-8691-9d4a7a66cfdb"},{"name":"Get Driver Rating","id":"6c6074bd-9a0a-4099-8966-70e32df8c34a","request":{"method":"GET","header":[],"url":"{{hostname}}/v2/customerReviews/rating/:driverId/:limit","description":"<p>Returns a driver’s average rating over their most recent reviews.</p>\n<h4 id=\"response\">Response</h4>\n<p>Returns <code>{ rating }</code> — a number rounded to one decimal, or <code>null</code> when the driver has no reviews.</p>\n","auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{apiKey}}"}]},"isInherited":true,"source":{"_postman_id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","name":"ShuttleControl Open API","type":"collection"}},"urlObject":{"path":["v2","customerReviews","rating",":driverId",":limit"],"host":["{{hostname}}"],"query":[],"variable":[{"id":"2ed7ca15-b9f4-4043-bff7-7a01a359ae67","description":{"content":"<p>UUID of the driver.</p>\n","type":"text/plain"},"type":"any","value":"","key":"driverId"},{"id":"8ef71e9a-82a9-496f-a3c5-337e5b2fb598","description":{"content":"<p>How many most-recent reviews to average (integer ≥ 1).</p>\n","type":"text/plain"},"type":"any","value":"25","key":"limit"}]}},"response":[],"_postman_id":"6c6074bd-9a0a-4099-8966-70e32df8c34a"},{"name":"Review Analytics","id":"f2fa50e3-60de-419f-8e61-affa46ab1f0f","request":{"method":"GET","header":[],"url":"{{hostname}}/v2/customerReviews/analytics?startDate=2026-07-01T00:00:00.000Z&endDate=2026-07-31T23:59:59.000Z&granularity=day&timezoneOffset=-240","description":"<p>Returns per-store review-rating time series (bucketed by the chosen granularity) plus an aggregate, for the given window.</p>\n<h4 id=\"response\">Response</h4>\n<p>Returns <code>{ stores: [{ name, color, data }], aggregate }</code>.</p>\n","auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{apiKey}}"}]},"isInherited":true,"source":{"_postman_id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","name":"ShuttleControl Open API","type":"collection"}},"urlObject":{"path":["v2","customerReviews","analytics"],"host":["{{hostname}}"],"query":[{"description":{"content":"<p>Required. ISO 8601 window start.</p>\n","type":"text/plain"},"key":"startDate","value":"2026-07-01T00:00:00.000Z"},{"description":{"content":"<p>Required. ISO 8601 window end.</p>\n","type":"text/plain"},"key":"endDate","value":"2026-07-31T23:59:59.000Z"},{"description":{"content":"<p>Required. <code>day</code> | <code>week</code> | <code>month</code>.</p>\n","type":"text/plain"},"key":"granularity","value":"day"},{"description":{"content":"<p>Required. Caller’s UTC offset in minutes.</p>\n","type":"text/plain"},"key":"timezoneOffset","value":"-240"},{"disabled":true,"description":{"content":"<p>Filter to one store.</p>\n","type":"text/plain"},"key":"storeId","value":""},{"disabled":true,"description":{"content":"<p>Filter by creating dispatcher.</p>\n","type":"text/plain"},"key":"dispatcherId","value":""},{"disabled":true,"description":{"content":"<p>Filter by an assigned driver.</p>\n","type":"text/plain"},"key":"driverId","value":""},{"disabled":true,"description":{"content":"<p>Filter by workflow.</p>\n","type":"text/plain"},"key":"workflowId","value":""},{"disabled":true,"description":{"content":"<p>Free-text search (max 100).</p>\n","type":"text/plain"},"key":"search","value":""},{"disabled":true,"description":{"content":"<p>Exact rating filter, 1–5.</p>\n","type":"text/plain"},"key":"rating","value":""}],"variable":[]}},"response":[],"_postman_id":"f2fa50e3-60de-419f-8e61-affa46ab1f0f"},{"name":"Delete Customer Review","id":"8d6c5b01-7359-416a-802a-8c95cb0386ba","request":{"method":"DELETE","header":[],"url":"{{hostname}}/v2/customerReviews/:id","description":"<p>Permanently deletes a review.</p>\n<p><strong>Required role:</strong> <code>ADMIN</code> or higher. An account API key always satisfies this (it authenticates as the account owner).</p>\n<h4 id=\"response\">Response</h4>\n<p>Responds <code>204 No Content</code>.</p>\n","auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{apiKey}}"}]},"isInherited":true,"source":{"_postman_id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","name":"ShuttleControl Open API","type":"collection"}},"urlObject":{"path":["v2","customerReviews",":id"],"host":["{{hostname}}"],"query":[],"variable":[{"id":"bd6a2d00-9173-4048-b57f-095fadb9d8e6","description":{"content":"<p>UUID of the review.</p>\n","type":"text/plain"},"type":"any","value":"","key":"id"}]}},"response":[{"id":"0b6291c8-cf16-437f-9e76-5ec77bd2dc89","name":"Delete Customer Review","originalRequest":{"method":"DELETE","header":[],"url":"{{hostname}}/v2/customerReviews/"},"status":"No Content","code":204,"_postman_previewlanguage":"plain","header":[{"key":"Access-Control-Allow-Origin","value":"*"},{"key":"Content-Security-Policy","value":"default-src 'self';base-uri 'self';font-src 'self' https: data:;form-action 'self';frame-ancestors 'self';img-src 'self' data:;object-src 'none';script-src 'self';script-src-attr 'none';style-src 'self' https: 'unsafe-inline';upgrade-insecure-requests"},{"key":"Cross-Origin-Embedder-Policy","value":"require-corp"},{"key":"Cross-Origin-Opener-Policy","value":"same-origin"},{"key":"X-DNS-Prefetch-Control","value":"off"},{"key":"X-Frame-Options","value":"SAMEORIGIN"},{"key":"Strict-Transport-Security","value":"max-age=15552000; includeSubDomains"},{"key":"X-Download-Options","value":"noopen"},{"key":"X-Content-Type-Options","value":"nosniff"},{"key":"Origin-Agent-Cluster","value":"?1"},{"key":"X-Permitted-Cross-Domain-Policies","value":"none"},{"key":"Referrer-Policy","value":"no-referrer"},{"key":"X-XSS-Protection","value":"0"},{"key":"Date","value":"Fri, 15 Mar 2024 13:50:11 GMT"},{"key":"Connection","value":"keep-alive"},{"key":"Keep-Alive","value":"timeout=5"}],"cookie":[],"responseTime":null,"body":null}],"_postman_id":"8d6c5b01-7359-416a-802a-8c95cb0386ba"}],"id":"0ac1d96a-9146-42a4-905c-29df490d722c","description":"<p>Star ratings (1–5) and comments customers leave after completed trips. Reviews are created by customers from the trip-tracking page; through the API you can list, analyze, and moderate them.</p>\n","_postman_id":"0ac1d96a-9146-42a4-905c-29df490d722c","auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{apiKey}}"}]},"isInherited":true,"source":{"_postman_id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","name":"ShuttleControl Open API","type":"collection"}}},{"name":"Places","item":[{"name":"Create Favorite Place","id":"7c2dd22d-1290-42d8-b8c0-23555f29eca9","request":{"method":"POST","header":[],"body":{"mode":"raw","raw":"{\n  \"storeId\": \"9f2d1c34-0000-0000-0000-000000000000\",\n  \"address\": \"900 Airport Rd, Dorval, QC\"\n}","options":{"raw":{"language":"json"}}},"url":"{{hostname}}/v2/places","description":"<p>Geocodes an address and saves it as a favorite place of a store.</p>\n<h4 id=\"body-fields\">Body fields</h4>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Field</th>\n<th>Type</th>\n<th>Required</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>storeId</code></td>\n<td>string (UUID)</td>\n<td>Yes</td>\n<td>The store the place belongs to.</td>\n</tr>\n<tr>\n<td><code>address</code></td>\n<td>string</td>\n<td>Yes</td>\n<td>The address, max 100 characters.</td>\n</tr>\n</tbody>\n</table>\n</div><h4 id=\"response\">Response</h4>\n<p>Responds <code>201</code> with the created place (<code>id</code>, <code>address</code>, <code>latitude</code>, <code>longitude</code>, <code>isFavorite</code>).</p>\n","auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{apiKey}}"}]},"isInherited":true,"source":{"_postman_id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","name":"ShuttleControl Open API","type":"collection"}},"urlObject":{"path":["v2","places"],"host":["{{hostname}}"],"query":[],"variable":[]}},"response":[],"_postman_id":"7c2dd22d-1290-42d8-b8c0-23555f29eca9"},{"name":"List Places","id":"3341788c-eba8-4942-9a80-19da530fbe22","request":{"method":"GET","header":[],"url":"{{hostname}}/v2/places/list?page=0&size=10","description":"<p>Returns a paginated list of favorite places, including which workflows use each place.</p>\n<h4 id=\"response\">Response</h4>\n<p>Returns <code>{ items, count }</code> — each item includes <code>store.name</code> and <code>workflowSteps[].workflow</code> references.</p>\n","auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{apiKey}}"}]},"isInherited":true,"source":{"_postman_id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","name":"ShuttleControl Open API","type":"collection"}},"urlObject":{"path":["v2","places","list"],"host":["{{hostname}}"],"query":[{"description":{"content":"<p>Zero-based page index. Default <code>0</code>.</p>\n","type":"text/plain"},"key":"page","value":"0"},{"description":{"content":"<p>Page size, 1–100. Default <code>10</code>.</p>\n","type":"text/plain"},"key":"size","value":"10"},{"disabled":true,"description":{"content":"<p>Case-insensitive substring match on the address.</p>\n","type":"text/plain"},"key":"search","value":""},{"disabled":true,"description":{"content":"<p>Filter to one store. Default: all visible stores.</p>\n","type":"text/plain"},"key":"storeId","value":""}],"variable":[]}},"response":[{"id":"e45d26e1-93a4-4120-b84b-b1f82fdeefdf","name":"List Places response","originalRequest":{"method":"GET","header":[],"url":{"raw":"{{hostname}}/v2/places?page=0&size=5&storeId=","host":["{{hostname}}"],"path":["v2","places"],"query":[{"key":"page","value":"0"},{"key":"size","value":"5"},{"key":"storeId","value":""}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"content-length","value":"401"},{"key":"content-type","value":"application/json; charset=utf-8"}],"cookie":[],"responseTime":null,"body":"[\n    {\n        \"id\": \"b6f8a2de-1fbf-4276-a4c3-269fdd25735d\",\n        \"address\": \"3901 Rue Bannantyne, Verdun, QC H4G 1C2\",\n        \"latitude\": 45.4651011,\n        \"longitude\": -73.5759264,\n        \"isFavorite\": true,\n        \"createdAt\": \"2023-04-06T17:07:28.032Z\"\n    },\n    {\n        \"id\": \"8cbe98a0-0838-4994-a9ff-38970798f8d9\",\n        \"address\": \"Saint Joseph's Oratory of Mount Royal\",\n        \"latitude\": 45.4919122,\n        \"longitude\": -73.6186555,\n        \"isFavorite\": true,\n        \"createdAt\": \"2023-04-05T14:18:11.960Z\"\n    }\n]"}],"_postman_id":"3341788c-eba8-4942-9a80-19da530fbe22"},{"name":"List All Places","id":"079546a0-6144-4e74-be2b-d697cab6270d","request":{"method":"GET","header":[],"url":"{{hostname}}/v2/places?storeId=","description":"<p>Returns all favorite places of a store (non-paginated), newest first.</p>\n<h4 id=\"response\">Response</h4>\n<p>Returns an array of <code>{ id, address, latitude, longitude, isFavorite, createdAt }</code>.</p>\n","auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{apiKey}}"}]},"isInherited":true,"source":{"_postman_id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","name":"ShuttleControl Open API","type":"collection"}},"urlObject":{"path":["v2","places"],"host":["{{hostname}}"],"query":[{"description":{"content":"<p>Required. The store whose favorite places to return.</p>\n","type":"text/plain"},"key":"storeId","value":""}],"variable":[]}},"response":[{"id":"a36b1e81-0ad1-4740-8e06-3c60c336b56d","name":"List All Places response","originalRequest":{"method":"GET","header":[],"url":{"raw":"{{hostname}}/v2/places?storeId=","host":["{{hostname}}"],"path":["v2","places"],"query":[{"key":"storeId","value":""}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Access-Control-Allow-Origin","value":"*"},{"key":"Content-Security-Policy","value":"default-src 'self';base-uri 'self';font-src 'self' https: data:;form-action 'self';frame-ancestors 'self';img-src 'self' data:;object-src 'none';script-src 'self';script-src-attr 'none';style-src 'self' https: 'unsafe-inline';upgrade-insecure-requests"},{"key":"Cross-Origin-Embedder-Policy","value":"require-corp"},{"key":"Cross-Origin-Opener-Policy","value":"same-origin"},{"key":"X-DNS-Prefetch-Control","value":"off"},{"key":"X-Frame-Options","value":"SAMEORIGIN"},{"key":"Strict-Transport-Security","value":"max-age=15552000; includeSubDomains"},{"key":"X-Download-Options","value":"noopen"},{"key":"X-Content-Type-Options","value":"nosniff"},{"key":"Origin-Agent-Cluster","value":"?1"},{"key":"X-Permitted-Cross-Domain-Policies","value":"none"},{"key":"Referrer-Policy","value":"no-referrer"},{"key":"X-XSS-Protection","value":"0"},{"key":"Content-Type","value":"application/json; charset=utf-8"},{"key":"Content-Length","value":"200"},{"key":"ETag","value":"W/\"c8-8GAF5cIq+mtF5vZuTb7myKHdWr8\""},{"key":"Vary","value":"Accept-Encoding"},{"key":"Date","value":"Mon, 18 Mar 2024 18:53:34 GMT"},{"key":"Connection","value":"keep-alive"},{"key":"Keep-Alive","value":"timeout=5"}],"cookie":[],"responseTime":null,"body":"[\n    {\n        \"id\": \"828fc62a-f64c-4ba6-a525-4165d1a7846f\",\n        \"address\": \"Saint Joseph's Oratory of Mount Royal\",\n        \"latitude\": 45.4919122,\n        \"longitude\": -73.6186555,\n        \"isFavorite\": true,\n        \"createdAt\": \"2024-03-14T19:06:04.251Z\"\n    }\n]"}],"_postman_id":"079546a0-6144-4e74-be2b-d697cab6270d"},{"name":"Get Place","id":"9755d187-f772-4423-b2ea-e47de55ed009","request":{"method":"GET","header":[],"url":"{{hostname}}/v2/places/:id","description":"<p>Returns a single place.</p>\n<h4 id=\"response\">Response</h4>\n<p>Returns the place object.</p>\n","auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{apiKey}}"}]},"isInherited":true,"source":{"_postman_id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","name":"ShuttleControl Open API","type":"collection"}},"urlObject":{"path":["v2","places",":id"],"host":["{{hostname}}"],"query":[],"variable":[{"id":"dac56cba-5f57-452c-a580-a90e56b629ef","description":{"content":"<p>UUID of the place.</p>\n","type":"text/plain"},"type":"any","value":"","key":"id"}]}},"response":[{"id":"c167f24b-cbcf-4b11-a25a-9768c03fa135","name":"Get Place response","originalRequest":{"method":"GET","header":[],"url":"{{hostname}}/v2/places/"},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Access-Control-Allow-Origin","value":"*"},{"key":"Content-Security-Policy","value":"default-src 'self';base-uri 'self';font-src 'self' https: data:;form-action 'self';frame-ancestors 'self';img-src 'self' data:;object-src 'none';script-src 'self';script-src-attr 'none';style-src 'self' https: 'unsafe-inline';upgrade-insecure-requests"},{"key":"Cross-Origin-Embedder-Policy","value":"require-corp"},{"key":"Cross-Origin-Opener-Policy","value":"same-origin"},{"key":"X-DNS-Prefetch-Control","value":"off"},{"key":"X-Frame-Options","value":"SAMEORIGIN"},{"key":"Strict-Transport-Security","value":"max-age=15552000; includeSubDomains"},{"key":"X-Download-Options","value":"noopen"},{"key":"X-Content-Type-Options","value":"nosniff"},{"key":"Origin-Agent-Cluster","value":"?1"},{"key":"X-Permitted-Cross-Domain-Policies","value":"none"},{"key":"Referrer-Policy","value":"no-referrer"},{"key":"X-XSS-Protection","value":"0"},{"key":"Content-Type","value":"application/json; charset=utf-8"},{"key":"Content-Length","value":"255"},{"key":"ETag","value":"W/\"ff-eOZLS0iHuDtmKbhzTY0S/ISdxxE\""},{"key":"Vary","value":"Accept-Encoding"},{"key":"Date","value":"Mon, 18 Mar 2024 18:54:41 GMT"},{"key":"Connection","value":"keep-alive"},{"key":"Keep-Alive","value":"timeout=5"}],"cookie":[],"responseTime":null,"body":"{\n    \"id\": \"828fc62a-f64c-4ba6-a525-4165d1a7846f\",\n    \"address\": \"Saint Joseph's Oratory of Mount Royal\",\n    \"latitude\": 45.4919122,\n    \"longitude\": -73.6186555,\n    \"store\": {\n        \"id\": \"e81f65c4-5cf7-4339-b6f8-437bc9cd42b7\",\n        \"name\": \"Alpha Store\"\n    },\n    \"createdAt\": \"2024-03-14T19:06:04.251Z\"\n}"}],"_postman_id":"9755d187-f772-4423-b2ea-e47de55ed009"},{"name":"Favorite Place","id":"0f37d7e4-021a-487c-856b-46f4bf1c24df","request":{"method":"POST","header":[],"url":"{{hostname}}/v2/places/favorite/:id","description":"<p>Marks an existing place as a favorite of its store.</p>\n<h4 id=\"response\">Response</h4>\n<p>Returns the place object with <code>isFavorite: true</code>.</p>\n","auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{apiKey}}"}]},"isInherited":true,"source":{"_postman_id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","name":"ShuttleControl Open API","type":"collection"}},"urlObject":{"path":["v2","places","favorite",":id"],"host":["{{hostname}}"],"query":[],"variable":[{"id":"5f74480d-0cf0-42a7-9028-ee4b77701323","description":{"content":"<p>UUID of the place.</p>\n","type":"text/plain"},"type":"any","value":"","key":"id"}]}},"response":[{"id":"933e4671-102c-4bb6-9dd4-cf138317cbd7","name":"Favorite Place response","originalRequest":{"method":"POST","header":[],"url":"{{hostname}}/v2/places/favorite/"},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"content-length","value":"275"},{"key":"content-type","value":"application/json; charset=utf-8"}],"cookie":[],"responseTime":null,"body":"{\n    \"id\": \"b6f8a2de-1fbf-4276-a4c3-269fdd25735d\",\n    \"address\": \"3901 Rue Bannantyne, Verdun, QC H4G 1C2\",\n    \"latitude\": 45.4651011,\n    \"longitude\": -73.5759264,\n    \"store\": {\n        \"id\": \"0b8a26d9-14f3-40ae-8d44-681e0b5c381a\",\n        \"name\": \"Alpha Store\"\n    },\n    \"createdAt\": \"2023-04-06T17:07:28.032Z\",\n    \"isFavorite\": true\n}"}],"_postman_id":"0f37d7e4-021a-487c-856b-46f4bf1c24df"},{"name":"Unfavorite Place","id":"889f46be-fa32-4381-b72b-db4726e298ee","request":{"method":"DELETE","header":[],"url":"{{hostname}}/v2/places/:id","description":"<p>Removes a place from the store’s favorites. Rejected while any workflow step uses the place (<code>400 PLACE_HAS_WORKFLOW</code>). The place itself is kept (it may be referenced by past trips).</p>\n<h4 id=\"response\">Response</h4>\n<p>Responds <code>204 No Content</code>.</p>\n","auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{apiKey}}"}]},"isInherited":true,"source":{"_postman_id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","name":"ShuttleControl Open API","type":"collection"}},"urlObject":{"path":["v2","places",":id"],"host":["{{hostname}}"],"query":[],"variable":[{"id":"8f6d50fa-5038-497c-8e0a-232a37cf95a6","description":{"content":"<p>UUID of the place.</p>\n","type":"text/plain"},"type":"any","value":"","key":"id"}]}},"response":[{"id":"bb9682fb-edf6-4e47-8bf8-8f1af3f0b041","name":"Unfavorite Place response","originalRequest":{"method":"DELETE","header":[],"url":"{{hostname}}/v2/places/"},"status":"No Content","code":204,"_postman_previewlanguage":"plain","header":[],"cookie":[],"responseTime":null,"body":null}],"_postman_id":"889f46be-fa32-4381-b72b-db4726e298ee"},{"name":"List Favorite Places by Kiosk","id":"1107c022-ea05-4f66-a5b5-9543cf56d8d2","request":{"method":"GET","header":[],"url":"{{hostname}}/v2/places/favorites/:kioskShortUrl","description":"<p>Returns the favorite places of the store that owns the given kiosk — the destination quick-picks shown on that kiosk.</p>\n<h4 id=\"response\">Response</h4>\n<p>Returns an array of <code>{ id, address, latitude, longitude, isFavorite, createdAt }</code>.</p>\n","auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{apiKey}}"}]},"isInherited":true,"source":{"_postman_id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","name":"ShuttleControl Open API","type":"collection"}},"urlObject":{"path":["v2","places","favorites",":kioskShortUrl"],"host":["{{hostname}}"],"query":[],"variable":[{"id":"3a848eb1-c6ea-4f02-8c28-d071531deabb","description":{"content":"<p>The kiosk’s short URL code (max 10 characters).</p>\n","type":"text/plain"},"type":"any","value":"","key":"kioskShortUrl"}]}},"response":[],"_postman_id":"1107c022-ea05-4f66-a5b5-9543cf56d8d2"}],"id":"f57f6d4b-ba5e-44e0-8d03-e4bf6f3743ea","description":"<p>Geocoded addresses. “Favorite” places belong to a store and appear as quick-pick destinations; customers also hold their own saved places (see the Customers folder).</p>\n","_postman_id":"f57f6d4b-ba5e-44e0-8d03-e4bf6f3743ea","auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{apiKey}}"}]},"isInherited":true,"source":{"_postman_id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","name":"ShuttleControl Open API","type":"collection"}}},{"name":"Zones","item":[{"name":"Create Zone","id":"780153f5-f470-46ff-9dca-bdc7db6418d1","request":{"method":"POST","header":[],"body":{"mode":"raw","raw":"{\n  \"name\": \"Downtown\",\n  \"geometry\": \"{\\\"type\\\":\\\"Polygon\\\",\\\"coordinates\\\":[[[-73.58,45.49],[-73.55,45.49],[-73.55,45.51],[-73.58,45.51],[-73.58,45.49]]]}\",\n  \"color\": \"#1677ff\",\n  \"storeIds\": [\n    \"9f2d1c34-0000-0000-0000-000000000000\"\n  ],\n  \"restricted\": false\n}","options":{"raw":{"language":"json"}}},"url":"{{hostname}}/v2/zones","description":"<p>Creates a zone and assigns it to one or more stores. Existing active trips whose places fall inside the polygon are tagged with the new zone automatically.</p>\n<p><strong>Required role:</strong> <code>ADMIN</code> or higher. An account API key always satisfies this (it authenticates as the account owner).</p>\n<h4 id=\"body-fields\">Body fields</h4>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Field</th>\n<th>Type</th>\n<th>Required</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>name</code></td>\n<td>string</td>\n<td>Yes</td>\n<td>Zone name, max 100 characters.</td>\n</tr>\n<tr>\n<td><code>geometry</code></td>\n<td>string</td>\n<td>Yes</td>\n<td>The polygon as a GeoJSON geometry string.</td>\n</tr>\n<tr>\n<td><code>color</code></td>\n<td>string</td>\n<td>Yes</td>\n<td>Display color (hex).</td>\n</tr>\n<tr>\n<td><code>storeIds</code></td>\n<td>string[] (UUID)</td>\n<td>Yes</td>\n<td>Stores the zone applies to. At least one.</td>\n</tr>\n<tr>\n<td><code>restricted</code></td>\n<td>boolean</td>\n<td>No</td>\n<td>Restricted zones limit kiosk trip destinations. Default <code>false</code>.</td>\n</tr>\n</tbody>\n</table>\n</div><h4 id=\"response\">Response</h4>\n<p>Responds <code>201</code> with the created zone.</p>\n","auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{apiKey}}"}]},"isInherited":true,"source":{"_postman_id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","name":"ShuttleControl Open API","type":"collection"}},"urlObject":{"path":["v2","zones"],"host":["{{hostname}}"],"query":[],"variable":[]}},"response":[{"id":"d0d22e16-943a-4288-ba55-b1806f5bff43","name":"Create Zone response","originalRequest":{"method":"POST","header":[],"body":{"mode":"raw","raw":"{\n    \"geometry\": \"_fvtGdyh`MxrBq|Hm~C?cr@p|Hv}A?\",\n    \"name\": \"Alpha Zone\",\n    \"color\": \"blue\",\n    \"storeId\": \"\"\n}","options":{"raw":{"language":"json"}}},"url":"{{hostname}}/v2/zones"},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Access-Control-Allow-Origin","value":"*"},{"key":"Content-Security-Policy","value":"default-src 'self';base-uri 'self';font-src 'self' https: data:;form-action 'self';frame-ancestors 'self';img-src 'self' data:;object-src 'none';script-src 'self';script-src-attr 'none';style-src 'self' https: 'unsafe-inline';upgrade-insecure-requests"},{"key":"Cross-Origin-Embedder-Policy","value":"require-corp"},{"key":"Cross-Origin-Opener-Policy","value":"same-origin"},{"key":"X-DNS-Prefetch-Control","value":"off"},{"key":"X-Frame-Options","value":"SAMEORIGIN"},{"key":"Strict-Transport-Security","value":"max-age=15552000; includeSubDomains"},{"key":"X-Download-Options","value":"noopen"},{"key":"X-Content-Type-Options","value":"nosniff"},{"key":"Origin-Agent-Cluster","value":"?1"},{"key":"X-Permitted-Cross-Domain-Policies","value":"none"},{"key":"Referrer-Policy","value":"no-referrer"},{"key":"X-XSS-Protection","value":"0"},{"key":"Location","value":"https://api.shuttlecontrol.com/v2/zones/0be847c5-6936-427d-82fc-06bc59b10173"},{"key":"Content-Type","value":"application/json; charset=utf-8"},{"key":"Content-Length","value":"310"},{"key":"ETag","value":"W/\"136-Lj+/rPg6/DqCojEjIUGMpMfkN4w\""},{"key":"Vary","value":"Accept-Encoding"},{"key":"Date","value":"Mon, 26 Feb 2024 20:08:27 GMT"},{"key":"Connection","value":"keep-alive"},{"key":"Keep-Alive","value":"timeout=5"}],"cookie":[],"responseTime":null,"body":"{\n    \"id\": \"0be847c5-6936-427d-82fc-06bc59b10173\",\n    \"store\": \"63fab983-9250-4883-9214-b420099d855d\",\n    \"name\": \"Alpha Zone\",\n    \"geometry\": \"_fvtGdyh`MxrBq|Hm~C?cr@p|Hv}A?\",\n    \"color\": \"blue\",\n    \"createdBy\": \"f4bbf2aa-8af8-4c56-aeff-c9da3ded6cfb\",\n    \"enabled\": true,\n    \"createdAt\": \"2024-02-26T20:08:26.911Z\",\n    \"updatedAt\": null,\n    \"updatedBy\": null\n}"}],"_postman_id":"780153f5-f470-46ff-9dca-bdc7db6418d1"},{"name":"List Zones","id":"a83a16bb-490b-452b-b546-bc9b523cf440","request":{"method":"GET","header":[],"url":"{{hostname}}/v2/zones?page=0&size=10","description":"<p>Returns a paginated list of zones visible to the caller.</p>\n<h4 id=\"response\">Response</h4>\n<p>Returns <code>{ items, count }</code>.</p>\n","auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{apiKey}}"}]},"isInherited":true,"source":{"_postman_id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","name":"ShuttleControl Open API","type":"collection"}},"urlObject":{"path":["v2","zones"],"host":["{{hostname}}"],"query":[{"description":{"content":"<p>Required. Zero-based page index.</p>\n","type":"text/plain"},"key":"page","value":"0"},{"description":{"content":"<p>Page size, 1–100. Default <code>10</code>.</p>\n","type":"text/plain"},"key":"size","value":"10"},{"disabled":true,"description":{"content":"<p>Filter to one store.</p>\n","type":"text/plain"},"key":"storeId","value":""},{"disabled":true,"description":{"content":"<p><code>normal</code> (default — unrestricted zones), <code>restricted</code>, or <code>all</code>.</p>\n","type":"text/plain"},"key":"scope","value":"normal"}],"variable":[]}},"response":[{"id":"ce3a83fe-aa93-4675-8a37-6da8a35000b3","name":"List Zones response","originalRequest":{"method":"GET","header":[],"url":{"raw":"{{hostname}}/v2/zones?page=0&size=5&storeId=","host":["{{hostname}}"],"path":["v2","zones"],"query":[{"key":"page","value":"0"},{"key":"size","value":"5"},{"key":"storeId","value":""}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"content-type","value":"application/json; charset=utf-8"}],"cookie":[],"responseTime":null,"body":"{\n    \"items\": [\n        {\n            \"id\": \"68d451ee-99af-4b72-93d1-74cd5f891de5\",\n            \"name\": \"Alpha Zone\",\n            \"color\": \"blue\",\n            \"geometry\": \"_fvtGdyh`MxrBq|Hm~C?cr@p|Hv}A?\",\n            \"store\": {\n                \"id\": \"0b8a26d9-14f3-40ae-8d44-681e0b5c381a\",\n                \"name\": \"Alpha Store\",\n                \"color\": \"blue\"\n            },\n            \"createdAt\": \"2023-04-11T13:08:40.175Z\",\n            \"createdBy\": {\n                \"id\": \"b2eeb765-8c35-4ef1-b307-e0c47eda1e78\",\n                \"firstName\": \"Edward\",\n                \"lastName\": \"Maxedon\"\n            },\n            \"updatedAt\": null,\n            \"updatedBy\": null\n        },\n        {\n            \"id\": \"a6b45a7a-1402-42f5-a045-ca0a07ca5038\",\n            \"name\": \"Alpha Zone\",\n            \"color\": \"blue\",\n            \"geometry\": \"gfytGx`d`Mf_BjwCxrBq|H??\",\n            \"store\": {\n                \"id\": \"0b8a26d9-14f3-40ae-8d44-681e0b5c381a\",\n                \"name\": \"Alpha Store\",\n                \"color\": \"blue\"\n            },\n            \"createdAt\": \"2023-04-11T13:04:04.729Z\",\n            \"createdBy\": {\n                \"id\": \"b2eeb765-8c35-4ef1-b307-e0c47eda1e78\",\n                \"firstName\": \"Edward\",\n                \"lastName\": \"Maxedon\"\n            },\n            \"updatedAt\": null,\n            \"updatedBy\": null\n        },\n        {\n            \"id\": \"83f89048-1c83-470c-875d-4f8ea886682e\",\n            \"name\": \"Alpha Zone\",\n            \"color\": \"blue\",\n            \"geometry\": \"_~ntGvp_`Mtj@fCo@nr@_YlSmNqU\",\n            \"store\": {\n                \"id\": \"0b8a26d9-14f3-40ae-8d44-681e0b5c381a\",\n                \"name\": \"Alpha Store\",\n                \"color\": \"blue\"\n            },\n            \"createdAt\": \"2023-04-11T13:03:13.326Z\",\n            \"createdBy\": {\n                \"id\": \"b2eeb765-8c35-4ef1-b307-e0c47eda1e78\",\n                \"firstName\": \"Edward\",\n                \"lastName\": \"Maxedon\"\n            },\n            \"updatedAt\": null,\n            \"updatedBy\": null\n        }\n    ],\n    \"count\": 3\n}"}],"_postman_id":"a83a16bb-490b-452b-b546-bc9b523cf440"},{"name":"List All Zones","id":"0463aa41-b00a-4a38-913d-03ee971778ed","request":{"method":"GET","header":[],"url":"{{hostname}}/v2/zones/all","description":"<p>Returns all zones for the given stores (non-paginated).</p>\n<h4 id=\"response\">Response</h4>\n<p>Returns an array of zone objects, each with its <code>stores</code>.</p>\n","auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{apiKey}}"}]},"isInherited":true,"source":{"_postman_id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","name":"ShuttleControl Open API","type":"collection"}},"urlObject":{"path":["v2","zones","all"],"host":["{{hostname}}"],"query":[{"disabled":true,"description":{"content":"<p>Repeatable UUID filter. Default: all visible stores.</p>\n","type":"text/plain"},"key":"storeIds","value":""},{"disabled":true,"description":{"content":"<p><code>normal</code> (default), <code>restricted</code>, or <code>all</code>.</p>\n","type":"text/plain"},"key":"scope","value":"normal"}],"variable":[]}},"response":[{"id":"51ec6f39-3c8c-482c-b0d4-d07f3119acdb","name":"List All Zones response","originalRequest":{"method":"GET","header":[],"url":{"raw":"{{hostname}}/v2/zones/all?storeId=","host":["{{hostname}}"],"path":["v2","zones","all"],"query":[{"key":"storeId","value":""}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Access-Control-Allow-Origin","value":"*"},{"key":"Content-Security-Policy","value":"default-src 'self';base-uri 'self';font-src 'self' https: data:;form-action 'self';frame-ancestors 'self';img-src 'self' data:;object-src 'none';script-src 'self';script-src-attr 'none';style-src 'self' https: 'unsafe-inline';upgrade-insecure-requests"},{"key":"Cross-Origin-Embedder-Policy","value":"require-corp"},{"key":"Cross-Origin-Opener-Policy","value":"same-origin"},{"key":"X-DNS-Prefetch-Control","value":"off"},{"key":"X-Frame-Options","value":"SAMEORIGIN"},{"key":"Strict-Transport-Security","value":"max-age=15552000; includeSubDomains"},{"key":"X-Download-Options","value":"noopen"},{"key":"X-Content-Type-Options","value":"nosniff"},{"key":"Origin-Agent-Cluster","value":"?1"},{"key":"X-Permitted-Cross-Domain-Policies","value":"none"},{"key":"Referrer-Policy","value":"no-referrer"},{"key":"X-XSS-Protection","value":"0"},{"key":"Content-Type","value":"application/json; charset=utf-8"},{"key":"Content-Length","value":"393"},{"key":"ETag","value":"W/\"189-gmyArNU4qvhvteH6mxlIgiw4Lnw\""},{"key":"Vary","value":"Accept-Encoding"},{"key":"Date","value":"Wed, 06 Mar 2024 19:05:10 GMT"},{"key":"Connection","value":"keep-alive"},{"key":"Keep-Alive","value":"timeout=5"}],"cookie":[],"responseTime":null,"body":"[\n    {\n        \"id\": \"5c6ab53a-43e3-4818-b6b9-72f8b7d5b57a\",\n        \"name\": \"Alpha Zone\",\n        \"color\": \"springgreen\",\n        \"geometry\": \"tsj`MiqutGoiB`n@zsAll@rTo{A\",\n        \"store\": {\n            \"id\": \"d7a5f4f4-fbce-47a2-8256-b6338b15c5d8\",\n            \"name\": \"Alpha Store\",\n            \"color\": \"blue\"\n        },\n        \"createdAt\": \"2024-03-06T19:05:00.981Z\",\n        \"createdBy\": {\n            \"id\": \"67182782-f8a3-4723-98fc-8b443d5e4a71\",\n            \"firstName\": \"Edward\",\n            \"lastName\": \"Maxedon\"\n        },\n        \"updatedAt\": null,\n        \"updatedBy\": null\n    }\n]"}],"_postman_id":"0463aa41-b00a-4a38-913d-03ee971778ed"},{"name":"Grouped Zones","id":"37721b42-8425-45f0-8465-ef7bd0504e28","request":{"method":"GET","header":[],"url":"{{hostname}}/v2/zones/grouped","description":"<p>Returns stores with their zones nested — convenient for grouped drop-down filters.</p>\n<h4 id=\"response\">Response</h4>\n<p>Returns an array of stores, each with a <code>zones</code> array.</p>\n","auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{apiKey}}"}]},"isInherited":true,"source":{"_postman_id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","name":"ShuttleControl Open API","type":"collection"}},"urlObject":{"path":["v2","zones","grouped"],"host":["{{hostname}}"],"query":[{"disabled":true,"description":{"content":"<p>Repeatable UUID filter. Default: all visible stores.</p>\n","type":"text/plain"},"key":"storeIds","value":""},{"disabled":true,"description":{"content":"<p><code>normal</code> (default), <code>restricted</code>, or <code>all</code>.</p>\n","type":"text/plain"},"key":"scope","value":"normal"}],"variable":[]}},"response":[{"id":"8f394412-4db5-432a-b58e-806fcc07fc59","name":"Grouped Zones response","originalRequest":{"method":"GET","header":[],"url":{"raw":"{{hostname}}/v2/zones/grouped?storeId=","host":["{{hostname}}"],"path":["v2","zones","grouped"],"query":[{"key":"storeId","value":"","description":"Optional store Id. If not given, zones for all stores are returned"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Access-Control-Allow-Origin","value":"*"},{"key":"Content-Security-Policy","value":"default-src 'self';base-uri 'self';font-src 'self' https: data:;form-action 'self';frame-ancestors 'self';img-src 'self' data:;object-src 'none';script-src 'self';script-src-attr 'none';style-src 'self' https: 'unsafe-inline';upgrade-insecure-requests"},{"key":"Cross-Origin-Embedder-Policy","value":"require-corp"},{"key":"Cross-Origin-Opener-Policy","value":"same-origin"},{"key":"X-DNS-Prefetch-Control","value":"off"},{"key":"X-Frame-Options","value":"SAMEORIGIN"},{"key":"Strict-Transport-Security","value":"max-age=15552000; includeSubDomains"},{"key":"X-Download-Options","value":"noopen"},{"key":"X-Content-Type-Options","value":"nosniff"},{"key":"Origin-Agent-Cluster","value":"?1"},{"key":"X-Permitted-Cross-Domain-Policies","value":"none"},{"key":"Referrer-Policy","value":"no-referrer"},{"key":"X-XSS-Protection","value":"0"},{"key":"Content-Type","value":"application/json; charset=utf-8"},{"key":"Content-Length","value":"187"},{"key":"ETag","value":"W/\"bb-xbwstPEyY9T2M80W4dd+YtTK8wQ\""},{"key":"Vary","value":"Accept-Encoding"},{"key":"Date","value":"Wed, 28 Feb 2024 19:57:52 GMT"},{"key":"Connection","value":"keep-alive"},{"key":"Keep-Alive","value":"timeout=5"}],"cookie":[],"responseTime":null,"body":"[\n    {\n        \"id\": \"63fab983-9250-4883-9214-b420099d855d\",\n        \"name\": \"Alpha Store\",\n        \"zones\": [\n            {\n                \"id\": \"21ee2943-466f-41db-88d7-7ca9400c9cc4\",\n                \"name\": \"Alpha Store Zone\",\n                \"color\": \"springgreen\",\n                \"enabled\": true\n            }\n        ]\n    }\n]"}],"_postman_id":"37721b42-8425-45f0-8465-ef7bd0504e28"},{"name":"Get Zone","id":"f61a9f61-dc47-4cd2-88a5-b6ae707abda4","request":{"method":"GET","header":[],"url":"{{hostname}}/v2/zones/:id","description":"<p>Returns a single zone.</p>\n<h4 id=\"response\">Response</h4>\n<p>Returns <code>{ id, name, color, geometry, restricted, stores, createdAt, createdBy, updatedAt, updatedBy }</code>.</p>\n","auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{apiKey}}"}]},"isInherited":true,"source":{"_postman_id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","name":"ShuttleControl Open API","type":"collection"}},"urlObject":{"path":["v2","zones",":id"],"host":["{{hostname}}"],"query":[],"variable":[{"id":"71bc61ef-6071-46ab-9b93-1771cda41f6d","description":{"content":"<p>UUID of the zone.</p>\n","type":"text/plain"},"type":"any","value":"","key":"id"}]}},"response":[{"id":"bb70f428-9395-4370-9212-344797c4a774","name":"Get Zone response","originalRequest":{"method":"GET","header":[],"url":"{{hostname}}/v2/zones/"},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"content-length","value":"387"},{"key":"content-type","value":"application/json; charset=utf-8"}],"cookie":[],"responseTime":null,"body":"{\n    \"id\": \"68d451ee-99af-4b72-93d1-74cd5f891de5\",\n    \"name\": \"Alpha Zone\",\n    \"color\": \"blue\",\n    \"geometry\": \"_fvtGdyh`MxrBq|Hm~C?cr@p|Hv}A?\",\n    \"store\": {\n        \"id\": \"0b8a26d9-14f3-40ae-8d44-681e0b5c381a\",\n        \"name\": \"Alpha Store\",\n        \"color\": \"blue\"\n    },\n    \"createdAt\": \"2023-04-11T13:08:40.175Z\",\n    \"createdBy\": {\n        \"id\": \"b2eeb765-8c35-4ef1-b307-e0c47eda1e78\",\n        \"firstName\": \"Edward\",\n        \"lastName\": \"Maxedon\"\n    },\n    \"updatedAt\": null,\n    \"updatedBy\": null\n}"}],"_postman_id":"f61a9f61-dc47-4cd2-88a5-b6ae707abda4"},{"name":"Update Zone","id":"b68ccf03-ce78-44ed-9646-d32ebf5f7741","request":{"method":"PUT","header":[],"body":{"mode":"raw","raw":"{\n  \"name\": \"Downtown\",\n  \"geometry\": \"{\\\"type\\\":\\\"Polygon\\\",\\\"coordinates\\\":[[[-73.58,45.49],[-73.55,45.49],[-73.55,45.51],[-73.58,45.51],[-73.58,45.49]]]}\",\n  \"color\": \"#1677ff\",\n  \"storeIds\": [\n    \"9f2d1c34-0000-0000-0000-000000000000\"\n  ]\n}","options":{"raw":{"language":"json"}}},"url":"{{hostname}}/v2/zones/:id","description":"<p>Replaces a zone’s definition and store assignments.</p>\n<h4 id=\"body-fields\">Body fields</h4>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Field</th>\n<th>Type</th>\n<th>Required</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>name</code></td>\n<td>string</td>\n<td>Yes</td>\n<td>Max 100 characters.</td>\n</tr>\n<tr>\n<td><code>geometry</code></td>\n<td>string</td>\n<td>Yes</td>\n<td>GeoJSON geometry string.</td>\n</tr>\n<tr>\n<td><code>color</code></td>\n<td>string</td>\n<td>Yes</td>\n<td>Display color (hex).</td>\n</tr>\n<tr>\n<td><code>storeIds</code></td>\n<td>string[] (UUID)</td>\n<td>Yes</td>\n<td>Full replacement set of store assignments. At least one.</td>\n</tr>\n<tr>\n<td><code>restricted</code></td>\n<td>boolean</td>\n<td>No</td>\n<td>Whether the zone is restricted.</td>\n</tr>\n</tbody>\n</table>\n</div><h4 id=\"response\">Response</h4>\n<p>Responds <code>204 No Content</code>.</p>\n","auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{apiKey}}"}]},"isInherited":true,"source":{"_postman_id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","name":"ShuttleControl Open API","type":"collection"}},"urlObject":{"path":["v2","zones",":id"],"host":["{{hostname}}"],"query":[],"variable":[{"id":"cdd9b81b-a932-49be-ac4c-af08b2d68364","description":{"content":"<p>UUID of the zone.</p>\n","type":"text/plain"},"type":"any","value":"","key":"id"}]}},"response":[{"id":"6c14a136-e5cc-46a7-b693-4a4d83cb1694","name":"Update Zone response","originalRequest":{"method":"PUT","header":[],"body":{"mode":"raw","raw":"{\n    \"geometry\": \"pmk`M{eytGguCdmArlChqB|pCg|AihCgbB\",\n    \"name\": \"Alpha Store Zone\",\n    \"color\": \"blue\",\n    \"storeId\": \"\"\n}","options":{"raw":{"language":"json"}}},"url":"{{hostname}}/v2/zones/"},"status":"No Content","code":204,"_postman_previewlanguage":"plain","header":[{"key":"Access-Control-Allow-Origin","value":"*"},{"key":"Content-Security-Policy","value":"default-src 'self';base-uri 'self';font-src 'self' https: data:;form-action 'self';frame-ancestors 'self';img-src 'self' data:;object-src 'none';script-src 'self';script-src-attr 'none';style-src 'self' https: 'unsafe-inline';upgrade-insecure-requests"},{"key":"Cross-Origin-Embedder-Policy","value":"require-corp"},{"key":"Cross-Origin-Opener-Policy","value":"same-origin"},{"key":"X-DNS-Prefetch-Control","value":"off"},{"key":"X-Frame-Options","value":"SAMEORIGIN"},{"key":"Strict-Transport-Security","value":"max-age=15552000; includeSubDomains"},{"key":"X-Download-Options","value":"noopen"},{"key":"X-Content-Type-Options","value":"nosniff"},{"key":"Origin-Agent-Cluster","value":"?1"},{"key":"X-Permitted-Cross-Domain-Policies","value":"none"},{"key":"Referrer-Policy","value":"no-referrer"},{"key":"X-XSS-Protection","value":"0"},{"key":"ETag","value":"W/\"a-bAsFyilMr4Ra1hIU5PyoyFRunpI\""},{"key":"Date","value":"Wed, 28 Feb 2024 16:45:13 GMT"},{"key":"Connection","value":"keep-alive"},{"key":"Keep-Alive","value":"timeout=5"}],"cookie":[],"responseTime":null,"body":null}],"_postman_id":"b68ccf03-ce78-44ed-9646-d32ebf5f7741"},{"name":"Delete Zone","id":"6a2f7c98-b1f8-4160-a37b-289c74a867ce","request":{"method":"DELETE","header":[],"url":"{{hostname}}/v2/zones/:id","description":"<p>Soft-deletes a zone and detaches it from active trips. Rejected while a confirmed trip is using the zone (<code>400 ZONE_IS_IN_USE</code>).</p>\n<p><strong>Required role:</strong> <code>ADMIN</code> or higher. An account API key always satisfies this (it authenticates as the account owner).</p>\n<h4 id=\"response\">Response</h4>\n<p>Responds <code>204 No Content</code>.</p>\n","auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{apiKey}}"}]},"isInherited":true,"source":{"_postman_id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","name":"ShuttleControl Open API","type":"collection"}},"urlObject":{"path":["v2","zones",":id"],"host":["{{hostname}}"],"query":[],"variable":[{"id":"51f9089f-98f2-472d-b82d-1bcfa61a9236","description":{"content":"<p>UUID of the zone.</p>\n","type":"text/plain"},"type":"any","value":"","key":"id"}]}},"response":[{"id":"33990cb0-8523-4941-bd64-bccb59176456","name":"Delete Zone response","originalRequest":{"method":"DELETE","header":[],"url":"{{hostname}}/v2/zones/"},"status":"No Content","code":204,"_postman_previewlanguage":"plain","header":[],"cookie":[],"responseTime":null,"body":null}],"_postman_id":"6a2f7c98-b1f8-4160-a37b-289c74a867ce"}],"id":"7da72371-3896-4bd3-a031-3d52d8138b5d","description":"<p>Geographic polygons attached to one or more stores. Zones tag trips for filtering/analytics; <code>restricted</code> zones limit where kiosk trips may go.</p>\n","_postman_id":"7da72371-3896-4bd3-a031-3d52d8138b5d","auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{apiKey}}"}]},"isInherited":true,"source":{"_postman_id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","name":"ShuttleControl Open API","type":"collection"}}},{"name":"Kiosks","item":[{"name":"Create Kiosk","id":"587277d3-d7e1-4aa7-96a0-2736c9e1baf1","request":{"method":"POST","header":[],"body":{"mode":"raw","raw":"{\n  \"name\": \"Lobby kiosk\",\n  \"description\": \"Book your shuttle to the airport.\",\n  \"storeId\": \"9f2d1c34-0000-0000-0000-000000000000\",\n  \"enabledWorkflowIds\": [\n    \"7ab30e12-0000-0000-0000-000000000000\"\n  ],\n  \"tripStates\": [\n    \"SCHEDULED\"\n  ],\n  \"minimumNotice\": 1,\n  \"maximumNotice\": 336,\n  \"returnTripEnabled\": true,\n  \"maximumSeats\": 4,\n  \"tripRestrictionZoneId\": null\n}","options":{"raw":{"language":"json"}}},"url":"{{hostname}}/v2/kiosks","description":"<p>Creates a kiosk for a store. A unique short URL is generated automatically.</p>\n<p><strong>Required role:</strong> <code>ADMIN</code> or higher. An account API key always satisfies this (it authenticates as the account owner).</p>\n<h4 id=\"body-fields\">Body fields</h4>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Field</th>\n<th>Type</th>\n<th>Required</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>name</code></td>\n<td>string</td>\n<td>Yes</td>\n<td>Kiosk name, max 100 characters.</td>\n</tr>\n<tr>\n<td><code>description</code></td>\n<td>string</td>\n<td>Yes</td>\n<td>Shown on the kiosk landing page, max 1000 characters. May be empty.</td>\n</tr>\n<tr>\n<td><code>storeId</code></td>\n<td>string (UUID)</td>\n<td>Yes</td>\n<td>The store the kiosk belongs to.</td>\n</tr>\n<tr>\n<td><code>enabledWorkflowIds</code></td>\n<td>string[] (UUID)</td>\n<td>Yes</td>\n<td>Workflows bookable from this kiosk.</td>\n</tr>\n<tr>\n<td><code>tripStates</code></td>\n<td>string[]</td>\n<td>Yes</td>\n<td>Which trip states the kiosk may create: any of <code>REQUESTED</code>, <code>SCHEDULED</code>, <code>PENDING</code>. At least one.</td>\n</tr>\n<tr>\n<td><code>minimumNotice</code></td>\n<td>number</td>\n<td>Yes</td>\n<td>Minimum booking notice in hours, 0–48.</td>\n</tr>\n<tr>\n<td><code>maximumNotice</code></td>\n<td>number</td>\n<td>Yes</td>\n<td>Maximum booking horizon in hours, 0–8760 (1 year).</td>\n</tr>\n<tr>\n<td><code>returnTripEnabled</code></td>\n<td>boolean</td>\n<td>Yes</td>\n<td>Whether customers can book a return trip.</td>\n</tr>\n<tr>\n<td><code>maximumSeats</code></td>\n<td>integer</td>\n<td>null</td>\n<td>No</td>\n</tr>\n<tr>\n<td><code>tripRestrictionZoneId</code></td>\n<td>string (UUID)</td>\n<td>null</td>\n<td>No</td>\n</tr>\n<tr>\n<td><code>lightHeadingFontColor</code></td>\n<td>string</td>\n<td>No</td>\n<td>Light-theme heading color (hex, max 50). Default <code>\"\"</code>.</td>\n</tr>\n<tr>\n<td><code>lightTextFontColor</code></td>\n<td>string</td>\n<td>No</td>\n<td>Light-theme text color. Default <code>\"\"</code>.</td>\n</tr>\n<tr>\n<td><code>lightBackgroundColor</code></td>\n<td>string</td>\n<td>No</td>\n<td>Light-theme background color. Default <code>\"\"</code>.</td>\n</tr>\n<tr>\n<td><code>darkHeadingFontColor</code></td>\n<td>string</td>\n<td>No</td>\n<td>Dark-theme heading color. Default <code>\"\"</code>.</td>\n</tr>\n<tr>\n<td><code>darkTextFontColor</code></td>\n<td>string</td>\n<td>No</td>\n<td>Dark-theme text color. Default <code>\"\"</code>.</td>\n</tr>\n<tr>\n<td><code>darkBackgroundColor</code></td>\n<td>string</td>\n<td>No</td>\n<td>Dark-theme background color. Default <code>\"\"</code>.</td>\n</tr>\n</tbody>\n</table>\n</div><h4 id=\"response\">Response</h4>\n<p>Responds <code>201</code> with the created kiosk (including its generated <code>shortUrl</code>).</p>\n","auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{apiKey}}"}]},"isInherited":true,"source":{"_postman_id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","name":"ShuttleControl Open API","type":"collection"}},"urlObject":{"path":["v2","kiosks"],"host":["{{hostname}}"],"query":[],"variable":[]}},"response":[],"_postman_id":"587277d3-d7e1-4aa7-96a0-2736c9e1baf1"},{"name":"List Kiosks","id":"bf509b91-eb11-454f-ac61-e954f44e0e2f","request":{"method":"GET","header":[],"url":"{{hostname}}/v2/kiosks?page=0&size=10","description":"<p>Returns a paginated list of active kiosks for the caller’s stores.</p>\n<p><strong>Required role:</strong> <code>ADMIN</code> or higher. An account API key always satisfies this (it authenticates as the account owner).</p>\n<h4 id=\"response\">Response</h4>\n<p>Returns <code>{ items, count }</code> — each item includes <code>shortUrl</code>, notice settings, <code>tripStates</code>, <code>store</code>, and <code>workflows</code>.</p>\n","auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{apiKey}}"}]},"isInherited":true,"source":{"_postman_id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","name":"ShuttleControl Open API","type":"collection"}},"urlObject":{"path":["v2","kiosks"],"host":["{{hostname}}"],"query":[{"description":{"content":"<p>Zero-based page index. Default <code>0</code>.</p>\n","type":"text/plain"},"key":"page","value":"0"},{"description":{"content":"<p>Page size, 1–100. Default <code>10</code>.</p>\n","type":"text/plain"},"key":"size","value":"10"},{"disabled":true,"description":{"content":"<p>Repeatable UUID filter.</p>\n","type":"text/plain"},"key":"storeIds","value":""},{"disabled":true,"description":{"content":"<p>Case-insensitive substring match on the kiosk name (max 100).</p>\n","type":"text/plain"},"key":"search","value":""}],"variable":[]}},"response":[],"_postman_id":"bf509b91-eb11-454f-ac61-e954f44e0e2f"},{"name":"Grouped Kiosks","id":"36a73e19-2d76-4f5b-a0cf-53ce27b8da40","request":{"method":"GET","header":[],"url":"{{hostname}}/v2/kiosks/grouped","description":"<p>Returns stores with their kiosks nested — convenient for grouped drop-downs.</p>\n<p><strong>Required role:</strong> <code>ADMIN</code> or higher. An account API key always satisfies this (it authenticates as the account owner).</p>\n<h4 id=\"response\">Response</h4>\n<p>Returns an array of stores, each with a <code>kiosks</code> array of <code>{ id, name }</code>.</p>\n","auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{apiKey}}"}]},"isInherited":true,"source":{"_postman_id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","name":"ShuttleControl Open API","type":"collection"}},"urlObject":{"path":["v2","kiosks","grouped"],"host":["{{hostname}}"],"query":[{"disabled":true,"description":{"content":"<p>Filter to one store. Default: all visible stores.</p>\n","type":"text/plain"},"key":"storeId","value":""}],"variable":[]}},"response":[],"_postman_id":"36a73e19-2d76-4f5b-a0cf-53ce27b8da40"},{"name":"Get Kiosk","id":"7870ed72-538b-4800-b42b-5c33c9eacd8c","request":{"method":"GET","header":[],"url":"{{hostname}}/v2/kiosks/:id","description":"<p>Returns a single kiosk with its workflows, availability windows, and theming. When the kiosk is connected to a point of sale, the response also includes the POS’s Stripe products.</p>\n<p><strong>Required role:</strong> <code>ADMIN</code> or higher. An account API key always satisfies this (it authenticates as the account owner).</p>\n<h4 id=\"response\">Response</h4>\n<p>Returns the kiosk object.</p>\n","auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{apiKey}}"}]},"isInherited":true,"source":{"_postman_id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","name":"ShuttleControl Open API","type":"collection"}},"urlObject":{"path":["v2","kiosks",":id"],"host":["{{hostname}}"],"query":[],"variable":[{"id":"134230ca-f1a3-47c2-9eb4-a58d6c89dd9f","description":{"content":"<p>UUID of the kiosk.</p>\n","type":"text/plain"},"type":"any","value":"","key":"id"}]}},"response":[],"_postman_id":"7870ed72-538b-4800-b42b-5c33c9eacd8c"},{"name":"Update Kiosk","id":"5c544a15-2099-43b4-8a11-795da0355262","request":{"method":"PUT","header":[],"body":{"mode":"raw","raw":"{\n  \"shortUrl\": \"a1B2c3\",\n  \"name\": \"Lobby kiosk\",\n  \"description\": \"Book your shuttle to the airport.\",\n  \"enabledWorkflowIds\": [\n    \"7ab30e12-0000-0000-0000-000000000000\"\n  ],\n  \"tripStates\": [\n    \"SCHEDULED\"\n  ],\n  \"minimumNotice\": 1,\n  \"maximumNotice\": 336,\n  \"returnTripEnabled\": true,\n  \"maximumSeats\": 4,\n  \"tripRestrictionZoneId\": null,\n  \"lightHeadingFontColor\": \"\",\n  \"lightTextFontColor\": \"\",\n  \"lightBackgroundColor\": \"\",\n  \"darkHeadingFontColor\": \"\",\n  \"darkTextFontColor\": \"\",\n  \"darkBackgroundColor\": \"\"\n}","options":{"raw":{"language":"json"}}},"url":"{{hostname}}/v2/kiosks/:id","description":"<p>Replaces a kiosk’s settings. All fields are required (send current values for anything you don’t want to change); the workflow assignment is replaced by <code>enabledWorkflowIds</code>.</p>\n<p><strong>Required role:</strong> <code>ADMIN</code> or higher. An account API key always satisfies this (it authenticates as the account owner).</p>\n<h4 id=\"body-fields\">Body fields</h4>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Field</th>\n<th>Type</th>\n<th>Required</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>shortUrl</code></td>\n<td>string</td>\n<td>Yes</td>\n<td>The kiosk’s short URL code, max 100 characters.</td>\n</tr>\n<tr>\n<td><code>name</code></td>\n<td>string</td>\n<td>Yes</td>\n<td>Max 100 characters.</td>\n</tr>\n<tr>\n<td><code>description</code></td>\n<td>string</td>\n<td>Yes</td>\n<td>Max 1000 characters.</td>\n</tr>\n<tr>\n<td><code>enabledWorkflowIds</code></td>\n<td>string[] (UUID)</td>\n<td>Yes</td>\n<td>Full replacement set of bookable workflows.</td>\n</tr>\n<tr>\n<td><code>tripStates</code></td>\n<td>string[]</td>\n<td>Yes</td>\n<td>Any of <code>REQUESTED</code>, <code>SCHEDULED</code>, <code>PENDING</code>. At least one.</td>\n</tr>\n<tr>\n<td><code>minimumNotice</code></td>\n<td>number</td>\n<td>Yes</td>\n<td>Hours, 0–48.</td>\n</tr>\n<tr>\n<td><code>maximumNotice</code></td>\n<td>number</td>\n<td>Yes</td>\n<td>Hours, 0–8760.</td>\n</tr>\n<tr>\n<td><code>returnTripEnabled</code></td>\n<td>boolean</td>\n<td>Yes</td>\n<td>Whether return trips can be booked.</td>\n</tr>\n<tr>\n<td><code>maximumSeats</code></td>\n<td>integer</td>\n<td>null</td>\n<td>Yes</td>\n</tr>\n<tr>\n<td><code>tripRestrictionZoneId</code></td>\n<td>string (UUID)</td>\n<td>null</td>\n<td>No</td>\n</tr>\n<tr>\n<td><code>lightHeadingFontColor</code></td>\n<td>string</td>\n<td>Yes</td>\n<td>Hex color, max 50. May be empty.</td>\n</tr>\n<tr>\n<td><code>lightTextFontColor</code></td>\n<td>string</td>\n<td>Yes</td>\n<td>Hex color. May be empty.</td>\n</tr>\n<tr>\n<td><code>lightBackgroundColor</code></td>\n<td>string</td>\n<td>Yes</td>\n<td>Hex color. May be empty.</td>\n</tr>\n<tr>\n<td><code>darkHeadingFontColor</code></td>\n<td>string</td>\n<td>Yes</td>\n<td>Hex color. May be empty.</td>\n</tr>\n<tr>\n<td><code>darkTextFontColor</code></td>\n<td>string</td>\n<td>Yes</td>\n<td>Hex color. May be empty.</td>\n</tr>\n<tr>\n<td><code>darkBackgroundColor</code></td>\n<td>string</td>\n<td>Yes</td>\n<td>Hex color. May be empty.</td>\n</tr>\n</tbody>\n</table>\n</div><h4 id=\"response\">Response</h4>\n<p>Responds <code>204 No Content</code>.</p>\n","auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{apiKey}}"}]},"isInherited":true,"source":{"_postman_id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","name":"ShuttleControl Open API","type":"collection"}},"urlObject":{"path":["v2","kiosks",":id"],"host":["{{hostname}}"],"query":[],"variable":[{"id":"b42900f3-81f4-4fc5-a802-58b95ed81aa9","description":{"content":"<p>UUID of the kiosk.</p>\n","type":"text/plain"},"type":"any","value":"","key":"id"}]}},"response":[],"_postman_id":"5c544a15-2099-43b4-8a11-795da0355262"},{"name":"Delete Kiosk","id":"e63051a1-12e3-46bd-a2a9-dc8b804f3abc","request":{"method":"DELETE","header":[],"url":"{{hostname}}/v2/kiosks/:id","description":"<p>Permanently deletes a kiosk. Rejected while the kiosk is connected to an active point of sale (<code>400 KIOSK_CONNECTED_TO_POS</code>).</p>\n<p><strong>Required role:</strong> <code>ADMIN</code> or higher. An account API key always satisfies this (it authenticates as the account owner).</p>\n<h4 id=\"response\">Response</h4>\n<p>Responds <code>204 No Content</code>.</p>\n","auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{apiKey}}"}]},"isInherited":true,"source":{"_postman_id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","name":"ShuttleControl Open API","type":"collection"}},"urlObject":{"path":["v2","kiosks",":id"],"host":["{{hostname}}"],"query":[],"variable":[{"id":"64e19b17-9c64-4345-b615-55d10c51a01f","description":{"content":"<p>UUID of the kiosk.</p>\n","type":"text/plain"},"type":"any","value":"","key":"id"}]}},"response":[],"_postman_id":"e63051a1-12e3-46bd-a2a9-dc8b804f3abc"},{"name":"Regenerate Kiosk Short URL","id":"4c52d14f-ab6d-46fa-949a-2e3fb751f6d9","request":{"method":"POST","header":[],"url":"{{hostname}}/v2/kiosks/:id/generateShortUrl","description":"<p>Replaces the kiosk’s short URL with a newly generated one, invalidating the old link.</p>\n<p><strong>Required role:</strong> <code>ADMIN</code> or higher. An account API key always satisfies this (it authenticates as the account owner).</p>\n<h4 id=\"response\">Response</h4>\n<p>Responds <code>204 No Content</code>. Fetch the kiosk to read the new <code>shortUrl</code>.</p>\n","auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{apiKey}}"}]},"isInherited":true,"source":{"_postman_id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","name":"ShuttleControl Open API","type":"collection"}},"urlObject":{"path":["v2","kiosks",":id","generateShortUrl"],"host":["{{hostname}}"],"query":[],"variable":[{"id":"0ee992ab-a69a-4852-973a-55fb00fc7f65","description":{"content":"<p>UUID of the kiosk.</p>\n","type":"text/plain"},"type":"any","value":"","key":"id"}]}},"response":[],"_postman_id":"4c52d14f-ab6d-46fa-949a-2e3fb751f6d9"},{"name":"Create Kiosk Availability","id":"d31bab3b-9b0c-423d-9e78-bda28a1d253d","request":{"method":"POST","header":[],"body":{"mode":"raw","raw":"{\n  \"dayOfWeek\": 1,\n  \"startTime\": \"08:00\",\n  \"endTime\": \"18:00\",\n  \"availableSeats\": 40,\n  \"availableTrips\": 10\n}","options":{"raw":{"language":"json"}}},"url":"{{hostname}}/v2/kiosks/:id/availabilities","description":"<p>Adds a weekly availability window to a kiosk. When a kiosk has any windows, scheduled bookings are only accepted inside them (and per-window seat/trip caps are enforced).</p>\n<p><strong>Required role:</strong> <code>ADMIN</code> or higher. An account API key always satisfies this (it authenticates as the account owner).</p>\n<h4 id=\"body-fields\">Body fields</h4>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Field</th>\n<th>Type</th>\n<th>Required</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>dayOfWeek</code></td>\n<td>integer</td>\n<td>Yes</td>\n<td>0 (Sunday) – 6 (Saturday).</td>\n</tr>\n<tr>\n<td><code>startTime</code></td>\n<td>string</td>\n<td>Yes</td>\n<td>Window start, 24-hour <code>HH:mm</code> (store-local time).</td>\n</tr>\n<tr>\n<td><code>endTime</code></td>\n<td>string</td>\n<td>Yes</td>\n<td>Window end, 24-hour <code>HH:mm</code>.</td>\n</tr>\n<tr>\n<td><code>availableSeats</code></td>\n<td>integer</td>\n<td>null</td>\n<td>No</td>\n</tr>\n<tr>\n<td><code>availableTrips</code></td>\n<td>integer</td>\n<td>null</td>\n<td>No</td>\n</tr>\n</tbody>\n</table>\n</div><h4 id=\"response\">Response</h4>\n<p>Responds <code>201</code> with the created availability window.</p>\n","auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{apiKey}}"}]},"isInherited":true,"source":{"_postman_id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","name":"ShuttleControl Open API","type":"collection"}},"urlObject":{"path":["v2","kiosks",":id","availabilities"],"host":["{{hostname}}"],"query":[],"variable":[{"id":"c606bf5c-6599-4e31-961d-97bc12fd3ec1","description":{"content":"<p>UUID of the kiosk.</p>\n","type":"text/plain"},"type":"any","value":"","key":"id"}]}},"response":[],"_postman_id":"d31bab3b-9b0c-423d-9e78-bda28a1d253d"},{"name":"Update Kiosk Availability","id":"a376623f-e7bd-4f7a-a295-2d3bcb36e71f","request":{"method":"PUT","header":[],"body":{"mode":"raw","raw":"{\n  \"dayOfWeek\": 1,\n  \"startTime\": \"09:00\",\n  \"endTime\": \"17:00\",\n  \"availableSeats\": null,\n  \"availableTrips\": 8\n}","options":{"raw":{"language":"json"}}},"url":"{{hostname}}/v2/kiosks/:id/availabilities/:availabilityId","description":"<p>Replaces an availability window’s definition.</p>\n<p><strong>Required role:</strong> <code>ADMIN</code> or higher. An account API key always satisfies this (it authenticates as the account owner).</p>\n<h4 id=\"body-fields\">Body fields</h4>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Field</th>\n<th>Type</th>\n<th>Required</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>dayOfWeek</code></td>\n<td>integer</td>\n<td>Yes</td>\n<td>0 (Sunday) – 6 (Saturday).</td>\n</tr>\n<tr>\n<td><code>startTime</code></td>\n<td>string</td>\n<td>Yes</td>\n<td>24-hour <code>HH:mm</code>.</td>\n</tr>\n<tr>\n<td><code>endTime</code></td>\n<td>string</td>\n<td>Yes</td>\n<td>24-hour <code>HH:mm</code>.</td>\n</tr>\n<tr>\n<td><code>availableSeats</code></td>\n<td>integer</td>\n<td>null</td>\n<td>No</td>\n</tr>\n<tr>\n<td><code>availableTrips</code></td>\n<td>integer</td>\n<td>null</td>\n<td>No</td>\n</tr>\n</tbody>\n</table>\n</div><h4 id=\"response\">Response</h4>\n<p>Returns the updated availability window.</p>\n","auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{apiKey}}"}]},"isInherited":true,"source":{"_postman_id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","name":"ShuttleControl Open API","type":"collection"}},"urlObject":{"path":["v2","kiosks",":id","availabilities",":availabilityId"],"host":["{{hostname}}"],"query":[],"variable":[{"id":"acd7739b-7efc-4c75-bf68-65a210697d5c","description":{"content":"<p>UUID of the kiosk.</p>\n","type":"text/plain"},"type":"any","value":"","key":"id"},{"id":"9a403b16-b17d-4227-b998-8fb9596bf0f9","description":{"content":"<p>UUID of the availability window.</p>\n","type":"text/plain"},"type":"any","value":"","key":"availabilityId"}]}},"response":[],"_postman_id":"a376623f-e7bd-4f7a-a295-2d3bcb36e71f"},{"name":"Delete Kiosk Availability","id":"62292289-e620-469e-9223-8d8e6fcd7609","request":{"method":"DELETE","header":[],"url":"{{hostname}}/v2/kiosks/:id/availabilities/:availabilityId","description":"<p>Removes an availability window from a kiosk.</p>\n<p><strong>Required role:</strong> <code>ADMIN</code> or higher. An account API key always satisfies this (it authenticates as the account owner).</p>\n<h4 id=\"response\">Response</h4>\n<p>Responds <code>204 No Content</code>.</p>\n","auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{apiKey}}"}]},"isInherited":true,"source":{"_postman_id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","name":"ShuttleControl Open API","type":"collection"}},"urlObject":{"path":["v2","kiosks",":id","availabilities",":availabilityId"],"host":["{{hostname}}"],"query":[],"variable":[{"id":"c7175604-9eaa-4474-a774-26ee702c6069","description":{"content":"<p>UUID of the kiosk.</p>\n","type":"text/plain"},"type":"any","value":"","key":"id"},{"id":"863f4834-2f41-4e8f-a4ac-4698a013c74c","description":{"content":"<p>UUID of the availability window.</p>\n","type":"text/plain"},"type":"any","value":"","key":"availabilityId"}]}},"response":[],"_postman_id":"62292289-e620-469e-9223-8d8e6fcd7609"}],"id":"37e3298b-1e09-43b7-90c2-c681064f808a","description":"<p>Self-serve booking kiosks. Each kiosk belongs to a store, exposes a subset of the store’s workflows, and is reached by customers through its short URL. Optional weekly availability windows cap when (and how many) trips can be booked.</p>\n","_postman_id":"37e3298b-1e09-43b7-90c2-c681064f808a","auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{apiKey}}"}]},"isInherited":true,"source":{"_postman_id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","name":"ShuttleControl Open API","type":"collection"}}},{"name":"UserSchedules","item":[{"name":"Create UserSchedule","id":"a2bc6ea7-95e7-49fd-9b71-2c45a461e6d7","request":{"method":"POST","header":[],"body":{"mode":"raw","raw":"{\n  \"userId\": \"4be9f1e0-0000-0000-0000-000000000000\",\n  \"startAt\": \"2026-08-03T12:00:00.000Z\",\n  \"endAt\": \"2026-08-03T20:00:00.000Z\"\n}","options":{"raw":{"language":"json"}}},"url":"{{hostname}}/v2/userSchedules","description":"<p>Creates a shift for a user.</p>\n<p><strong>Required role:</strong> <code>ADMIN</code> or higher. An account API key always satisfies this (it authenticates as the account owner).</p>\n<h4 id=\"body-fields\">Body fields</h4>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Field</th>\n<th>Type</th>\n<th>Required</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>userId</code></td>\n<td>string (UUID)</td>\n<td>Yes</td>\n<td>The user the shift belongs to.</td>\n</tr>\n<tr>\n<td><code>startAt</code></td>\n<td>string (ISO 8601)</td>\n<td>Yes</td>\n<td>Shift start.</td>\n</tr>\n<tr>\n<td><code>endAt</code></td>\n<td>string (ISO 8601)</td>\n<td>Yes</td>\n<td>Shift end.</td>\n</tr>\n</tbody>\n</table>\n</div><h4 id=\"response\">Response</h4>\n<p>Responds <code>201</code> with the created schedule.</p>\n","auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{apiKey}}"}]},"isInherited":true,"source":{"_postman_id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","name":"ShuttleControl Open API","type":"collection"}},"urlObject":{"path":["v2","userSchedules"],"host":["{{hostname}}"],"query":[],"variable":[]}},"response":[],"_postman_id":"a2bc6ea7-95e7-49fd-9b71-2c45a461e6d7"},{"name":"List UserSchedules","id":"2c0c4b6c-5e3e-4440-a2b2-c02d50a0bc67","request":{"method":"GET","header":[],"url":"{{hostname}}/v2/userSchedules","description":"<p>Returns schedules for the caller’s stores (non-paginated), optionally narrowed to one user or one day.</p>\n<h4 id=\"response\">Response</h4>\n<p>Returns an array of schedule objects (<code>id</code>, <code>user</code>, <code>startAt</code>, <code>endAt</code>).</p>\n","auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{apiKey}}"}]},"isInherited":true,"source":{"_postman_id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","name":"ShuttleControl Open API","type":"collection"}},"urlObject":{"path":["v2","userSchedules"],"host":["{{hostname}}"],"query":[{"disabled":true,"description":{"content":"<p>ISO 8601 date — return only shifts overlapping that day.</p>\n","type":"text/plain"},"key":"search","value":""},{"disabled":true,"description":{"content":"<p>Filter to one user.</p>\n","type":"text/plain"},"key":"userId","value":""},{"disabled":true,"description":{"content":"<p>Repeatable UUID store filter.</p>\n","type":"text/plain"},"key":"storeIds","value":""}],"variable":[]}},"response":[],"_postman_id":"2c0c4b6c-5e3e-4440-a2b2-c02d50a0bc67"},{"name":"Get UserSchedule","id":"4e75df7c-b1c1-4fea-b3a2-93716485f7b1","request":{"method":"GET","header":[],"url":"{{hostname}}/v2/userSchedules/:id","description":"<p>Returns a single schedule.</p>\n<h4 id=\"response\">Response</h4>\n<p>Returns the schedule object.</p>\n","auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{apiKey}}"}]},"isInherited":true,"source":{"_postman_id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","name":"ShuttleControl Open API","type":"collection"}},"urlObject":{"path":["v2","userSchedules",":id"],"host":["{{hostname}}"],"query":[],"variable":[{"id":"2b3d3e9c-6400-442c-a1e6-50dbb293594d","description":{"content":"<p>UUID of the schedule.</p>\n","type":"text/plain"},"type":"any","value":"","key":"id"}]}},"response":[],"_postman_id":"4e75df7c-b1c1-4fea-b3a2-93716485f7b1"},{"name":"Update UserSchedule","id":"e7fbbb3d-c50e-4319-b95d-3196dc691a3a","request":{"method":"PUT","header":[],"body":{"mode":"raw","raw":"{\n  \"startAt\": \"2026-08-03T13:00:00.000Z\",\n  \"endAt\": \"2026-08-03T21:00:00.000Z\"\n}","options":{"raw":{"language":"json"}}},"url":"{{hostname}}/v2/userSchedules/:id","description":"<p>Replaces a shift’s start and end times.</p>\n<p><strong>Required role:</strong> <code>ADMIN</code> or higher. An account API key always satisfies this (it authenticates as the account owner).</p>\n<h4 id=\"body-fields\">Body fields</h4>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Field</th>\n<th>Type</th>\n<th>Required</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>startAt</code></td>\n<td>string (ISO 8601)</td>\n<td>Yes</td>\n<td>New shift start.</td>\n</tr>\n<tr>\n<td><code>endAt</code></td>\n<td>string (ISO 8601)</td>\n<td>Yes</td>\n<td>New shift end.</td>\n</tr>\n</tbody>\n</table>\n</div><h4 id=\"response\">Response</h4>\n<p>Responds <code>204 No Content</code>.</p>\n","auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{apiKey}}"}]},"isInherited":true,"source":{"_postman_id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","name":"ShuttleControl Open API","type":"collection"}},"urlObject":{"path":["v2","userSchedules",":id"],"host":["{{hostname}}"],"query":[],"variable":[{"id":"0224a806-2956-4d56-b80e-1e717b53db8d","description":{"content":"<p>UUID of the schedule.</p>\n","type":"text/plain"},"type":"any","value":"","key":"id"}]}},"response":[],"_postman_id":"e7fbbb3d-c50e-4319-b95d-3196dc691a3a"},{"name":"Delete UserSchedule","id":"b351465f-a2ce-4b40-a7dd-0a2bfe6c09b9","request":{"method":"DELETE","header":[],"url":"{{hostname}}/v2/userSchedules/:id","description":"<p>Deletes a single shift.</p>\n<p><strong>Required role:</strong> <code>ADMIN</code> or higher. An account API key always satisfies this (it authenticates as the account owner).</p>\n<h4 id=\"response\">Response</h4>\n<p>Responds <code>204 No Content</code>.</p>\n","auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{apiKey}}"}]},"isInherited":true,"source":{"_postman_id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","name":"ShuttleControl Open API","type":"collection"}},"urlObject":{"path":["v2","userSchedules",":id"],"host":["{{hostname}}"],"query":[],"variable":[{"id":"87326ae0-1339-4ab8-a120-a0410904532f","description":{"content":"<p>UUID of the schedule.</p>\n","type":"text/plain"},"type":"any","value":"","key":"id"}]}},"response":[],"_postman_id":"b351465f-a2ce-4b40-a7dd-0a2bfe6c09b9"},{"name":"Delete All Schedules For User","id":"ffa407db-cbd0-481b-b906-19bbc77cf7ff","request":{"method":"DELETE","header":[],"url":"{{hostname}}/v2/userSchedules/forUser/:id","description":"<p>Deletes every shift belonging to the given user.</p>\n<p><strong>Required role:</strong> <code>ADMIN</code> or higher. An account API key always satisfies this (it authenticates as the account owner).</p>\n<h4 id=\"response\">Response</h4>\n<p>Responds <code>204 No Content</code>.</p>\n","auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{apiKey}}"}]},"isInherited":true,"source":{"_postman_id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","name":"ShuttleControl Open API","type":"collection"}},"urlObject":{"path":["v2","userSchedules","forUser",":id"],"host":["{{hostname}}"],"query":[],"variable":[{"id":"7d7c0aef-b60e-4949-ac72-373f539e3d0a","description":{"content":"<p>UUID of the <strong>user</strong> whose shifts to delete.</p>\n","type":"text/plain"},"type":"any","value":"","key":"id"}]}},"response":[],"_postman_id":"ffa407db-cbd0-481b-b906-19bbc77cf7ff"}],"id":"c91c7381-b71d-4e95-ab5e-6243884152c9","description":"<p>Work shifts for your staff. Auto-dispatch uses driver schedules to decide who can take a trip, so creating/updating/deleting a schedule re-runs auto-dispatch for that user.</p>\n","_postman_id":"c91c7381-b71d-4e95-ab5e-6243884152c9","auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{apiKey}}"}]},"isInherited":true,"source":{"_postman_id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","name":"ShuttleControl Open API","type":"collection"}}},{"name":"VehicleDriverLogs","item":[{"name":"Create VehicleDriverLog","id":"bdfdc1e2-db76-407f-a631-9a7a7bb18322","request":{"method":"POST","header":[],"body":{"mode":"raw","raw":"{\n  \"vehicle\": \"b2c3d4e5-0000-0000-0000-000000000000\",\n  \"driver\": \"4be9f1e0-0000-0000-0000-000000000000\",\n  \"claimedAt\": \"2026-07-28T12:00:00.000Z\",\n  \"releasedAt\": \"2026-07-28T20:00:00.000Z\"\n}","options":{"raw":{"language":"json"}}},"url":"{{hostname}}/v2/vehicleDriverLogs","description":"<p>Manually records a vehicle-possession entry (e.g. to backfill a missed claim).</p>\n<p><strong>Required role:</strong> <code>ADMIN</code> or higher. An account API key always satisfies this (it authenticates as the account owner).</p>\n<h4 id=\"body-fields\">Body fields</h4>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Field</th>\n<th>Type</th>\n<th>Required</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>vehicle</code></td>\n<td>string (UUID)</td>\n<td>Yes</td>\n<td>The vehicle.</td>\n</tr>\n<tr>\n<td><code>driver</code></td>\n<td>string (UUID)</td>\n<td>Yes</td>\n<td>The driver who held it.</td>\n</tr>\n<tr>\n<td><code>claimedAt</code></td>\n<td>string (ISO 8601)</td>\n<td>Yes</td>\n<td>When the driver took the vehicle.</td>\n</tr>\n<tr>\n<td><code>releasedAt</code></td>\n<td>string (ISO 8601)</td>\n<td>Yes</td>\n<td>When the driver released it.</td>\n</tr>\n</tbody>\n</table>\n</div><h4 id=\"response\">Response</h4>\n<p>Responds <code>201</code> with the created log entry.</p>\n","auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{apiKey}}"}]},"isInherited":true,"source":{"_postman_id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","name":"ShuttleControl Open API","type":"collection"}},"urlObject":{"path":["v2","vehicleDriverLogs"],"host":["{{hostname}}"],"query":[],"variable":[]}},"response":[],"_postman_id":"bdfdc1e2-db76-407f-a631-9a7a7bb18322"},{"name":"List VehicleDriverLogs","id":"0e24ee7f-c7c6-4f02-8268-0cc9858d8532","request":{"method":"GET","header":[],"url":"{{hostname}}/v2/vehicleDriverLogs?startDate=2026-07-01T00:00:00.000Z&endDate=2026-07-31T23:59:59.000Z","description":"<p>Returns log entries overlapping the given window for the caller’s stores. Pagination is optional — omit <code>page</code>/<code>size</code> to get all matches.</p>\n<h4 id=\"response\">Response</h4>\n<p>Returns <code>{ items, count }</code> — each item includes the vehicle, driver, <code>claimedAt</code>, <code>releasedAt</code>, and <code>duration</code> (seconds).</p>\n","auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{apiKey}}"}]},"isInherited":true,"source":{"_postman_id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","name":"ShuttleControl Open API","type":"collection"}},"urlObject":{"path":["v2","vehicleDriverLogs"],"host":["{{hostname}}"],"query":[{"description":{"content":"<p>Required. ISO 8601 window start.</p>\n","type":"text/plain"},"key":"startDate","value":"2026-07-01T00:00:00.000Z"},{"description":{"content":"<p>Required. ISO 8601 window end.</p>\n","type":"text/plain"},"key":"endDate","value":"2026-07-31T23:59:59.000Z"},{"disabled":true,"description":{"content":"<p>Zero-based page index (optional).</p>\n","type":"text/plain"},"key":"page","value":"0"},{"disabled":true,"description":{"content":"<p>Page size, 1–100 (optional).</p>\n","type":"text/plain"},"key":"size","value":"10"},{"disabled":true,"description":{"content":"<p>Filter to one store.</p>\n","type":"text/plain"},"key":"storeId","value":""},{"disabled":true,"description":{"content":"<p>Filter to one driver.</p>\n","type":"text/plain"},"key":"driverId","value":""}],"variable":[]}},"response":[],"_postman_id":"0e24ee7f-c7c6-4f02-8268-0cc9858d8532"},{"name":"Get VehicleDriverLog","id":"4db6e6e1-a14b-4734-a401-a008f2d7d656","request":{"method":"GET","header":[],"url":"{{hostname}}/v2/vehicleDriverLogs/:id","description":"<p>Returns a single log entry.</p>\n<h4 id=\"response\">Response</h4>\n<p>Returns the log entry object.</p>\n","auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{apiKey}}"}]},"isInherited":true,"source":{"_postman_id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","name":"ShuttleControl Open API","type":"collection"}},"urlObject":{"path":["v2","vehicleDriverLogs",":id"],"host":["{{hostname}}"],"query":[],"variable":[{"id":"994858d4-4608-4beb-b448-80f8f65bf597","description":{"content":"<p>UUID of the log entry.</p>\n","type":"text/plain"},"type":"any","value":"","key":"id"}]}},"response":[],"_postman_id":"4db6e6e1-a14b-4734-a401-a008f2d7d656"},{"name":"Update VehicleDriverLog","id":"b7525dd4-8004-45ef-814b-b899744b360b","request":{"method":"PUT","header":[],"body":{"mode":"raw","raw":"{\n  \"vehicle\": \"b2c3d4e5-0000-0000-0000-000000000000\",\n  \"claimedAt\": \"2026-07-28T12:30:00.000Z\",\n  \"releasedAt\": \"2026-07-28T20:00:00.000Z\",\n  \"duration\": 27000\n}","options":{"raw":{"language":"json"}}},"url":"{{hostname}}/v2/vehicleDriverLogs/:id","description":"<p>Corrects a log entry. <code>duration</code> is recomputed server-side from <code>claimedAt</code>/<code>releasedAt</code>.</p>\n<p><strong>Required role:</strong> <code>ADMIN</code> or higher. An account API key always satisfies this (it authenticates as the account owner).</p>\n<h4 id=\"body-fields\">Body fields</h4>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Field</th>\n<th>Type</th>\n<th>Required</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>vehicle</code></td>\n<td>string (UUID)</td>\n<td>Yes</td>\n<td>The vehicle.</td>\n</tr>\n<tr>\n<td><code>claimedAt</code></td>\n<td>string (ISO 8601)</td>\n<td>Yes</td>\n<td>Corrected claim time.</td>\n</tr>\n<tr>\n<td><code>releasedAt</code></td>\n<td>string (ISO 8601)</td>\n<td>Yes</td>\n<td>Corrected release time.</td>\n</tr>\n<tr>\n<td><code>duration</code></td>\n<td>integer</td>\n<td>Yes</td>\n<td>Seconds; accepted for backward compatibility but recomputed from the timestamps.</td>\n</tr>\n</tbody>\n</table>\n</div><h4 id=\"response\">Response</h4>\n<p>Returns the updated log entry.</p>\n","auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{apiKey}}"}]},"isInherited":true,"source":{"_postman_id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","name":"ShuttleControl Open API","type":"collection"}},"urlObject":{"path":["v2","vehicleDriverLogs",":id"],"host":["{{hostname}}"],"query":[],"variable":[{"id":"71852e25-9053-424a-bf16-784990521689","description":{"content":"<p>UUID of the log entry.</p>\n","type":"text/plain"},"type":"any","value":"","key":"id"}]}},"response":[],"_postman_id":"b7525dd4-8004-45ef-814b-b899744b360b"},{"name":"Delete VehicleDriverLog","id":"f1812264-09f6-4baa-a0fa-39e13a387a1d","request":{"method":"DELETE","header":[],"url":"{{hostname}}/v2/vehicleDriverLogs/:id","description":"<p>Permanently deletes a log entry.</p>\n<p><strong>Required role:</strong> <code>ADMIN</code> or higher. An account API key always satisfies this (it authenticates as the account owner).</p>\n<h4 id=\"response\">Response</h4>\n<p>Responds <code>204 No Content</code>.</p>\n","auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{apiKey}}"}]},"isInherited":true,"source":{"_postman_id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","name":"ShuttleControl Open API","type":"collection"}},"urlObject":{"path":["v2","vehicleDriverLogs",":id"],"host":["{{hostname}}"],"query":[],"variable":[{"id":"c5e18e24-c6ae-46c8-b411-ac37141a668f","description":{"content":"<p>UUID of the log entry.</p>\n","type":"text/plain"},"type":"any","value":"","key":"id"}]}},"response":[],"_postman_id":"f1812264-09f6-4baa-a0fa-39e13a387a1d"}],"id":"11def3ee-5144-49d7-95c8-2416bdc6222b","description":"<p>The audit log of which driver held which vehicle and when. Entries are created automatically when drivers claim/release vehicles; these endpoints let you list them and make manual corrections.</p>\n","_postman_id":"11def3ee-5144-49d7-95c8-2416bdc6222b","auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{apiKey}}"}]},"isInherited":true,"source":{"_postman_id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","name":"ShuttleControl Open API","type":"collection"}}},{"name":"OSRM","item":[{"name":"Route","id":"d40e5437-e779-4f81-ba4f-58163a531627","request":{"method":"POST","header":[],"body":{"mode":"raw","raw":"{\n  \"points\": [\n    {\n      \"latitude\": 45.5019,\n      \"longitude\": -73.5674\n    },\n    {\n      \"latitude\": 45.4706,\n      \"longitude\": -73.7408\n    }\n  ],\n  \"steps\": false\n}","options":{"raw":{"language":"json"}}},"url":"{{hostname}}/v2/osrm/route","description":"<p>Computes the driving route through the given points, in order.</p>\n<h4 id=\"body-fields\">Body fields</h4>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Field</th>\n<th>Type</th>\n<th>Required</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>points</code></td>\n<td>object[]</td>\n<td>Yes</td>\n<td>Two or more waypoints: <code>[{ latitude: number, longitude: number }]</code>.</td>\n</tr>\n<tr>\n<td><code>steps</code></td>\n<td>boolean</td>\n<td>No</td>\n<td>When <code>true</code>, includes turn-by-turn steps (and omits the overview geometry).</td>\n</tr>\n</tbody>\n</table>\n</div><h4 id=\"response\">Response</h4>\n<p>Returns the OSRM route response: <code>routes[]</code> with <code>distance</code> (meters), <code>duration</code> (seconds), and geometry.</p>\n","auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{apiKey}}"}]},"isInherited":true,"source":{"_postman_id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","name":"ShuttleControl Open API","type":"collection"}},"urlObject":{"path":["v2","osrm","route"],"host":["{{hostname}}"],"query":[],"variable":[]}},"response":[{"id":"8c9b4793-9ae6-444c-9d3b-2d6e06260003","name":"Route","originalRequest":{"method":"POST","header":[],"body":{"mode":"raw","raw":"{\n    \"points\": [\n        {\n            \"latitude\": 45.457755310612356,\n            \"longitude\": -73.59553709374609\n        },\n        {\n            \"latitude\": 45.45205785618882,\n            \"longitude\": -73.59109305052687\n        }\n    ]\n}","options":{"raw":{"language":"json"}}},"url":"{{hostname}}/v2/osrm/route"},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Access-Control-Allow-Origin","value":"*"},{"key":"Content-Security-Policy","value":"default-src 'self';base-uri 'self';font-src 'self' https: data:;form-action 'self';frame-ancestors 'self';img-src 'self' data:;object-src 'none';script-src 'self';script-src-attr 'none';style-src 'self' https: 'unsafe-inline';upgrade-insecure-requests"},{"key":"Cross-Origin-Embedder-Policy","value":"require-corp"},{"key":"Cross-Origin-Opener-Policy","value":"same-origin"},{"key":"X-DNS-Prefetch-Control","value":"off"},{"key":"X-Frame-Options","value":"SAMEORIGIN"},{"key":"Strict-Transport-Security","value":"max-age=15552000; includeSubDomains"},{"key":"X-Download-Options","value":"noopen"},{"key":"X-Content-Type-Options","value":"nosniff"},{"key":"Origin-Agent-Cluster","value":"?1"},{"key":"X-Permitted-Cross-Domain-Policies","value":"none"},{"key":"Referrer-Policy","value":"no-referrer"},{"key":"X-XSS-Protection","value":"0"},{"key":"Content-Type","value":"application/json; charset=utf-8"},{"key":"Content-Length","value":"638"},{"key":"ETag","value":"W/\"27e-4L+9X+hChj/IrvWlQZPIQYiHhRE\""},{"key":"Vary","value":"Accept-Encoding"},{"key":"Date","value":"Fri, 23 Feb 2024 20:26:40 GMT"},{"key":"Connection","value":"keep-alive"},{"key":"Keep-Alive","value":"timeout=5"}],"cookie":[],"responseTime":null,"body":"{\n    \"code\": \"Ok\",\n    \"routes\": [\n        {\n            \"geometry\": \"ymmtG~ce`Mzg@gN_AkJmAZByA\",\n            \"legs\": [\n                {\n                    \"steps\": [],\n                    \"summary\": \"\",\n                    \"weight\": 121.1,\n                    \"duration\": 112.6,\n                    \"distance\": 977.7\n                }\n            ],\n            \"weight_name\": \"routability\",\n            \"weight\": 121.1,\n            \"duration\": 112.6,\n            \"distance\": 977.7\n        }\n    ],\n    \"waypoints\": [\n        {\n            \"hint\": \"CF0DgDVdA4BNAAAAMwAAAAAAAAAAAAAANP-qQne9YUIAAAAAAAAAAE0AAAAzAAAAAAAAAAAAAACHAgAA3wSd-0GhtQJvBZ37W6G1AgAAXwrAZ-q-\",\n            \"distance\": 11.624626594,\n            \"name\": \"Boulevard Monk\",\n            \"location\": [\n                -73.595681,\n                45.457729\n            ]\n        },\n        {\n            \"hint\": \"cVgDgHlYA4CMAQAAqwAAAAAAAAAAAAAA--ykQhGJDkIAAAAAAAAAAMUAAABWAAAAAAAAAAAAAACHAgAAvRad-2WKtQLLFp37Gou1AgAAHxHAZ-q-\",\n            \"distance\": 20.146295365,\n            \"name\": \"\",\n            \"location\": [\n                -73.591107,\n                45.451877\n            ]\n        }\n    ]\n}"}],"_postman_id":"d40e5437-e779-4f81-ba4f-58163a531627"}],"id":"6a823a7b-36e0-4c63-b88d-ea3c6cb8c6c0","description":"<p>Road routing powered by OSRM.</p>\n","_postman_id":"6a823a7b-36e0-4c63-b88d-ea3c6cb8c6c0","auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{apiKey}}"}]},"isInherited":true,"source":{"_postman_id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","name":"ShuttleControl Open API","type":"collection"}}},{"name":"Stores","item":[{"name":"Get Stores","id":"9910aa3d-7c3e-456c-9750-0bde4c47a043","request":{"method":"GET","header":[],"url":"{{hostname}}/v2/stores","description":"<p>Returns every active store visible to the caller.</p>\n<p><strong>Required role:</strong> <code>ADMIN</code> or higher. An account API key always satisfies this (it authenticates as the account owner).</p>\n<h4 id=\"response\">Response</h4>\n<p>Returns <code>{ items, count, total, storeLimit }</code> — <code>total</code> is the account-wide store count and <code>storeLimit</code> your plan’s cap (<code>0</code> = unlimited).</p>\n","auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{apiKey}}"}]},"isInherited":true,"source":{"_postman_id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","name":"ShuttleControl Open API","type":"collection"}},"urlObject":{"path":["v2","stores"],"host":["{{hostname}}"],"query":[],"variable":[]}},"response":[{"id":"bf7651dd-6011-4621-a5f1-47cf7b92e426","name":"Get Stores response","originalRequest":{"method":"GET","header":[],"url":"{{hostname}}/v2/stores"},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Access-Control-Allow-Origin","value":"*"},{"key":"Content-Security-Policy","value":"default-src 'self';base-uri 'self';font-src 'self' https: data:;form-action 'self';frame-ancestors 'self';img-src 'self' data:;object-src 'none';script-src 'self';script-src-attr 'none';style-src 'self' https: 'unsafe-inline';upgrade-insecure-requests"},{"key":"Cross-Origin-Embedder-Policy","value":"require-corp"},{"key":"Cross-Origin-Opener-Policy","value":"same-origin"},{"key":"X-DNS-Prefetch-Control","value":"off"},{"key":"X-Frame-Options","value":"SAMEORIGIN"},{"key":"Strict-Transport-Security","value":"max-age=15552000; includeSubDomains"},{"key":"X-Download-Options","value":"noopen"},{"key":"X-Content-Type-Options","value":"nosniff"},{"key":"Origin-Agent-Cluster","value":"?1"},{"key":"X-Permitted-Cross-Domain-Policies","value":"none"},{"key":"Referrer-Policy","value":"no-referrer"},{"key":"X-XSS-Protection","value":"0"},{"key":"Content-Type","value":"application/json; charset=utf-8"},{"key":"Content-Length","value":"723"},{"key":"ETag","value":"W/\"2d3-fFd/DgVobkDV8RuBy2OE7HRFeLg\""},{"key":"Vary","value":"Accept-Encoding"},{"key":"Date","value":"Mon, 08 Apr 2024 19:11:10 GMT"},{"key":"Connection","value":"keep-alive"},{"key":"Keep-Alive","value":"timeout=5"}],"cookie":[],"responseTime":null,"body":"{\n    \"items\": [\n        {\n            \"id\": \"495fd56c-6484-4198-bac2-d3ffd4455f4a\",\n            \"name\": \"Alpha Storex\",\n            \"color\": \"blue\",\n            \"enabled\": true,\n            \"place\": {\n                \"id\": \"5c3d5c7d-0812-420d-85b0-92731917dd6f\",\n                \"address\": \"Saint Joseph's Oratory of Mount Royal\",\n                \"latitude\": 45.4919122,\n                \"longitude\": -73.6186555\n            },\n            \"radiusBound\": null,\n            \"createdAt\": \"2024-03-27T17:56:31.354Z\",\n            \"liveTVWaypoints\": [],\n            \"zones\": []\n        },\n        {\n            \"id\": \"4554e868-2e21-4cdf-b9f4-378a3254565f\",\n            \"name\": \"Bravo Store\",\n            \"color\": \"blue\",\n            \"enabled\": true,\n            \"place\": {\n                \"id\": \"3b18c62e-ceb2-490b-9a1e-2c0d65157918\",\n                \"address\": \"3901 Bannantyne Ave, Verdun, QC H4G 1B9\",\n                \"latitude\": 45.4651629,\n                \"longitude\": -73.5756481\n            },\n            \"radiusBound\": null,\n            \"createdAt\": \"2024-03-27T17:56:31.362Z\",\n            \"liveTVWaypoints\": [],\n            \"zones\": []\n        }\n    ],\n    \"count\": 2,\n    \"total\": 2,\n    \"storeLimit\": 5\n}"}],"_postman_id":"9910aa3d-7c3e-456c-9750-0bde4c47a043"},{"name":"Get Archived Stores","id":"01cd357a-3fcb-4632-b364-e10089b74fbf","request":{"method":"GET","header":[],"url":"{{hostname}}/v2/stores/archived","description":"<p>Returns the account’s archived stores.</p>\n<p><strong>Required role:</strong> <code>ADMIN</code> or higher. An account API key always satisfies this (it authenticates as the account owner).</p>\n<h4 id=\"response\">Response</h4>\n<p>Returns <code>{ items, count }</code>.</p>\n","auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{apiKey}}"}]},"isInherited":true,"source":{"_postman_id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","name":"ShuttleControl Open API","type":"collection"}},"urlObject":{"path":["v2","stores","archived"],"host":["{{hostname}}"],"query":[],"variable":[]}},"response":[{"id":"62081261-7aa4-438c-baa0-6848df75998f","name":"Get Archived Stores response","originalRequest":{"method":"GET","header":[],"url":"{{hostname}}/v2/stores/archived"},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Access-Control-Allow-Origin","value":"*"},{"key":"Content-Security-Policy","value":"default-src 'self';base-uri 'self';font-src 'self' https: data:;form-action 'self';frame-ancestors 'self';img-src 'self' data:;object-src 'none';script-src 'self';script-src-attr 'none';style-src 'self' https: 'unsafe-inline';upgrade-insecure-requests"},{"key":"Cross-Origin-Embedder-Policy","value":"require-corp"},{"key":"Cross-Origin-Opener-Policy","value":"same-origin"},{"key":"X-DNS-Prefetch-Control","value":"off"},{"key":"X-Frame-Options","value":"SAMEORIGIN"},{"key":"Strict-Transport-Security","value":"max-age=15552000; includeSubDomains"},{"key":"X-Download-Options","value":"noopen"},{"key":"X-Content-Type-Options","value":"nosniff"},{"key":"Origin-Agent-Cluster","value":"?1"},{"key":"X-Permitted-Cross-Domain-Policies","value":"none"},{"key":"Referrer-Policy","value":"no-referrer"},{"key":"X-XSS-Protection","value":"0"},{"key":"Content-Type","value":"application/json; charset=utf-8"},{"key":"Content-Length","value":"340"},{"key":"ETag","value":"W/\"154-RrTx4apIQRjAECRJkzFRP7xtEzQ\""},{"key":"Vary","value":"Accept-Encoding"},{"key":"Date","value":"Mon, 08 Apr 2024 19:13:49 GMT"},{"key":"Connection","value":"keep-alive"},{"key":"Keep-Alive","value":"timeout=5"}],"cookie":[],"responseTime":null,"body":"{\n    \"items\": [\n        {\n            \"id\": \"4554e868-2e21-4cdf-b9f4-378a3254565f\",\n            \"name\": \"Bravo Store\",\n            \"color\": \"blue\",\n            \"enabled\": false,\n            \"place\": {\n                \"id\": \"3b18c62e-ceb2-490b-9a1e-2c0d65157918\",\n                \"address\": \"3901 Bannantyne Ave, Verdun, QC H4G 1B9\",\n                \"latitude\": 45.4651629,\n                \"longitude\": -73.5756481\n            },\n            \"radiusBound\": null,\n            \"createdAt\": \"2024-03-27T17:56:31.362Z\",\n            \"zones\": []\n        }\n    ],\n    \"count\": 1\n}"}],"_postman_id":"01cd357a-3fcb-4632-b364-e10089b74fbf"},{"name":"Create Store","id":"06cb59b7-da72-4997-a262-aad1fc8d143c","request":{"method":"POST","header":[],"body":{"mode":"raw","raw":"{\n  \"name\": \"Downtown branch\",\n  \"color\": \"#1677ff\",\n  \"address\": \"1 Main St, Montreal, QC\",\n  \"addDefaultWorkflows\": true,\n  \"allowTripOutsideRadius\": true,\n  \"autoDispatchEnabled\": false,\n  \"autoDispatchScheduledTripEnabled\": false,\n  \"overbookingPreventionEnabled\": false,\n  \"radiusBound\": null,\n  \"tripOptimizationHeuristic\": \"MINIMIZE_DURATION\"\n}","options":{"raw":{"language":"json"}}},"url":"{{hostname}}/v2/stores","description":"<p>Creates a store. The address is geocoded into the store’s home place. The name must be unique on the account (<code>409 STORE_NAME_TAKEN</code>); plan store limits apply (<code>400 STORE_LIMIT_REACHED</code>). The caller and the account owner are automatically assigned to the new store.</p>\n<p><strong>Required role:</strong> <code>ADMIN</code> or higher. An account API key always satisfies this (it authenticates as the account owner).</p>\n<h4 id=\"body-fields\">Body fields</h4>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Field</th>\n<th>Type</th>\n<th>Required</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>name</code></td>\n<td>string</td>\n<td>Yes</td>\n<td>Store name, max 100 characters. Unique per account.</td>\n</tr>\n<tr>\n<td><code>color</code></td>\n<td>string</td>\n<td>Yes</td>\n<td>Display color (hex), max 100.</td>\n</tr>\n<tr>\n<td><code>address</code></td>\n<td>string</td>\n<td>Yes</td>\n<td>The store’s address, max 100 characters. Geocoded server-side.</td>\n</tr>\n<tr>\n<td><code>addDefaultWorkflows</code></td>\n<td>boolean</td>\n<td>Yes</td>\n<td>Seed the store with the default workflows for your account’s industry.</td>\n</tr>\n<tr>\n<td><code>allowTripOutsideRadius</code></td>\n<td>boolean</td>\n<td>Yes</td>\n<td>Whether trips may extend beyond <code>radiusBound</code>.</td>\n</tr>\n<tr>\n<td><code>autoDispatchEnabled</code></td>\n<td>boolean</td>\n<td>Yes</td>\n<td>Automatically assign requested trips to available drivers.</td>\n</tr>\n<tr>\n<td><code>autoDispatchScheduledTripEnabled</code></td>\n<td>boolean</td>\n<td>Yes</td>\n<td>Auto-dispatch scheduled trips too.</td>\n</tr>\n<tr>\n<td><code>overbookingPreventionEnabled</code></td>\n<td>boolean</td>\n<td>Yes</td>\n<td>Reject scheduled bookings that exceed vehicle capacity.</td>\n</tr>\n<tr>\n<td><code>radiusBound</code></td>\n<td>integer</td>\n<td>null</td>\n<td>No</td>\n</tr>\n<tr>\n<td><code>tripOptimizationHeuristic</code></td>\n<td>string</td>\n<td>No</td>\n<td><code>MINIMIZE_DURATION</code> (default) or <code>MINIMIZE_DISTANCE</code>.</td>\n</tr>\n<tr>\n<td><code>kioskWorkflows</code></td>\n<td>string[] (UUID)</td>\n<td>No</td>\n<td>Workflows to expose on the store kiosk.</td>\n</tr>\n</tbody>\n</table>\n</div><h4 id=\"response\">Response</h4>\n<p>Responds <code>201</code> with the created store (including its geocoded <code>place</code>).</p>\n","auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{apiKey}}"}]},"isInherited":true,"source":{"_postman_id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","name":"ShuttleControl Open API","type":"collection"}},"urlObject":{"path":["v2","stores"],"host":["{{hostname}}"],"query":[],"variable":[]}},"response":[{"id":"aaafa6d0-532b-439e-b962-779e39c84443","name":"Create Store response","originalRequest":{"method":"POST","header":[],"body":{"mode":"raw","raw":"{\n    \"addDefaultWorkflows\": true,\n    \"name\": \"Silverline Motors\",\n    \"color\": \"skyblue\",\n    \"address\": \"1234 Oakwood Drive, Grandview, CA 90210\",\n    \"radiusBound\": 50\n}","options":{"raw":{"language":"json"}}},"url":"{{hostname}}/v2/stores"},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Access-Control-Allow-Origin","value":"*"},{"key":"Content-Security-Policy","value":"default-src 'self';base-uri 'self';font-src 'self' https: data:;form-action 'self';frame-ancestors 'self';img-src 'self' data:;object-src 'none';script-src 'self';script-src-attr 'none';style-src 'self' https: 'unsafe-inline';upgrade-insecure-requests"},{"key":"Cross-Origin-Embedder-Policy","value":"require-corp"},{"key":"Cross-Origin-Opener-Policy","value":"same-origin"},{"key":"X-DNS-Prefetch-Control","value":"off"},{"key":"X-Frame-Options","value":"SAMEORIGIN"},{"key":"Strict-Transport-Security","value":"max-age=15552000; includeSubDomains"},{"key":"X-Download-Options","value":"noopen"},{"key":"X-Content-Type-Options","value":"nosniff"},{"key":"Origin-Agent-Cluster","value":"?1"},{"key":"X-Permitted-Cross-Domain-Policies","value":"none"},{"key":"Referrer-Policy","value":"no-referrer"},{"key":"X-XSS-Protection","value":"0"},{"key":"Location","value":"undefined/v2/stores/35772dfa-81cf-40ab-a6c1-30fb54797e60"},{"key":"Content-Type","value":"application/json; charset=utf-8"},{"key":"ETag","value":"W/\"446-SuXqoMkQ+eKyM5QGzwQzOFoRWg4\""},{"key":"Vary","value":"Accept-Encoding"},{"key":"Content-Encoding","value":"gzip"},{"key":"Date","value":"Mon, 08 Apr 2024 19:46:56 GMT"},{"key":"Connection","value":"keep-alive"},{"key":"Keep-Alive","value":"timeout=5"},{"key":"Transfer-Encoding","value":"chunked"}],"cookie":[],"responseTime":null,"body":"{\n    \"id\": \"35772dfa-81cf-40ab-a6c1-30fb54797e60\",\n    \"account\": \"ee05a9bb-fd36-4805-bd05-cd8f48c0e03a\",\n    \"name\": \"Silverline Motors\",\n    \"createdBy\": \"e8c091d9-5303-411f-9c1b-05acbe8a6496\",\n    \"color\": \"skyblue\",\n    \"place\": {\n        \"id\": \"9b745f9f-4efe-4fb3-9853-7a35ad201e3a\",\n        \"store\": {\n            \"id\": \"35772dfa-81cf-40ab-a6c1-30fb54797e60\",\n            \"account\": \"ee05a9bb-fd36-4805-bd05-cd8f48c0e03a\",\n            \"name\": \"Silverline Motors\",\n            \"createdBy\": \"e8c091d9-5303-411f-9c1b-05acbe8a6496\",\n            \"color\": \"skyblue\",\n            \"place\": null,\n            \"radiusBound\": 50,\n            \"iconUrl\": null,\n            \"markerUrl\": null,\n            \"enabled\": true,\n            \"createdAt\": \"2024-04-08T19:46:55.768Z\",\n            \"updatedAt\": null,\n            \"updatedBy\": null,\n            \"users\": [],\n            \"liveTVShortUrl\": \"\",\n            \"kioskShortUrl\": \"\",\n            \"autoDispatchEnabled\": false,\n            \"kioskTripsPending\": false\n        },\n        \"latitude\": 34.1030032,\n        \"longitude\": -118.4104684,\n        \"address\": \"1234 Oakwood Drive, Grandview, CA 90210\",\n        \"isFavorite\": true,\n        \"createdAt\": \"2024-04-08T19:46:55.817Z\"\n    },\n    \"radiusBound\": 50,\n    \"iconUrl\": null,\n    \"markerUrl\": null,\n    \"enabled\": true,\n    \"createdAt\": \"2024-04-08T19:46:55.768Z\",\n    \"updatedAt\": null,\n    \"updatedBy\": null,\n    \"users\": [],\n    \"liveTVShortUrl\": \"\",\n    \"kioskShortUrl\": \"\",\n    \"autoDispatchEnabled\": false,\n    \"kioskTripsPending\": false\n}"}],"_postman_id":"06cb59b7-da72-4997-a262-aad1fc8d143c"},{"name":"Get Store","id":"e223d832-3802-40aa-b803-a973459a8dd9","request":{"method":"GET","header":[],"url":"{{hostname}}/v2/stores/:id","description":"<p>Returns a single store with its place, settings, and zones.</p>\n<h4 id=\"response\">Response</h4>\n<p>Returns the store object.</p>\n","auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{apiKey}}"}]},"isInherited":true,"source":{"_postman_id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","name":"ShuttleControl Open API","type":"collection"}},"urlObject":{"path":["v2","stores",":id"],"host":["{{hostname}}"],"query":[],"variable":[{"id":"1e6c4b4b-7d8c-4dfb-a289-7f8cb34141d9","description":{"content":"<p>UUID of the store.</p>\n","type":"text/plain"},"type":"any","value":"","key":"id"}]}},"response":[{"id":"16affedd-637c-46b4-a646-263c97dd98ed","name":"Get Store response","originalRequest":{"method":"GET","header":[],"url":"{{hostname}}/v2/stores/"},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Access-Control-Allow-Origin","value":"*"},{"key":"Content-Security-Policy","value":"default-src 'self';base-uri 'self';font-src 'self' https: data:;form-action 'self';frame-ancestors 'self';img-src 'self' data:;object-src 'none';script-src 'self';script-src-attr 'none';style-src 'self' https: 'unsafe-inline';upgrade-insecure-requests"},{"key":"Cross-Origin-Embedder-Policy","value":"require-corp"},{"key":"Cross-Origin-Opener-Policy","value":"same-origin"},{"key":"X-DNS-Prefetch-Control","value":"off"},{"key":"X-Frame-Options","value":"SAMEORIGIN"},{"key":"Strict-Transport-Security","value":"max-age=15552000; includeSubDomains"},{"key":"X-Download-Options","value":"noopen"},{"key":"X-Content-Type-Options","value":"nosniff"},{"key":"Origin-Agent-Cluster","value":"?1"},{"key":"X-Permitted-Cross-Domain-Policies","value":"none"},{"key":"Referrer-Policy","value":"no-referrer"},{"key":"X-XSS-Protection","value":"0"},{"key":"Content-Type","value":"application/json; charset=utf-8"},{"key":"Content-Length","value":"580"},{"key":"ETag","value":"W/\"244-tVEXedyp76BGVhfr7mxQkjEYxDo\""},{"key":"Vary","value":"Accept-Encoding"},{"key":"Date","value":"Tue, 09 Apr 2024 14:40:09 GMT"},{"key":"Connection","value":"keep-alive"},{"key":"Keep-Alive","value":"timeout=5"}],"cookie":[],"responseTime":null,"body":"{\n    \"id\": \"4554e868-2e21-4cdf-b9f4-378a3254565f\",\n    \"name\": \"Bravo Store\",\n    \"color\": \"blue\",\n    \"enabled\": true,\n    \"iconUrl\": null,\n    \"liveTVShortUrl\": \"\",\n    \"liveTVWaypoints\": [],\n    \"kioskShortUrl\": \"\",\n    \"autoDispatchEnabled\": false,\n    \"kioskTripsPending\": false,\n    \"place\": {\n        \"id\": \"3b18c62e-ceb2-490b-9a1e-2c0d65157918\",\n        \"address\": \"3901 Bannantyne Ave, Verdun, QC H4G 1B9\",\n        \"latitude\": 45.4651629,\n        \"longitude\": -73.5756481\n    },\n    \"radiusBound\": null,\n    \"createdAt\": \"2024-03-27T17:56:31.362Z\",\n    \"createdBy\": {\n        \"id\": \"e8c091d9-5303-411f-9c1b-05acbe8a6496\",\n        \"firstName\": \"Edward\",\n        \"lastName\": \"Maxedon\"\n    },\n    \"updatedAt\": null,\n    \"updatedBy\": null,\n    \"zones\": []\n}"}],"_postman_id":"e223d832-3802-40aa-b803-a973459a8dd9"},{"name":"Update Store","id":"7f7500b8-2b58-4d27-8bc9-73cfaaba7c50","request":{"method":"PUT","header":[],"body":{"mode":"raw","raw":"{\n  \"name\": \"Downtown branch\",\n  \"color\": \"#1677ff\",\n  \"address\": \"1 Main St, Montreal, QC\",\n  \"radiusBound\": 50,\n  \"allowTripOutsideRadius\": true,\n  \"autoDispatchEnabled\": true,\n  \"autoDispatchScheduledTripEnabled\": false,\n  \"overbookingPreventionEnabled\": false,\n  \"users\": [\n    \"4be9f1e0-0000-0000-0000-000000000000\"\n  ]\n}","options":{"raw":{"language":"json"}}},"url":"{{hostname}}/v2/stores/:id","description":"<p>Replaces a store’s settings and (non-owner) user assignments. Changing <code>address</code> geocodes a new home place and repoints workflow steps that used the old one. <code>users</code> is the full replacement set of assigned users — the owner is always kept.</p>\n<p><strong>Required role:</strong> <code>ADMIN</code> or higher. An account API key always satisfies this (it authenticates as the account owner).</p>\n<h4 id=\"body-fields\">Body fields</h4>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Field</th>\n<th>Type</th>\n<th>Required</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>name</code></td>\n<td>string</td>\n<td>Yes</td>\n<td>Max 100 characters. Unique per account (<code>409</code> on conflict).</td>\n</tr>\n<tr>\n<td><code>color</code></td>\n<td>string</td>\n<td>Yes</td>\n<td>Display color (hex), max 100.</td>\n</tr>\n<tr>\n<td><code>address</code></td>\n<td>string</td>\n<td>Yes</td>\n<td>Store address, max 100 characters.</td>\n</tr>\n<tr>\n<td><code>radiusBound</code></td>\n<td>integer</td>\n<td>null</td>\n<td>Yes</td>\n</tr>\n<tr>\n<td><code>allowTripOutsideRadius</code></td>\n<td>boolean</td>\n<td>Yes</td>\n<td>Whether trips may extend beyond the radius.</td>\n</tr>\n<tr>\n<td><code>autoDispatchEnabled</code></td>\n<td>boolean</td>\n<td>Yes</td>\n<td>Auto-dispatch requested trips.</td>\n</tr>\n<tr>\n<td><code>autoDispatchScheduledTripEnabled</code></td>\n<td>boolean</td>\n<td>Yes</td>\n<td>Auto-dispatch scheduled trips.</td>\n</tr>\n<tr>\n<td><code>overbookingPreventionEnabled</code></td>\n<td>boolean</td>\n<td>Yes</td>\n<td>Reject over-capacity scheduled bookings.</td>\n</tr>\n<tr>\n<td><code>users</code></td>\n<td>string[] (UUID)</td>\n<td>Yes</td>\n<td>Full replacement set of assigned users.</td>\n</tr>\n<tr>\n<td><code>tripOptimizationHeuristic</code></td>\n<td>string</td>\n<td>No</td>\n<td><code>MINIMIZE_DURATION</code> or <code>MINIMIZE_DISTANCE</code>.</td>\n</tr>\n</tbody>\n</table>\n</div><h4 id=\"response\">Response</h4>\n<p>Returns <code>{ place }</code> — the store’s (possibly new) home place.</p>\n","auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{apiKey}}"}]},"isInherited":true,"source":{"_postman_id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","name":"ShuttleControl Open API","type":"collection"}},"urlObject":{"path":["v2","stores",":id"],"host":["{{hostname}}"],"query":[],"variable":[{"id":"80f6c5f3-71b8-4cb0-969b-3276c62fd091","description":{"content":"<p>UUID of the store.</p>\n","type":"text/plain"},"type":"any","value":"","key":"id"}]}},"response":[{"id":"3ddf6039-a16d-402c-bdcb-92d32412ecdf","name":"Update Store response","originalRequest":{"method":"PUT","header":[],"body":{"mode":"raw","raw":"{\n    \"addDefaultWorkflows\": true,\n    \"name\": \"Silverline Motors\",\n    \"color\": \"skyblue\",\n    \"address\": \"1234 Oakwood Drive, Grandview, CA 90210\",\n    \"radiusBound\": 50,\n    \"kioskTripsPending\": true,\n    \"autoDispatchEnabled\": true\n}","options":{"raw":{"language":"json"}}},"url":"{{hostname}}/v2/stores/"},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Access-Control-Allow-Origin","value":"*"},{"key":"Content-Security-Policy","value":"default-src 'self';base-uri 'self';font-src 'self' https: data:;form-action 'self';frame-ancestors 'self';img-src 'self' data:;object-src 'none';script-src 'self';script-src-attr 'none';style-src 'self' https: 'unsafe-inline';upgrade-insecure-requests"},{"key":"Cross-Origin-Embedder-Policy","value":"require-corp"},{"key":"Cross-Origin-Opener-Policy","value":"same-origin"},{"key":"X-DNS-Prefetch-Control","value":"off"},{"key":"X-Frame-Options","value":"SAMEORIGIN"},{"key":"Strict-Transport-Security","value":"max-age=15552000; includeSubDomains"},{"key":"X-Download-Options","value":"noopen"},{"key":"X-Content-Type-Options","value":"nosniff"},{"key":"Origin-Agent-Cluster","value":"?1"},{"key":"X-Permitted-Cross-Domain-Policies","value":"none"},{"key":"Referrer-Policy","value":"no-referrer"},{"key":"X-XSS-Protection","value":"0"},{"key":"Content-Type","value":"application/json; charset=utf-8"},{"key":"Content-Length","value":"214"},{"key":"ETag","value":"W/\"d6-zwkrVRa7v7L6NTcGyL/drTaFX1A\""},{"key":"Vary","value":"Accept-Encoding"},{"key":"Date","value":"Tue, 09 Apr 2024 14:44:02 GMT"},{"key":"Connection","value":"keep-alive"},{"key":"Keep-Alive","value":"timeout=5"}],"cookie":[],"responseTime":null,"body":"{\n    \"place\": {\n        \"store\": \"4554e868-2e21-4cdf-b9f4-378a3254565f\",\n        \"latitude\": 34.1030032,\n        \"longitude\": -118.4104684,\n        \"address\": \"1234 Oakwood Drive, Grandview, CA 90210\",\n        \"isFavorite\": true,\n        \"createdAt\": \"2024-04-09T14:44:02.529Z\"\n    }\n}"}],"_postman_id":"7f7500b8-2b58-4d27-8bc9-73cfaaba7c50"},{"name":"Archive Store","id":"6b8b9064-b151-4e48-9ed6-9733ecaca8c5","request":{"method":"DELETE","header":[],"body":{"mode":"raw","raw":"{\n  \"transferToStoreId\": \"9f2d1c34-0000-0000-0000-000000000000\"\n}","options":{"raw":{"language":"json"}}},"url":"{{hostname}}/v2/stores/:id/archive","description":"<p>Archives a store. Rejected while the store has active trips (<code>400 STORE_HAS_ACTIVE_TRIPS</code>). All claimed vehicles are released; users whose only store this was are moved to <code>transferToStoreId</code>, everyone else is simply unassigned.</p>\n<p><strong>Required role:</strong> <code>ADMIN</code> or higher. An account API key always satisfies this (it authenticates as the account owner).</p>\n<h4 id=\"body-fields\">Body fields</h4>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Field</th>\n<th>Type</th>\n<th>Required</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>transferToStoreId</code></td>\n<td>string (UUID)</td>\n<td>Yes</td>\n<td>Where to move users who would otherwise be left without a store.</td>\n</tr>\n</tbody>\n</table>\n</div><h4 id=\"response\">Response</h4>\n<p>Responds <code>204 No Content</code>.</p>\n","auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{apiKey}}"}]},"isInherited":true,"source":{"_postman_id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","name":"ShuttleControl Open API","type":"collection"}},"urlObject":{"path":["v2","stores",":id","archive"],"host":["{{hostname}}"],"query":[],"variable":[{"id":"1d31fd3e-5b24-4949-9f28-dc5858be1eef","description":{"content":"<p>UUID of the store to archive.</p>\n","type":"text/plain"},"type":"any","value":"","key":"id"}]}},"response":[{"id":"0921d1a9-7d3f-4b8f-a9cc-726853330725","name":"Archive Store response","originalRequest":{"method":"DELETE","header":[],"body":{"mode":"raw","raw":"{\n    \"transferToStoreId\": \"495fd56c-6484-4198-bac2-d3ffd4455f4a\"\n}","options":{"raw":{"language":"json"}}},"url":"{{hostname}}/v2/stores/35772dfa-81cf-40ab-a6c1-30fb54797e60/archive"},"status":"No Content","code":204,"_postman_previewlanguage":"plain","header":[{"key":"Access-Control-Allow-Origin","value":"*"},{"key":"Content-Security-Policy","value":"default-src 'self';base-uri 'self';font-src 'self' https: data:;form-action 'self';frame-ancestors 'self';img-src 'self' data:;object-src 'none';script-src 'self';script-src-attr 'none';style-src 'self' https: 'unsafe-inline';upgrade-insecure-requests"},{"key":"Cross-Origin-Embedder-Policy","value":"require-corp"},{"key":"Cross-Origin-Opener-Policy","value":"same-origin"},{"key":"X-DNS-Prefetch-Control","value":"off"},{"key":"X-Frame-Options","value":"SAMEORIGIN"},{"key":"Strict-Transport-Security","value":"max-age=15552000; includeSubDomains"},{"key":"X-Download-Options","value":"noopen"},{"key":"X-Content-Type-Options","value":"nosniff"},{"key":"Origin-Agent-Cluster","value":"?1"},{"key":"X-Permitted-Cross-Domain-Policies","value":"none"},{"key":"Referrer-Policy","value":"no-referrer"},{"key":"X-XSS-Protection","value":"0"},{"key":"Date","value":"Mon, 08 Apr 2024 19:52:03 GMT"},{"key":"Connection","value":"keep-alive"},{"key":"Keep-Alive","value":"timeout=5"}],"cookie":[],"responseTime":null,"body":null}],"_postman_id":"6b8b9064-b151-4e48-9ed6-9733ecaca8c5"},{"name":"Restore Store","id":"296cb88f-d1b3-4376-a3ed-91547731733d","request":{"method":"POST","header":[],"url":"{{hostname}}/v2/stores/:id/restore","description":"<p>Restores an archived store, assigning the caller (and the account owner) to it. Plan store limits apply (<code>400 STORE_LIMIT_REACHED</code>).</p>\n<p><strong>Required role:</strong> <code>ADMIN</code> or higher. An account API key always satisfies this (it authenticates as the account owner).</p>\n<h4 id=\"response\">Response</h4>\n<p>Returns the restored store object.</p>\n","auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{apiKey}}"}]},"isInherited":true,"source":{"_postman_id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","name":"ShuttleControl Open API","type":"collection"}},"urlObject":{"path":["v2","stores",":id","restore"],"host":["{{hostname}}"],"query":[],"variable":[{"id":"95642fb5-e79d-42df-b8b7-14155fad0e35","description":{"content":"<p>UUID of the store to restore.</p>\n","type":"text/plain"},"type":"any","value":"","key":"id"}]}},"response":[{"id":"478f7ee0-dd19-45c3-a084-18fa32f46109","name":"Restore Store response","originalRequest":{"method":"POST","header":[],"url":"{{hostname}}/v2/stores//restore"},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Access-Control-Allow-Origin","value":"*"},{"key":"Content-Security-Policy","value":"default-src 'self';base-uri 'self';font-src 'self' https: data:;form-action 'self';frame-ancestors 'self';img-src 'self' data:;object-src 'none';script-src 'self';script-src-attr 'none';style-src 'self' https: 'unsafe-inline';upgrade-insecure-requests"},{"key":"Cross-Origin-Embedder-Policy","value":"require-corp"},{"key":"Cross-Origin-Opener-Policy","value":"same-origin"},{"key":"X-DNS-Prefetch-Control","value":"off"},{"key":"X-Frame-Options","value":"SAMEORIGIN"},{"key":"Strict-Transport-Security","value":"max-age=15552000; includeSubDomains"},{"key":"X-Download-Options","value":"noopen"},{"key":"X-Content-Type-Options","value":"nosniff"},{"key":"Origin-Agent-Cluster","value":"?1"},{"key":"X-Permitted-Cross-Domain-Policies","value":"none"},{"key":"Referrer-Policy","value":"no-referrer"},{"key":"X-XSS-Protection","value":"0"},{"key":"Content-Type","value":"application/json; charset=utf-8"},{"key":"Content-Length","value":"309"},{"key":"ETag","value":"W/\"135-+8i2gzujqAop+Ur/0zFjZzXDFis\""},{"key":"Vary","value":"Accept-Encoding"},{"key":"Date","value":"Tue, 09 Apr 2024 14:38:40 GMT"},{"key":"Connection","value":"keep-alive"},{"key":"Keep-Alive","value":"timeout=5"}],"cookie":[],"responseTime":null,"body":"{\n    \"id\": \"4554e868-2e21-4cdf-b9f4-378a3254565f\",\n    \"enabled\": false,\n    \"account\": {\n        \"id\": \"ee05a9bb-fd36-4805-bd05-cd8f48c0e03a\"\n    },\n    \"name\": \"Bravo Store\",\n    \"radiusBound\": null,\n    \"place\": {\n        \"id\": \"3b18c62e-ceb2-490b-9a1e-2c0d65157918\",\n        \"latitude\": 45.4651629,\n        \"longitude\": -73.5756481,\n        \"address\": \"3901 Bannantyne Ave, Verdun, QC H4G 1B9\"\n    }\n}"}],"_postman_id":"296cb88f-d1b3-4376-a3ed-91547731733d"}],"id":"fe6246e7-52e8-4983-81c8-91e85396db5a","description":"<p>Stores are your dispatch locations. Users, vehicles, customers, workflows, and trips all belong to a store.</p>\n","_postman_id":"fe6246e7-52e8-4983-81c8-91e85396db5a","auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{apiKey}}"}]},"isInherited":true,"source":{"_postman_id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","id":"37ebbaf7-dba8-4eac-b34c-002c858aa03f","name":"ShuttleControl Open API","type":"collection"}}}],"auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{apiKey}}"}]}},"variable":[{"key":"page","value":"0"},{"key":"size","value":"5"},{"key":"messageType","value":"\"SMS\""},{"key":"availabilityId","value":""},{"key":"customerId","value":""},{"key":"customerReviewId","value":""},{"key":"driverId","value":""},{"key":"kioskId","value":""},{"key":"kioskShortUrl","value":""},{"key":"messageTemplateId","value":""},{"key":"placeId","value":""},{"key":"stepId","value":""},{"key":"storeId","value":""},{"key":"tripId","value":""},{"key":"userId","value":""},{"key":"userScheduleId","value":""},{"key":"vehicleDriverLogId","value":""},{"key":"vehicleId","value":""},{"key":"workflowId","value":""},{"key":"zoneId","value":""}]}