{
  "openapi": "3.0.3",
  "servers": [
    {
      "url": "https://api.smartroutes.io/v2/"
    }
  ],
  "info": {
    "title": "SmartRoutes Open API",
    "description": "</br>\n<h1 style=\"color:rgb(51, 51, 51)\">Introduction</h1>\n<p>The SmartRoutes Open API allows you to use the power of the SmartRoutes Routing Engine directly from within your own software application.</p>\n<p>To use the API, you will need to generate an API Access Key for your SmartRoutes account. To generate, login to your SmartRoutes account and navigate to Settings > Integrations > SmartRoutes Open API and click 'Generate API Key'. For more details on SmartRoutes integrations, click <a href='https://smartroutes.io/blogs/guides/integrations/'>here</a>.</p>\n<p>This access key can be used to connect to the API.</p>\n<h1 id=\"webhooks\" style=\"color:rgb(51, 51, 51)\">Webhooks</h1>\n<p>Configure a webhook receiver URL in your depot settings and SmartRoutes will deliver event notifications as they happen. Seven event types are emitted:</p>\n<table><thead><tr><th>Event</th><th>Type ID</th><th>Fires when</th><th><code>data</code> payload</th></tr></thead><tbody>\n<tr><td><code>ORDERS_STATUS</code></td><td>2</td><td>An order's status changes (line-item or order-level transition)</td><td><code>{ \"order_id\": &lt;int&gt;, \"order_number\": &lt;string&gt;, \"status\": &lt;OrderStatus&gt; }</code></td></tr>\n<tr><td><code>PLANS_CREATED</code></td><td>4</td><td>A Plan row is persisted (after <code>POST /plans/optimise/orders</code> or <code>/orders-for-ids</code>). Fires <i>before</i> optimisation completes — see the optimise endpoint description.</td><td><code>{ \"id\": &lt;int&gt; }</code> — plan id</td></tr>\n<tr><td><code>PLANS_DISPATCHED</code></td><td>5</td><td>A Plan is dispatched (routes published to drivers).</td><td><code>{ \"id\": &lt;int&gt; }</code> — plan id</td></tr>\n<tr><td><code>ROUTES_EDITED</code></td><td>6</td><td>A dispatched route is edited (re-ordering stops, etc.)</td><td><code>{ \"id\": &lt;int&gt; }</code> — route id</td></tr>\n<tr><td><code>ROUTES_DELETED</code></td><td>7</td><td>One or more dispatched routes are deleted (typically as part of solution replacement)</td><td><code>{ \"id\": &lt;int&gt; }</code> — route id</td></tr>\n<tr><td><code>ROUTES_COMPLETED</code></td><td>8</td><td>A dispatched route is completed by the driver.</td><td><code>{ \"id\": &lt;int&gt; }</code> — route id</td></tr>\n<tr><td><code>PLANS_DELETED</code></td><td>9</td><td>A Plan row is destroyed</td><td><code>{ \"id\": &lt;int&gt; }</code> — plan id</td></tr>\n</tbody></table>\n<h3>Delivery envelope</h3>\n<p>Each event is delivered as an <code>HTTP POST</code> to the receiver URL configured in your depot settings. The request body is always a JSON object of shape:</p>\n<pre>{ \"type\": &lt;event type string from the table above&gt;, \"data\": &lt;payload object from the table above&gt; }</pre>\n<p>The <code>data</code> field is the payload object for a single event — NOT an array. Bulk operations (e.g. order-status changes from a route delete) fan out into one POST per event, each with its own <code>data</code> object.</p>\n<h3>Headers</h3>\n<p>Outgoing requests carry <code>Content-Type: application/json</code> and an HTTP Basic <code>Authorization</code> header derived from the username/password you supplied when configuring the webhook. No HMAC signature header is sent; treat the basic-auth credentials as the integrity check and rotate them if compromised.</p>\n<h3>Timeout and retries</h3>\n<p>Each delivery has a server-side request timeout of <b>3 seconds</b>. On failure (HTTP error, timeout, or connection error) the delivery is retried up to <b>3 times total</b>; after the third failure the task is marked permanently <code>ERROR</code> and not retried again. Your receiver should respond <code>2xx</code> quickly — slow receivers will be treated as failures.</p>\n<h3>Machine-readable schemas</h3>\n<p>The delivery envelope and per-event payloads are also defined under <code>#/components/schemas/</code>: <code>WebhookDelivery</code>, <code>WebhookOrdersStatusPayload</code>, <code>WebhookPlanIdPayload</code>, <code>WebhookRouteIdPayload</code>. Reference these from your own integration's tests / contract tools to catch shape drift early.</p>\n<h1 style=\"color:rgb(51, 51, 51)\">Headers</h1>\n<p>All requests expect the API Access key to be provided in a header <code>x-access-key:YOUR_ACCESS_KEY</code> </p>\n<h1 id=\"rate-limits\" style=\"color:rgb(51, 51, 51)\">Rate Limits</h1>\n<p>Every endpoint has a per-minute limit, and most also have a short burst limit. Requests are rejected as soon as either limit is hit.</p>\n<p>Most endpoints fall into one of these tiers:</p>\n<table><thead><tr><th>Tier</th><th>Rate limit</th><th>Description</th></tr></thead><tbody>\n<tr><td>Standard</td><td>60 / min (max 5 / sec)</td><td>Single-resource reads and writes (e.g. <code>GET /orders/{id}</code>, <code>PUT /orders/{id}</code>)</td></tr>\n<tr><td>Listing</td><td>30 / min (max 5 / sec)</td><td>Paginated lists (e.g. <code>/customers</code>, <code>/plans</code>, <code>/routes</code>)</td></tr>\n<tr><td>Reference</td><td>60 / min (max 1 / sec)</td><td>Reference data (e.g. depots, capacities, custom fields, vehicles, zone groups)</td></tr>\n<tr><td>Bulk</td><td>30 / min (max 1 per 2 sec)</td><td>Bulk creates and heavy deletes</td></tr>\n<tr><td>Upload</td><td>15 / min (max 1 / sec)</td><td>File uploads (e.g. <code>POST /orders/{id}/attachments</code>)</td></tr>\n</tbody></table>\n<p>The following endpoints have a stricter limit of <b>5 / min (max 2 per 15 sec)</b>:</p>\n<ul>\n<li>Plan optimisation: <code>POST /plans/optimise/orders</code>, <code>POST /plans/optimise/orders-for-ids</code></li>\n<li>Booking availability: <code>POST /booking/availability</code>, <code>POST /booking/available-dates</code>, <code>POST /booking/available-slots</code></li>\n<li>Route reversal: <code>POST /routes/{id}/reverse</code></li>\n</ul>\n<p>When a limit is hit, the API returns HTTP <b>403</b> with a <code>Retry-After</code> header and <code>details.retry_after_seconds</code> in the body — both give the seconds until the limit resets.</p>\n<p>We may temporarily reduce these limits to protect platform stability. We aim to keep such reductions brief and rare. However, your application should be built to handle rate limits gracefully.</p>\n<h1 id=\"idempotency\" style=\"color:rgb(51, 51, 51)\">Idempotency</h1>\n<p>State-changing <code>POST</code> endpoints accept an optional <code>idempotency-key</code> request header. The mechanism is Stripe-style: send the same key with a retry of the same request and the server returns the original response without re-executing the underlying operation.</p>\n<p><b>Header:</b> <code>idempotency-key: &lt;opaque string, 1–255 characters&gt;</code>. The key can be any client-chosen identifier — a UUID is recommended. Keys are scoped per <i>(api-key, endpoint)</i>, so the same key on two different endpoints is treated as two distinct operations.</p>\n<p><b>Retention:</b> 24 hours from the time the original request was received.</p>\n<p><b>Behaviour:</b></p>\n<ul>\n<li><b>Replay (same key, same body, completed)</b> — server returns the original status code and response body. The response header <code>idempotency-replay: true</code> indicates the response is a cached replay. The underlying operation is <i>not</i> re-executed. Replays do not consume rate-limit or data-row quota.</li>\n<li><b>Body mismatch (same key, different body)</b> — server returns <code>422 IDEMPOTENCY_KEY_REUSED_WITH_DIFFERENT_BODY</code>.</li>\n<li><b>In-flight (same key, original request still processing)</b> — server returns <code>409 IDEMPOTENCY_REQUEST_IN_PROGRESS</code> with a <code>Retry-After</code> header. Retry after the period given.</li>\n<li><b>5xx server error</b> — the cached reservation is released. A retry with the same key is treated as a fresh request and can re-execute. <i>4xx client errors</i> are cached: replays return the same 4xx response.</li>\n<li><b>Invalid key</b> (empty, or longer than 255 chars) — server returns <code>400 IDEMPOTENCY_INVALID_KEY</code>.</li>\n</ul>\n<p><b>Supporting endpoints (Phase 1):</b></p>\n<ul>\n<li><code>POST /orders</code></li>\n<li><code>POST /depots/{id}/orders</code></li>\n<li><code>POST /plans/optimise/orders</code></li>\n<li><code>POST /plans/optimise/orders-for-ids</code></li>\n<li><code>POST /customers/</code></li>\n<li><code>POST /vehicles/</code></li>\n<li><code>POST /notifications/schedule/orders</code></li>\n</ul>\n<p>Other <code>POST</code> endpoints ignore the header. Multipart uploads (<code>POST /orders/{id}/attachments</code>) are excluded from idempotency in this phase.</p>\n<h1 style=\"color:rgb(51, 51, 51)\">Paging</h1>\n<h2> Usage:</h2>\n<p>\nMake an initial request to the API endpoint with the desired query parameters.\nThe API response includes the requested data and a Link header for the next page.\nUse the URL provided in the Link header to make subsequent requests for the next page.\n\nExample: <code>\"&#60;https://api.smartroutes.io/v2/orders?page_info=PAGE_INFO_STRING&limit=100&gt;; rel=next\"</code>\n</p>\n<h2>Query Parameters</h2>\n<p>\n<b>limit:</b> Specifies the maximum number of items per page. Limited to a maximum of 100\n\n<u>Example:</u> limit=50\n\n<b>updated_at_min:</b> Filters results based on the minimum update timestamp in the format YYYY-MM-DD hh:mm:ss or YYYY-MM-DDTHH:mm:ss.SSSZ.\n\n<u>Example:</u> updated_at_min=2023-01-01 12:00:00 OR updated_at_min=2023-01-01T12:00:00.000Z\n\n<b>status:</b> Filters results based on the order status.\n\n<u>Example:</u> status=Pending\n</p><h2>Error Responses</h2>\n<p>\n    Errors are classified into specific types, each identified by a unique <b>name</b> and accompanied by an appropriate HTTP <b>statusCode</b>. \n    The error responses include a brief description of the error, and additional <b>details</b> that provide more context about the specific issue.\n</p>\n<h3>Error Types</h3>\n<b>RESOURCE_NOT_FOUND</b>\n- statusCode: 404\n- description: The requested resource could not be found.\n\n<b>INVALID_INPUT</b>\n\n- statusCode: 400\n- description: The submitted input data is invalid.\n- details: An object <code>{ validationErrors: An array of Zod errors specifying validation issues in the submitted data. }</code> containing additional details about the error. For processing validation errors, refer to <a href=\"https://zod.dev/ERROR_HANDLING\">Zod Documentation </a></b>.\n\n<b>GEOCODING_FAILED</b>\n\n- statusCode: 500\n- description: Geocoding operation failed.\n- details: An object containing additional details about the error.",
    "version": "2.0.0",
    "contact": {
      "name": "SmartRoutes Support",
      "email": "support@smartroutes.io",
      "url": "https://smartroutes.io/support"
    }
  },
  "tags": [
    { "name": "Booking" },
    { "name": "Capacities" },
    { "name": "Custom Fields" },
    { "name": "Customers" },
    { "name": "Depots" },
    { "name": "Driver Questionnaires" },
    { "name": "Notification Tasks" },
    { "name": "Notifications" },
    { "name": "Orders" },
    { "name": "Plans" },
    { "name": "Proof of Delivery" },
    { "name": "Routes" },
    { "name": "Third Parties" },
    { "name": "Vehicles" },
    { "name": "Zone Groups" }
  ],
  "paths": {
    "/booking/availability": {
      "post": {
        "summary": "Check Booking Availability",
        "operationId": "checkBookingAvailabilityForOrder",
        "description": "Endpoint to check whether an order can be booked on a specified day",
        "tags": [
          "Booking"
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "date": {
                    "type": "string",
                    "format": "date",
                    "description": "Requested date for order collection/delivery."
                  },
                  "order": {
                    "type": "object",
                    "properties": {
                      "type": {
                        "type": "string",
                        "enum": [
                          "delivery",
                          "pickup"
                        ]
                      },
                      "delivery_address": {
                        "type": "string"
                      },
                      "delivery_country_code": {
                        "type": "string",
                        "description": "Two letter country code, e.g. 'IE'"
                      },
                      "delivery_postcode": {
                        "type": "string"
                      },
                      "delivery_lat": {
                        "type": "number"
                      },
                      "delivery_lng": {
                        "type": "number"
                      },
                      "delivery_duration": {
                        "type": "number"
                      },
                      "pickup_address": {
                        "type": "string"
                      },
                      "pickup_country_code": {
                        "type": "string",
                        "description": "Two letter country code, e.g. 'IE'"
                      },
                      "pickup_postcode": {
                        "type": "string"
                      },
                      "pickup_duration": {
                        "type": "number"
                      },
                      "pickup_lat": {
                        "type": "number"
                      },
                      "pickup_lng": {
                        "type": "number"
                      },
                      "capacities": {
                        "type": "array",
                        "items": {
                          "type": "object",
                          "properties": {
                            "id": {
                              "type": "integer",
                              "description": "Id of capacity (e.g., 1, 2)."
                            },
                            "capacity": {
                              "type": "number",
                              "format": "float",
                              "description": "Capacity value for the specified type."
                            }
                          },
                          "required": [
                            "id",
                            "capacity"
                          ],
                          "description": "List of capacities with their types and values."
                        },
                        "description": "List of capacities for the order."
                      }
                    },
                    "required": [
                      "type"
                    ],
                    "description": "Location and other routing information for booking availability check."
                  },
                  "vehicles": {
                    "type": "array",
                    "format": "object",
                    "description": "Array of vehicles to attempt to route the order with. If no vehicles provided, active vehicles will be used."
                  }
                },
                "required": [
                  "date",
                  "order"
                ],
                "description": "Request body for checking availability for bookings."
              },
              "example": [
                {
                  "date": "2025-01-01",
                  "order": {
                    "type": "delivery",
                    "delivery_address": "5 Main Street, London, UK",
                    "delivery_postcode": "HS2 3DE4",
                    "delivery_country_code": "IE",
                    "delivery_duration": 30,
                    "capacities": [
                      {
                        "id": 1,
                        "capacity": 100
                      }
                    ]
                  },
                  "vehicles": [
                    {
                      "id": 123
                    },
                    {
                      "id": 456
                    },
                    {
                      "id": 789
                    }
                  ]
                }
              ]
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful response",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/BookingAvailabilityResponse" },
                "example": {
                  "booking": {
                    "available": true
                  }
                }
              }
            }
          },
          "400": { "$ref": "#/components/responses/InvalidInput" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "500": { "$ref": "#/components/responses/ServerError" }
        }
      }
    },
    "/custom-fields": {
      "get": {
        "summary": "Get All Custom Fields",
        "operationId": "listCustomFields",
        "description": "Endpoint to retrieve all custom fields.",
        "tags": [
          "Custom Fields"
        ],
        "responses": {
          "200": {
            "description": "Successful response",
            "content": {
              "application/json": {
                "example": {
                  "custom_fields": [
                    {
                      "id": 123,
                      "name": "Custom Field Name",
                      "created": "2022-04-29T16:12:08.000Z",
                      "updated": "2022-09-29T10:11:06.000Z"
                    }
                  ]
                }
              }
            }
          },
          "400": { "$ref": "#/components/responses/InvalidInput" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "500": { "$ref": "#/components/responses/ServerError" }
        }
      }
    },
    "/capacities": {
      "get": {
        "summary": "Get All Capacities",
        "operationId": "listCapacities",
        "description": "Endpoint to retrieve all capacities.",
        "tags": [
          "Capacities"
        ],
        "responses": {
          "200": {
            "description": "Successful response",
            "content": {
              "application/json": {
                "example": {
                  "capacities": [
                    {
                      "id": 123,
                      "type": "Palettes",
                      "default": "20",
                      "created": "2022-04-29T16:12:08.000Z",
                      "updated": "2022-09-29T10:11:06.000Z"
                    }
                  ]
                }
              }
            }
          },
          "400": { "$ref": "#/components/responses/InvalidInput" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "500": { "$ref": "#/components/responses/ServerError" }
        }
      }
    },
    "/customers": {
      "get": {
        "summary": "Get Customers Page",
        "operationId": "listCustomers",
        "description": "Endpoint to retrieve a page of customers.",
        "tags": [
          "Customers"
        ],
        "parameters": [
          {
            "in": "query",
            "name": "page_info",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Information about the page for pagination. Generated by the OpenAPI"
            },
            "description": "Information about the page for pagination. Generated by the OpenAPI"
          },
          {
            "in": "query",
            "name": "updated_at_min",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date-time",
              "description": "Minimum updated date and time for filtering."
            },
            "description": "Minimum updated date and time for filtering."
          },
          {
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 100,
              "description": "Maximum number of customers to retrieve per page."
            },
            "description": "Maximum number of customers to retrieve per page."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful response",
            "headers": {
              "link": {
                "description": "Link to the next page of customers. Use with the page_info parameter for pagination.",
                "schema": {
                  "type": "string"
                },
                "example": "<https://api.smartroutes.io/v2/customers?page_info=PAGE_INFO_STRING&limit=100>; rel=next"
              }
            },
            "content": {
              "application/json": {
                "example": {
                  "customers": [
                    {
                      "id": 123,
                      "name": "John Doe",
                      "account": "NO123",
                      "address": "123 Main St 12345",
                      "email": "john@doe.com",
                      "postcode": "12345",
                      "lat": 12.345,
                      "lng": -67.890,
                      "phone": "+1234567890",
                      "duration": 30,
                      "notes": "Leave at the doorstep",
                      "created": "2022-04-29T16:12:08.000Z",
                      "updated": "2022-09-29T10:11:06.000Z"
                    }
                  ]
                }
              }
            }
          },
          "400": { "$ref": "#/components/responses/InvalidInput" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "500": { "$ref": "#/components/responses/ServerError" }
        }
      },
      "post": {
        "summary": "Bulk Create Customers",
        "operationId": "createCustomers",
        "description": "Creates multiple customers in a single request (max 100). All referenced `tags`, `skills`, and `capacities` must already exist. `custom_fields` can be matched by `id` or `name`.",
        "tags": [
          "Customers"
        ],
        "parameters": [
          { "$ref": "#/components/parameters/IdempotencyKeyHeader" }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "array",
                "maxItems": 100,
                "items": {
                  "type": "object",
                  "required": [
                    "account"
                  ],
                  "properties": {
                    "name": {
                      "type": "string",
                      "maxLength": 100,
                      "description": "Full name of the customer"
                    },
                    "account": {
                      "type": "string",
                      "maxLength": 100,
                      "description": "Unique account reference (required)"
                    },
                    "address": {
                      "type": "string",
                      "maxLength": 255
                    },
                    "postcode": {
                      "type": "string",
                      "maxLength": 20
                    },
                    "phone": {
                      "type": "string",
                      "maxLength": 30
                    },
                    "email": {
                      "type": "string",
                      "format": "email"
                    },
                    "lat": {
                      "type": "number",
                      "description": "Latitude coordinate"
                    },
                    "lng": {
                      "type": "number",
                      "description": "Longitude coordinate"
                    },
                    "duration": {
                      "type": "number",
                      "minimum": 1,
                      "maximum": 9999,
                      "description": "Visit duration in minutes"
                    },
                    "notes": {
                      "type": "string",
                      "maxLength": 40000
                    },
                    "capacities": {
                      "type": "array",
                      "description": "List of predefined capacity types by ID",
                      "items": {
                        "type": "object",
                        "required": [
                          "id",
                          "capacity"
                        ],
                        "properties": {
                          "id": {
                            "type": "integer"
                          },
                          "capacity": {
                            "type": "number"
                          }
                        }
                      }
                    },
                    "skills": {
                      "type": "array",
                      "description": "List of skill names (must already exist)",
                      "items": {
                        "type": "string"
                      }
                    },
                    "tags": {
                      "type": "array",
                      "description": "List of tag names (must already exist)",
                      "items": {
                        "type": "string"
                      }
                    },
                    "time_windows": {
                      "type": "array",
                      "maxItems": 2,
                      "description": "Up to two delivery/pickup time windows per customer",
                      "items": {
                        "type": "object",
                        "required": [
                          "from"
                        ],
                        "properties": {
                          "from": {
                            "type": "string",
                            "pattern": "^([01]\\d|2[0-3]):([0-5]\\d)$",
                            "description": "Start time in 24-hour HH:mm format"
                          },
                          "to": {
                            "type": "string",
                            "pattern": "^([01]\\d|2[0-3]):([0-5]\\d)$",
                            "description": "End time in 24-hour HH:mm format"
                          }
                        }
                      }
                    },
                    "custom_fields": {
                      "type": "array",
                      "description": "Custom field values. Use `id` or `name` to identify each custom field.",
                      "items": {
                        "type": "object",
                        "required": [
                          "value"
                        ],
                        "properties": {
                          "id": {
                            "type": "integer"
                          },
                          "name": {
                            "type": "string"
                          },
                          "value": {
                            "type": "string"
                          }
                        }
                      }
                    }
                  },
                  "additionalProperties": false
                }
              },
              "example": [
                {
                  "name": "John Doe",
                  "account": "12345678",
                  "address": "Cork, Ireland",
                  "phone": "+353877777777",
                  "email": "john@doe.com",
                  "lat": 51.8985,
                  "lng": -8.4756,
                  "notes": "Customer notes",
                  "duration": 10,
                  "tags": [
                    "Spring Route",
                    "Priority"
                  ],
                  "skills": [
                    "Manual Handling"
                  ],
                  "capacities": [
                    {
                      "id": 145,
                      "capacity": 12
                    }
                  ],
                  "time_windows": [
                    {
                      "from": "10:00",
                      "to": "19:30"
                    }
                  ],
                  "custom_fields": [
                    {
                      "name": "Colour",
                      "value": "Red"
                    },
                    {
                      "id": 261,
                      "value": "10"
                    }
                  ]
                }
              ]
            }
          }
        },
        "responses": {
          "201": {
            "description": "Customers created successfully",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "customers": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "integer"
                          },
                          "account": {
                            "type": "string"
                          }
                        }
                      }
                    },
                    "errors": {
                      "type": "array",
                      "description": "List of customers that failed validation"
                    }
                  }
                },
                "example": {
                  "customers": [
                    {
                      "id": 381321,
                      "account": "12345678"
                    },
                    {
                      "id": 381322,
                      "account": "12345678"
                    }
                  ],
                  "errors": []
                }
              }
            },
            "headers": {
              "idempotency-replay": { "$ref": "#/components/headers/IdempotencyReplay" }
            }
          },
          "400": { "$ref": "#/components/responses/InvalidInput" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "409": { "$ref": "#/components/responses/IdempotencyRequestInProgress" },
          "422": { "$ref": "#/components/responses/IdempotencyKeyReusedWithDifferentBody" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "500": { "$ref": "#/components/responses/ServerError" }
        }
      }
    },
    "/customers/{id}": {
      "get": {
        "summary": "Get Customer by ID",
        "operationId": "getCustomerById",
        "description": "Retrieve a customer based on ID.",
        "tags": [
          "Customers"
        ],
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "ID of the customer to retrieve."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful response",
            "content": {
              "application/json": {
                "example": {
                  "id": 123,
                  "name": "John Doe",
                  "account": "NO123",
                  "address": "123 Main St 12345",
                  "postcode": "12345",
                  "lat": 12.345,
                  "lng": -67.890,
                  "phone": "+1234567890",
                  "email": "john@doe.com",
                  "duration": 30,
                  "notes": "Leave at the doorstep",
                  "created": "2022-04-29T16:12:08.000Z",
                  "updated": "2022-09-29T10:11:06.000Z",
                  "capacities": [
                    {
                      "id": 201,
                      "type": "WEIGHT",
                      "capacity": 500
                    },
                    {
                      "id": 202,
                      "type": "VOLUME",
                      "capacity": 1000
                    }
                  ],
                  "time_windows": [
                    {
                      "from": "08:00",
                      "to": "12:00"
                    },
                    {
                      "from": "14:00",
                      "to": "18:00"
                    }
                  ],
                  "skills": [
                    "Skill A",
                    "Skill B"
                  ],
                  "tags": [
                    "Tag A",
                    "Tag B"
                  ],
                  "custom_fields": [
                    {
                      "value": "My Value",
                      "custom_field_type": {
                        "name": "My Custom Field",
                        "type": "TEXT",
                        "id": 123
                      }
                    }
                  ]
                }
              }
            }
          },
          "400": { "$ref": "#/components/responses/InvalidInput" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "500": { "$ref": "#/components/responses/ServerError" }
        }
      },
      "put": {
        "summary": "Update Customer by ID",
        "operationId": "updateCustomerById",
        "description": "Update a customer based on ID.",
        "tags": [
          "Customers"
        ],
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "ID of the customer to update."
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "description": "Name of the customer."
                  },
                  "account": {
                    "type": "string",
                    "description": "Account number of the customer."
                  },
                  "address": {
                    "type": "string",
                    "description": "Address of the customer."
                  },
                  "postcode": {
                    "type": "string",
                    "description": "Postcode for the customer address."
                  },
                  "lat": {
                    "type": "number",
                    "description": "Latitude of the customer location."
                  },
                  "lng": {
                    "type": "number",
                    "description": "Longitude of the customer location."
                  },
                  "phone": {
                    "type": "string",
                    "description": "Contact number of the customer."
                  },
                  "email": {
                    "type": "string",
                    "format": "email",
                    "description": "Email of the customer."
                  },
                  "duration": {
                    "type": "number",
                    "description": "Duration for customer interaction in minutes."
                  },
                  "notes": {
                    "type": "string",
                    "description": "Notes for customer interaction."
                  },
                  "time_windows": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "from": {
                          "type": "string",
                          "format": "time",
                          "description": "Start time of the time window."
                        },
                        "to": {
                          "type": "string",
                          "format": "time",
                          "description": "End time of the time window."
                        }
                      },
                      "required": [
                        "from",
                        "to"
                      ],
                      "description": "Time windows for the customer."
                    },
                    "description": "List of time windows for the customer."
                  },
                  "skills": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "description": "List of required skills for the customer."
                    },
                    "description": "List of required skills for the customer."
                  },
                  "tags": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "description": "List of tags for the customer"
                    },
                    "description": "List of tags for the customer"
                  },
                  "capacities": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "integer",
                          "description": "Id of capacity (e.g., 1, 2)."
                        },
                        "capacity": {
                          "type": "number",
                          "format": "float",
                          "description": "Capacity value for the specified type."
                        }
                      },
                      "required": [
                        "id",
                        "capacity"
                      ],
                      "description": "List of capacities with their types and values."
                    },
                    "description": "List of capacities for the customer."
                  },
                  "custom_fields": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "integer",
                          "description": "Id of custom field (e.g., 1, 2)."
                        },
                        "value": {
                          "type": "string",
                          "description": "New custom field value"
                        }
                      }
                    },
                    "description": "List custom fields for the customer"
                  }
                },
                "description": "Details of the customer to be updated."
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful response",
            "content": {
              "application/json": {
                "example": {
                  "id": 123,
                  "name": "John Doe",
                  "account": "NO123",
                  "address": "123 Main St 12345",
                  "postcode": "12345",
                  "lat": 12.345,
                  "lng": -67.890,
                  "phone": "+1234567890",
                  "email": "john@doe.com",
                  "duration": 30,
                  "notes": "Leave at the doorstep",
                  "capacities": [
                    {
                      "id": 201,
                      "type": "WEIGHT",
                      "capacity": 500
                    },
                    {
                      "id": 202,
                      "type": "VOLUME",
                      "capacity": 1000
                    }
                  ],
                  "time_windows": [
                    {
                      "from": "08:00",
                      "to": "12:00"
                    },
                    {
                      "from": "14:00",
                      "to": "18:00"
                    }
                  ],
                  "skills": [
                    "Skill A",
                    "Skill B"
                  ],
                  "tags": [
                    "Tag A",
                    "Tag B"
                  ],
                  "custom_fields": [
                    {
                      "id": 123,
                      "value": "My Value",
                      "name": "My Custom Field"
                    }
                  ]
                }
              }
            }
          },
          "400": { "$ref": "#/components/responses/InvalidInput" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "500": { "$ref": "#/components/responses/ServerError" }
        }
      }
    },
    "/depots": {
      "get": {
        "summary": "Get All Depots",
        "operationId": "listDepots",
        "description": "Endpoint to retrieve a list of all depots.",
        "tags": [
          "Depots"
        ],
        "responses": {
          "200": {
            "description": "Successful response",
            "content": {
              "application/json": {
                "example": {
                  "depots": [
                    {
                      "id": 123,
                      "name": "Depot 1",
                      "created": "2021-04-12T15:30:46.000Z",
                      "updated": "2024-06-24T08:38:20.000Z"
                    }
                  ]
                }
              }
            }
          },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "500": { "$ref": "#/components/responses/ServerError" }
        }
      }
    },
    "/depots/{id}/orders": {
      "post": {
        "summary": "Bulk Add Orders to Depot",
        "operationId": "createOrdersForDepot",
        "description": "Endpoint to bulk add orders to a depot.",
        "tags": [
          "Depots"
        ],
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "number"
            },
            "description": "ID of the depot to which bulk orders are added."
          },
          { "$ref": "#/components/parameters/IdempotencyKeyHeader" }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "order_number": {
                      "type": "string"
                    },
                    "type": {
                      "type": "string",
                      "enum": [
                        "delivery",
                        "pickup",
                        "shipment"
                      ]
                    },
                    "customer": {
                      "type": "object",
                      "description": "Optional. When omitted, the order is created without a customer association (`customer_id` will be `null`). Requires the 'Orders Without Customers' depot setting to be enabled.",
                      "properties": {
                        "id": {
                          "type": "number",
                          "description": "ID of the customer."
                        },
                        "account": {
                          "type": "string",
                          "description": "Account number of the customer, if both ID and account are provided, customer's account number will be updated if different to the customer's current account number."
                        },
                        "name": {
                          "type": "string",
                          "description": "Name of the customer."
                        },
                        "email": {
                          "type": "string",
                          "format": "email",
                          "description": "Email of the customer."
                        },
                        "phone": {
                          "type": "string",
                          "description": "Contact number of the customer."
                        },
                        "country_code": {
                          "type": "string",
                          "description": "Country code of the customer."
                        },
                        "address": {
                          "type": "string",
                          "description": "Address of the customer."
                        },
                        "postcode": {
                          "type": "string",
                          "description": "Postcode of the customer."
                        },
                        "lat": {
                          "type": "number",
                          "description": "Latitude of the customer location."
                        },
                        "lng": {
                          "type": "number",
                          "description": "Longitude of the customer location."
                        }
                      },
                      "required": [],
                      "oneOf": [
                        {
                          "title": "id",
                          "required": [
                            "id"
                          ]
                        },
                        {
                          "title": "account",
                          "required": [
                            "account"
                          ]
                        }
                      ]
                    },
                    "delivery_contact_name": {
                      "type": "string"
                    },
                    "delivery_contact_number": {
                      "type": "string"
                    },
                    "delivery_contact_email": {
                      "type": "string",
                      "format": "email"
                    },
                    "delivery_address": {
                      "type": "string"
                    },
                    "delivery_postcode": {
                      "type": "string"
                    },
                    "delivery_lat": {
                      "type": "number"
                    },
                    "delivery_lng": {
                      "type": "number"
                    },
                    "delivery_notes": {
                      "type": "string"
                    },
                    "delivery_time_windows": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "from": {
                            "type": "string",
                            "format": "time",
                            "description": "Start time of the time window."
                          },
                          "to": {
                            "type": "string",
                            "format": "time",
                            "description": "End time of the time window."
                          }
                        },
                        "required": [
                          "from",
                          "to"
                        ],
                        "description": "Time windows for order delivery."
                      },
                      "description": "List of time windows for order delivery."
                    },
                    "delivery_date": {
                      "type": "string",
                      "format": "date"
                    },
                    "delivery_available_days": {
                      "type": "array",
                      "items": {
                        "type": "string",
                        "description": " Days of the week the order can be delivered.",
                        "enum": [
                          "MONDAY",
                          "TUESDAY",
                          "WEDNESDAY",
                          "THURSDAY",
                          "FRIDAY",
                          "SATURDAY",
                          "SUNDAY"
                        ]
                      },
                      "description": "List of available delivery days for the order."
                    },
                    "pickup_address": {
                      "type": "string"
                    },
                    "pickup_postcode": {
                      "type": "string"
                    },
                    "pickup_duration": {
                      "type": "number"
                    },
                    "pickup_lat": {
                      "type": "number"
                    },
                    "pickup_lng": {
                      "type": "number"
                    },
                    "pickup_notes": {
                      "type": "string"
                    },
                    "pickup_time_windows": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "from": {
                            "type": "string",
                            "format": "time",
                            "description": "Start time of the time window."
                          },
                          "to": {
                            "type": "string",
                            "format": "time",
                            "description": "End time of the time window."
                          }
                        },
                        "required": [
                          "from",
                          "to"
                        ],
                        "description": "Time windows for order pickup."
                      },
                      "description": "List of time windows for order pickup."
                    },
                    "pickup_contact_name": {
                      "type": "string"
                    },
                    "pickup_contact_number": {
                      "type": "string"
                    },
                    "pickup_contact_email": {
                      "type": "string",
                      "format": "email"
                    },
                    "pickup_available_days": {
                      "type": "array",
                      "items": {
                        "type": "string",
                        "description": " Days of the week the order can be picked up.",
                        "enum": [
                          "MONDAY",
                          "TUESDAY",
                          "WEDNESDAY",
                          "THURSDAY",
                          "FRIDAY",
                          "SATURDAY",
                          "SUNDAY"
                        ]
                      },
                      "description": "List of available pickup days for the order."
                    },
                    "parts": {
                      "type": "number"
                    },
                    "line_items": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "product_code": {
                            "type": "string",
                            "maxLength": 20
                          },
                          "product_name": {
                            "type": "string",
                            "maxLength": 75
                          },
                          "product_quantity": {
                            "type": "integer"
                          },
                          "capacities": {
                            "type": "array",
                            "items": {
                              "type": "object",
                              "properties": {
                                "id": {
                                  "type": "integer",
                                  "description": "Id of capacity (e.g., 1, 2)."
                                },
                                "capacity": {
                                  "type": "number",
                                  "format": "float",
                                  "description": "Capacity value for the specified type."
                                }
                              },
                              "required": [
                                "id",
                                "capacity"
                              ],
                              "description": "List of capacities with their types and values."
                            },
                            "description": "List of capacities for the line item."
                          }
                        },
                        "required": [
                          "product_code",
                          "product_name",
                          "product_quantity"
                        ]
                      }
                    },
                    "skills": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    "custom_fields": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "description": "Custom fields to include on the order. Either id or name is required.",
                        "properties": {
                          "id": {
                            "type": "number"
                          },
                          "name": {
                            "type": "number"
                          },
                          "value": {
                            "type": "string"
                          }
                        },
                        "required": [
                          "value"
                        ]
                      }
                    },
                    "capacities": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "integer"
                          },
                          "type": {
                            "type": "string",
                            "description": "Type of the capacity"
                          },
                          "capacity": {
                            "type": "number",
                            "format": "float"
                          }
                        },
                        "required": [
                          "capacity"
                        ]
                      },
                      "description": "List of capacities for the order. Either id or type is required."
                    }
                  },
                  "required": [
                    "order_number",
                    "type"
                  ]
                }
              },
              "example": [
                {
                  "order_number": "ORD123",
                  "delivery_contact_name": "John Doe",
                  "delivery_contact_number": "+123456789",
                  "delivery_contact_email": "john@doe.com",
                  "delivery_address": "123 Main St",
                  "delivery_postcode": "12345",
                  "delivery_lat": 40.7128,
                  "delivery_lng": -74.0060,
                  "delivery_notes": "Leave at the doorstep",
                  "delivery_time_windows": [
                    {
                      "from": "10:00",
                      "to": "11:00"
                    }
                  ],
                  "delivery_date": "2023-12-31",
                  "delivery_available_days": ["MONDAY", "WEDNESDAY", "SUNDAY"],
                  "pickup_address": "456 Oak St",
                  "pickup_postcode": "54321",
                  "pickup_duration": 30,
                  "pickup_lat": 40.730610,
                  "pickup_lng": -73.935242,
                  "pickup_notes": "Call upon arrival",
                  "pickup_time_windows": [
                    {
                      "from": "08:00",
                      "to": "09:00"
                    }
                  ],
                  "pickup_contact_name": "Jane Smith",
                  "pickup_contact_number": "+987654321",
                  "pickup_contact_email": "jane@example.com",
                  "pickup_available_days": ["MONDAY", "WEDNESDAY", "SUNDAY"],
                  "type": "delivery",
                  "parts": 2,
                  "customer": {
                    "id": 123,
                    "account": "NO123"
                  },
                  "line_items": [
                    {
                      "product_code": "P001",
                      "product_name": "Product 1",
                      "product_quantity": 2
                    },
                    {
                      "product_code": "P002",
                      "product_name": "Product 2",
                      "product_quantity": 1
                    }
                  ],
                  "skills": [
                    "skill1",
                    "skill2"
                  ],
                  "custom_fields": [
                    {
                      "id": 123,
                      "value": "Value 1"
                    },
                    {
                      "id": 234,
                      "value": "Value 2"
                    }
                  ],
                  "capacities": [
                    {
                      "id": 1,
                      "capacity": 100
                    },
                    {
                      "id": 2,
                      "capacity": 50
                    }
                  ]
                }
              ]
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful response",
            "content": {
              "application/json": {
                "example": {
                  "orders": [
                    {
                      "id": "123",
                      "order_number": "ORD123"
                    },
                    {
                      "id": "124",
                      "order_number": "ORD456"
                    }
                  ],
                  "errors": [
                    {
                      "name": "GEOCODING_FAILED",
                      "description": "We've failed to geocode the provided location.",
                      "details": {
                        "id": 124,
                        "order_number": "ORD456",
                        "is_created": true
                      }
                    }
                  ]
                }
              }
            },
            "headers": {
              "idempotency-replay": { "$ref": "#/components/headers/IdempotencyReplay" }
            }
          },
          "400": { "$ref": "#/components/responses/InvalidInput" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "409": { "$ref": "#/components/responses/IdempotencyRequestInProgress" },
          "422": { "$ref": "#/components/responses/IdempotencyKeyReusedWithDifferentBody" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "500": { "$ref": "#/components/responses/ServerError" }
        }
      }
    },
    "/notification-tasks": {
      "get": {
        "summary": "Get Notification Tasks Page",
        "operationId": "listNotificationTasks",
        "description": "Endpoint to retrieve a page of notification tasks.",
        "tags": [
          "Notification Tasks"
        ],
        "parameters": [
          {
            "in": "query",
            "name": "page_info",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Pagination cursor generated by the API. Pass this value to retrieve the next page of results."
            },
            "description": "Pagination cursor generated by the API. Pass this value to retrieve the next page of results."
          },
          {
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 100,
              "description": "Maximum number of notification tasks to retrieve per page. Max 100."
            },
            "description": "Maximum number of notification tasks to retrieve per page. Max 100."
          },
          {
            "in": "query",
            "name": "updated_at_min",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date-time",
              "description": "Filter tasks modified at or after this datetime. Format: YYYY-MM-DD hh:mm:ss or YYYY-MM-DDTHH:mm:ss.SSSZ."
            },
            "description": "Filter tasks modified at or after this datetime. Format: YYYY-MM-DD hh:mm:ss or YYYY-MM-DDTHH:mm:ss.SSSZ."
          },
          {
            "in": "query",
            "name": "status",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Filter notification tasks by status."
            },
            "description": "Filter notification tasks by status."
          },
          {
            "in": "query",
            "name": "type",
            "required": false,
            "schema": {
              "type": "string",
              "enum": ["SMS", "EMAIL"],
              "description": "Filter notification tasks by type. Accepted values: SMS, EMAIL (case-insensitive)."
            },
            "description": "Filter notification tasks by type. Accepted values: SMS, EMAIL (case-insensitive)."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful response",
            "headers": {
              "link": {
                "description": "Link to the next page of notification tasks. Use with the page_info parameter for pagination.",
                "schema": {
                  "type": "string"
                },
                "example": "<https://api.smartroutes.io/v2/notification-tasks?page_info=PAGE_INFO_STRING&limit=100>; rel=next"
              }
            },
            "content": {
              "application/json": {
                "example": {
                  "notification_tasks": [
                    {
                      "id": 4616,
                      "template": {
                        "id": 197
                      },
                      "visit": {
                        "id": 599910
                      },
                      "order": null,
                      "scheduled_date": "2026-02-24T14:48:00.000Z",
                      "sent_date": null,
                      "to": "test@smartroutes.io",
                      "subject": "Delivery is on the way",
                      "message": "Hello, your delivery is scheduled.",
                      "status": "Scheduled"
                    },
                    {
                      "id": 4615,
                      "template": {
                        "id": 198
                      },
                      "visit": {
                        "id": 599910
                      },
                      "order": null,
                      "scheduled_date": "2026-02-24T14:48:00.000Z",
                      "sent_date": null,
                      "to": "353892373003",
                      "subject": "",
                      "message": "Hello, your delivery is scheduled.",
                      "status": "Scheduled"
                    },
                    {
                      "id": 4614,
                      "template": {
                        "id": 198
                      },
                      "visit": null,
                      "order": {
                        "id": 458457,
                        "order_number": "183"
                      },
                      "scheduled_date": "2026-02-28T14:42:00.000Z",
                      "sent_date": null,
                      "to": "353892373003",
                      "subject": "",
                      "message": "Hello, your delivery is scheduled.",
                      "status": "Scheduled"
                    }
                  ]
                }
              }
            }
          },
          "400": { "$ref": "#/components/responses/InvalidInput" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "500": { "$ref": "#/components/responses/ServerError" }
        }
      }
    },
    "/notifications/templates": {
      "get": {
        "summary": "Get Notification Templates",
        "operationId": "listNotificationTemplates",
        "description": "Endpoint to retrieve a depot's notification templates.",
        "tags": [
          "Notifications"
        ],
        "responses": {
          "200": {
            "description": "Successful response",
            "content": {
              "application/json": {
                "example": [
                  {
                    "id": 123,
                    "type": "EMAIL",
                    "name": "My Email Template"
                  },
                  {
                    "id": 124,
                    "type": "SMS",
                    "name": "My SMS Template"
                  }
                ]
              }
            }
          },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "500": { "$ref": "#/components/responses/ServerError" }
        }
      }
    },
    "/notifications/schedule/orders": {
      "post": {
        "summary": "Schedule Order Notifications",
        "operationId": "scheduleOrderNotifications",
        "description": "Schedule notification dispatches for a set of orders.",
        "tags": [
          "Notifications"
        ],
        "parameters": [
          { "$ref": "#/components/parameters/IdempotencyKeyHeader" }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "orders": {
                    "type": "array",
                    "format": "integer",
                    "description": "Array of order IDs to create notifications for"
                  },
                  "templates": {
                    "type": "array",
                    "format": "integer",
                    "description": "Array of template IDs to generate notifications for"
                  },
                  "send_time_utc": {
                    "type": "string",
                    "description": "UTC Timestamp at which to send the notifications, defaults to current time if not provided."
                  }
                },
                "required": [
                  "orders",
                  "templates"
                ]
              },
              "example": {
                "orders": [
                  123,
                  124
                ],
                "templates": [
                  999
                ],
                "send_time_utc": "2024-12-25 12:00:00"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful response",
            "content": {
              "application/json": {
                "example": {
                  "notifications": [
                    {
                      "order_id": 123
                    }
                  ],
                  "errors": [
                    {
                      "name": "INVALID_INPUT",
                      "description": "Couldn't create notification. No phone number provided",
                      "statusCode": 400,
                      "isOperational": true,
                      "sendAlert": false,
                      "sourceError": null,
                      "details": {
                        "id": null,
                        "order_id": 124,
                        "visit_orders": [
                          {
                            "order_id": 124,
                            "order_number": "ORD124"
                          }
                        ],
                        "phone": null,
                        "email": "johndoe@test.com",
                        "country": null,
                        "name": "John Doe",
                        "reference_id": "ORD124",
                        "visit_custom_fields": [],
                        "address": "Cork City, Cork"
                      },
                      "timestamp": "2024-12-30T00:00:00.000Z"
                    }
                  ]
                }
              }
            },
            "headers": {
              "idempotency-replay": { "$ref": "#/components/headers/IdempotencyReplay" }
            }
          },
          "400": { "$ref": "#/components/responses/InvalidInput" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "409": { "$ref": "#/components/responses/IdempotencyRequestInProgress" },
          "422": { "$ref": "#/components/responses/IdempotencyKeyReusedWithDifferentBody" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "500": { "$ref": "#/components/responses/ServerError" }
        }
      }
    },
    "/orders": {
      "description": "",
      "post": {
        "summary": "Bulk Add Orders",
        "operationId": "createOrders",
        "description": "Endpoint to bulk add orders.",
        "tags": [
          "Orders"
        ],
        "parameters": [
          { "$ref": "#/components/parameters/IdempotencyKeyHeader" }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "order_number": {
                      "type": "string",
                      "description": "Order number."
                    },
                    "customer": {
                      "type": "object",
                      "description": "Optional. When omitted, the order is created without a customer association (`customer_id` will be `null`). Requires the 'Orders Without Customers' depot setting to be enabled.",
                      "properties": {
                        "id": {
                          "type": "number",
                          "description": "ID of the customer."
                        },
                        "account": {
                          "type": "string",
                          "description": "Account number of the customer, if both ID and account are provided, customer's account number will be updated if different to the customer's current account number."
                        },
                        "name": {
                          "type": "string",
                          "description": "Name of the customer."
                        },
                        "email": {
                          "type": "string",
                          "format": "email",
                          "description": "Email of the customer."
                        },
                        "phone": {
                          "type": "string",
                          "description": "Contact number of the customer."
                        },
                        "country_code": {
                          "type": "string",
                          "description": "Country code of the customer."
                        },
                        "address": {
                          "type": "string",
                          "description": "Address of the customer."
                        },
                        "postcode": {
                          "type": "string",
                          "description": "Postcode of the customer."
                        },
                        "lat": {
                          "type": "number",
                          "description": "Latitude of the customer location."
                        },
                        "lng": {
                          "type": "number",
                          "description": "Longitude of the customer location."
                        }
                      },
                      "required": [],
                      "oneOf": [
                        {
                          "title": "id",
                          "required": [
                            "id"
                          ]
                        },
                        {
                          "title": "account",
                          "required": [
                            "account"
                          ]
                        }
                      ]
                    },
                    "type": {
                      "type": "string",
                      "enum": [
                        "delivery",
                        "pickup",
                        "shipment"
                      ],
                      "description": "Type of the order (delivery, pickup, or shipment)."
                    },
                    "priority": {
                      "type": "string",
                      "description": "Priority of the order (Accepts 'P1', 'P2', 'P3')."
                    },
                    "delivery_contact_name": {
                      "type": "string",
                      "description": "Name of the contact person."
                    },
                    "delivery_contact_number": {
                      "type": "string",
                      "description": "Contact number of the person."
                    },
                    "delivery_contact_email": {
                      "type": "string",
                      "description": "Email of the contact person.",
                      "format": "email"
                    },
                    "delivery_address": {
                      "type": "string",
                      "description": "Delivery address."
                    },
                    "delivery_country_code": {
                      "type": "string",
                      "description": "Two letter country code, e.g. 'IE'"
                    },
                    "delivery_postcode": {
                      "type": "string",
                      "description": "Postcode for delivery address."
                    },
                    "delivery_lat": {
                      "type": "number",
                      "description": "Latitude of the delivery location."
                    },
                    "delivery_lng": {
                      "type": "number",
                      "description": "Longitude of the delivery location."
                    },
                    "delivery_duration": {
                      "type": "number",
                      "description": "Duration for order delivery in minutes."
                    },
                    "delivery_notes": {
                      "type": "string",
                      "description": "Notes for delivery instructions."
                    },
                    "delivery_time_windows": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "from": {
                            "type": "string",
                            "format": "time",
                            "description": "Start time of the time window."
                          },
                          "to": {
                            "type": "string",
                            "format": "time",
                            "description": "End time of the time window."
                          }
                        },
                        "required": [
                          "from",
                          "to"
                        ],
                        "description": "Time windows for order delivery."
                      },
                      "description": "List of time windows for order delivery."
                    },
                    "delivery_date": {
                      "type": "string",
                      "format": "date",
                      "description": "Date for order delivery."
                    },
                    "delivery_available_days": {
                      "type": "array",
                      "items": {
                        "type": "string",
                        "description": " Days of the week the order can be delivered.",
                        "enum": [
                          "MONDAY",
                          "TUESDAY",
                          "WEDNESDAY",
                          "THURSDAY",
                          "FRIDAY",
                          "SATURDAY",
                          "SUNDAY"
                        ]
                      },
                      "description": "List of available delivery days for the order."
                    },
                    "pickup_address": {
                      "type": "string",
                      "description": "Address for order pickup."
                    },
                    "pickup_country_code": {
                      "type": "string",
                      "description": "Two letter country code, e.g. 'IE'"
                    },
                    "pickup_postcode": {
                      "type": "string",
                      "description": "Postcode for pickup address."
                    },
                    "pickup_duration": {
                      "type": "number",
                      "description": "Duration for order pickup in minutes."
                    },
                    "pickup_lat": {
                      "type": "number",
                      "description": "Latitude of the pickup location."
                    },
                    "pickup_lng": {
                      "type": "number",
                      "description": "Longitude of the pickup location."
                    },
                    "pickup_notes": {
                      "type": "string",
                      "description": "Notes for pickup instructions."
                    },
                    "pickup_time_windows": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "from": {
                            "type": "string",
                            "format": "time",
                            "description": "Start time of the time window."
                          },
                          "to": {
                            "type": "string",
                            "format": "time",
                            "description": "End time of the time window."
                          }
                        },
                        "required": [
                          "from",
                          "to"
                        ],
                        "description": "Time windows for order pickup."
                      },
                      "description": "List of time windows for order pickup."
                    },
                    "pickup_contact_name": {
                      "type": "string",
                      "description": "Name of the contact person for pickup."
                    },
                    "pickup_contact_number": {
                      "type": "string",
                      "description": "Contact number of the person for pickup."
                    },
                    "pickup_contact_email": {
                      "type": "string",
                      "format": "email",
                      "description": "Email of the contact person for pickup."
                    },
                    "pickup_available_days": {
                      "type": "array",
                      "items": {
                        "type": "string",
                        "description": "Days of the week the order can be picked up.",
                        "enum": [
                          "MONDAY",
                          "TUESDAY",
                          "WEDNESDAY",
                          "THURSDAY",
                          "FRIDAY",
                          "SATURDAY",
                          "SUNDAY"
                        ]
                      },
                      "description": "List of available pickup days for the order."
                    },
                    "parts": {
                      "type": "number",
                      "description": "Number of parts in the order."
                    },
                    "vehicle_assignment": {
                      "type": "object",
                      "properties": {
                        "vehicle_id": {
                          "type": "integer",
                          "description": "ID of the assigned vehicle"
                        }
                      }
                    },
                    "emails": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "email": {
                            "type": "string",
                            "format": "email",
                            "description": "Additional emails"
                          }
                        }
                      }
                    },
                    "third_party": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "integer",
                          "description": "ID of the third party for the order"
                        }
                      },
                      "description": "Third party object"
                    },
                    "line_items": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "product_code": {
                            "type": "string",
                            "description": "Code of the product.",
                            "maxLength": 20
                          },
                          "product_name": {
                            "type": "string",
                            "description": "Name of the product.",
                            "maxLength": 75
                          },
                          "product_quantity": {
                            "type": "integer",
                            "description": "Quantity of the product."
                          },
                          "capacities": {
                            "type": "array",
                            "items": {
                              "type": "object",
                              "properties": {
                                "id": {
                                  "type": "integer",
                                  "description": "Id of capacity (e.g., 1, 2)."
                                },
                                "capacity": {
                                  "type": "number",
                                  "format": "float",
                                  "description": "Capacity value for the specified type."
                                }
                              },
                              "required": [
                                "id",
                                "capacity"
                              ],
                              "description": "List of capacities with their types and values."
                            },
                            "description": "List of capacities for the line item."
                          },
                          "date": {
                            "type": "string",
                            "format": "date",
                            "description": "Date for the line item."
                          },
                          "custom_fields": {
                            "type": "array",
                            "items": {
                              "type": "object",
                              "properties": {
                                "id": {
                                  "type": "integer",
                                  "description": "Id of custom field (e.g., 1, 2)."
                                },
                                "value": {
                                  "type": "string",
                                  "description": "New custom field value"
                                }
                              }
                            },
                            "description": "List custom fields for the line item"
                          }
                        },
                        "required": [
                          "product_code",
                          "product_name",
                          "product_quantity"
                        ],
                        "description": "Details of each line item in the order."
                      },
                      "description": "List of line items in the order."
                    },
                    "skills": {
                      "type": "array",
                      "items": {
                        "type": "string",
                        "description": "List of required skills for the order."
                      },
                      "description": "List of required skills for the order."
                    },
                    "custom_fields": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "number",
                            "description": "ID of the custom field."
                          },
                          "name": {
                            "type": "string",
                            "description": "Name of the custom field."
                          },
                          "value": {
                            "type": "string",
                            "description": "Value of the custom field."
                          }
                        },
                        "required": [
                          "value"
                        ],
                        "description": "Custom fields to include on the order. Either id or name is required."
                      },
                      "description": "List of custom fields for the order."
                    },
                    "capacities": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "integer",
                            "description": "ID of a capacity."
                          },
                          "type": {
                            "type": "string",
                            "description": "Type of the capacity"
                          },
                          "capacity": {
                            "type": "number",
                            "format": "float",
                            "description": "Capacity value for the specified type."
                          }
                        },
                        "required": [
                          "capacity"
                        ],
                        "description": "List of capacities with their ids and values."
                      },
                      "description": "List of capacities for the order. Either id or type is required."
                    },
                    "tags": {
                      "type": "array",
                      "description": "List of tag names (must already exist)",
                      "items": {
                        "type": "string"
                      }
                    }
                  },
                  "required": [
                    "order_number",
                    "type"
                  ],
                  "description": "Details of an order including delivery, pickup, or shipment information."
                }
              },
              "example": [
                {
                  "order_number": "ORD123",
                  "delivery_contact_name": "John Doe",
                  "delivery_contact_number": "+123456789",
                  "delivery_contact_email": "john@doe.com",
                  "delivery_address": "123 Main St",
                  "delivery_country_code": "IE",
                  "delivery_postcode": "12345",
                  "delivery_lat": 40.7128,
                  "delivery_lng": -74.0060,
                  "delivery_notes": "Leave at the doorstep",
                  "delivery_time_windows": [
                    {
                      "from": "10:00",
                      "to": "11:00"
                    }
                  ],
                  "delivery_date": "2023-12-31",
                  "delivery_available_days": ["MONDAY", "WEDNESDAY", "SUNDAY"],
                  "pickup_address": "456 Oak St",
                  "pickup_country_code": "IE",
                  "pickup_postcode": "54321",
                  "pickup_duration": 30,
                  "pickup_lat": 40.730610,
                  "pickup_lng": -73.935242,
                  "pickup_notes": "Call upon arrival",
                  "pickup_time_windows": [
                    {
                      "from": "08:00",
                      "to": "09:00"
                    }
                  ],
                  "pickup_contact_name": "Jane Smith",
                  "pickup_contact_number": "+987654321",
                  "pickup_contact_email": "jane@example.com",
                  "pickup_available_days": ["MONDAY", "WEDNESDAY", "SUNDAY"],
                  "priority": "P1",
                  "type": "delivery",
                  "parts": 2,
                  "vehicle_assignment": {
                    "vehicle_id": 1958
                  },
                  "emails": [
                    {
                      "email": "example@email.com"
                    },
                    {
                      "email": "example2@email.com"
                    }
                  ],
                  "customer": {
                    "id": 123,
                    "account": "NO123"
                  },
                  "line_items": [
                    {
                      "product_code": "P001",
                      "product_name": "Product 1",
                      "product_quantity": 2,
                      "date": "2024-07-12",
                      "custom_fields": [
                        {
                          "id": 123,
                          "value": "Value 1"
                        }
                      ]
                    },
                    {
                      "product_code": "P002",
                      "product_name": "Product 2",
                      "product_quantity": 1,
                      "date": "2024-07-12",
                      "custom_fields": [
                        {
                          "id": 321,
                          "value": "Value 1"
                        }
                      ]
                    }
                  ],
                  "skills": [
                    "skill1",
                    "skill2"
                  ],
                  "custom_fields": [
                    {
                      "id": 123,
                      "value": "Value 1"
                    },
                    {
                      "id": 234,
                      "value": "Value 2"
                    }
                  ],
                  "capacities": [
                    {
                      "id": 1,
                      "capacity": 100
                    },
                    {
                      "id": 2,
                      "capacity": 50
                    }
                  ],
                  "tags": [
                    "tag1",
                    "tag2"
                  ]
                }
              ]
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful response",
            "content": {
              "application/json": {
                "example": {
                  "orders": [
                    {
                      "id": "123",
                      "order_number": "ORD123"
                    },
                    {
                      "id": "124",
                      "order_number": "ORD456"
                    }
                  ],
                  "errors": [
                    {
                      "name": "GEOCODING_FAILED",
                      "description": "We've failed to geocode the provided location.",
                      "details": {
                        "id": 124,
                        "order_number": "ORD456",
                        "is_created": true
                      }
                    }
                  ]
                }
              }
            },
            "headers": {
              "idempotency-replay": { "$ref": "#/components/headers/IdempotencyReplay" }
            }
          },
          "400": { "$ref": "#/components/responses/InvalidInput" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "409": { "$ref": "#/components/responses/IdempotencyRequestInProgress" },
          "422": { "$ref": "#/components/responses/IdempotencyKeyReusedWithDifferentBody" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "500": { "$ref": "#/components/responses/ServerError" }
        }
      },
      "get": {
        "summary": "Get Orders Page",
        "operationId": "listOrders",
        "description": "Endpoint to retrieve a page of orders.",
        "tags": [
          "Orders"
        ],
        "parameters": [
          {
            "in": "query",
            "name": "page_info",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Information about the page for pagination. Generated by the OpenAPI"
            },
            "description": "Information about the page for pagination. Generated by the OpenAPI"
          },
          {
            "in": "query",
            "name": "status",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Status of the orders to filter."
            },
            "description": "Status of the orders to filter."
          },
          {
            "in": "query",
            "name": "customer_id",
            "required": false,
            "schema": {
              "type": "integer",
              "description": "SmartRoutes customer id."
            },
            "description": "Filter orders by the customer they belong to."
          },
          {
            "in": "query",
            "name": "order_number",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Order number of the order to filter"
            },
            "description": "Filter orders by a specific order number"
          },
          {
            "in": "query",
            "name": "updated_at_min",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date-time",
              "description": "Minimum updated date and time for filtering."
            },
            "description": "Minimum updated date and time for filtering."
          },
          {
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 100,
              "description": "Maximum number of orders to retrieve per page."
            },
            "description": "Maximum number of orders to retrieve per page."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful response",
            "headers": {
              "link": {
                "description": "Link to the next page of orders. Use with the page_info parameter for pagination.",
                "schema": {
                  "type": "string"
                },
                "example": "<https://api.smartroutes.io/v2/orders?page_info=PAGE_INFO_STRING&limit=100>; rel=next"
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/OrdersListResponse" },
                "example": {
                  "orders": [
                    {
                      "id": 1,
                      "order_number": "ABC123",
                      "status": "DELIVERED",
                      "type": "delivery",
                      "stops": [
                        {
                          "id": 101,
                          "route_id": 123,
                          "address": "Dublin Road, Portlaoise, Ireland",
                          "postcode": "R32 XD32",
                          "phone": "+353 215 12320",
                          "lat": 53.52145,
                          "lng": -7.58954,
                          "planned_distance": 1278.2,
                          "arrival_date": "2024-03-04",
                          "departure_date": "2024-03-04",
                          "estimated_arrival_time": "14:17",
                          "estimated_departure_time": "14:27",
                          "actual_completed_ts": "2024-03-04T14:04:51.000Z",
                          "actual_completed_lat": 12.345,
                          "actual_completed_lng": -45.678,
                          "delivery_notes": null,
                          "driver_notes": null,
                          "actual_arrival_time": null,
                          "actual_duration": null,
                          "signature": "https://api.smartroutes.io/v2/proof-of-delivery/signatures/116839",
                          "signature_lat": 12.345,
                          "signature_lng": -45.678,
                          "signed_by": "James Murphy",
                          "photos": [
                            "https://api.smartroutes.io/v2/proof-of-delivery/photos/491548"
                          ],
                          "tracking_link": null,
                          "vehicle_assignment": null,
                          "directions": [
                            {
                              "instruction": "Turn left onto Sample Road"
                            },
                            {
                              "instruction": "At the roundabout, take the 3rd exit onto Baker Street"
                            }
                          ],
                          "driver_questionnaire_submissions": [
                            {
                              "id": 1269,
                              "driver_questionnaire": {
                                "type": "VISIT",
                                "title": "Stop Questionaire"
                              }
                            }
                          ],
                          "failed_reason": {
                            "reason": "Wrong Parcel"
                          },
                          "route": {
                            "id": 201,
                            "date": "2024-03-04",
                            "started_ts": "2024-03-04T15:09:34.000Z"
                          }
                        },
                        {
                          "id": 102,
                          "route_id": 456,
                          "address": "Dublin Road, Portlaoise, Ireland",
                          "postcode": "R32 XD32",
                          "phone": "+353 215 12320",
                          "lat": 53.52145,
                          "lng": -7.58954,
                          "planned_distance": 1234.5,
                          "arrival_date": "2024-03-05",
                          "departure_date": "2024-03-05",
                          "estimated_arrival_time": "13:27",
                          "estimated_departure_time": "13:37",
                          "actual_completed_ts": "2024-03-05T13:28:51.000Z",
                          "actual_completed_lat": 12.345,
                          "actual_completed_lng": -45.678,
                          "delivery_notes": null,
                          "driver_notes": null,
                          "actual_arrival_time": null,
                          "actual_duration": null,
                          "signature": "https://api.smartroutes.io/v2/proof-of-delivery/signatures/116839",
                          "signature_lat": 12.345,
                          "signature_lng": -45.678,
                          "signed_by": "James Murphy",
                          "photos": null,
                          "tracking_link": null,
                          "vehicle_assignment": null,
                          "directions": [
                            {
                              "instruction": "Turn right onto Example Road"
                            },
                            {
                              "instruction": "At the roundabout, take the 2nd exit onto Cook Street"
                            }
                          ],
                          "driver_questionnaire_submissions": [
                            {
                              "id": 1270,
                              "driver_questionnaire": {
                                "type": "VISIT",
                                "title": "Stop Questionaire"
                              }
                            }
                          ],
                          "failed_reason": {
                            "reason": "Wrong Parcel"
                          },
                          "route": {
                            "id": 202,
                            "date": "2024-03-05",
                            "started_ts": "2024-03-05T15:09:34.000Z"
                          }
                        }
                      ],
                      "customer": {
                        "id": 123,
                        "account": "NO123"
                      },
                      "created": "2022-04-29T16:12:08.000Z",
                      "updated": "2022-09-29T10:11:06.000Z"
                    },
                    {
                      "id": 2,
                      "order_number": "XYZ456",
                      "status": "OPEN",
                      "type": "delivery",
                      "stops": [
                        {
                          "id": 103,
                          "route": {
                            "id": 203,
                            "date": "2023-01-04",
                            "started_ts": "2023-01-04T15:09:34.000Z"
                          }
                        }
                      ],
                      "customer": {
                        "id": 124,
                        "account": "NO124"
                      },
                      "created": "2022-04-29T16:12:08.000Z",
                      "updated": "2022-09-29T10:11:06.000Z"
                    }
                  ]
                }
              }
            }
          },
          "400": { "$ref": "#/components/responses/InvalidInput" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "500": { "$ref": "#/components/responses/ServerError" }
        }
      }
    },
    "/orders/{id}": {
      "get": {
        "summary": "Get Order by ID",
        "operationId": "getOrderById",
        "description": "Retrieve an order based on ID.",
        "tags": [
          "Orders"
        ],
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "ID of the order to retrieve."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful response",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/OrderResponse" },
                "example": {
                  "order_number": "ABC123",
                  "priority": "P1",
                  "customer_id": 101,
                  "delivery_contact_name": "John Doe",
                  "delivery_contact_number": "+1234567890",
                  "delivery_contact_email": "john.doe@example.com",
                  "delivery_address": "123 Main St 12345",
                  "delivery_lat": 12.345,
                  "delivery_lng": -67.890,
                  "delivery_notes": "Leave at the doorstep",
                  "delivery_date": "2023-01-01",
                  "delivery_duration": 30,
                  "delivery_available_days": ["MONDAY", "SUNDAY"],
                  "pickup_address": "456 Oak Ave 67890",
                  "pickup_lat": 12.678,
                  "pickup_lng": -67.432,
                  "pickup_notes": "Collect from reception",
                  "pickup_contact_name": "Jane Smith",
                  "pickup_contact_number": "+0987654321",
                  "pickup_contact_email": "jane.smith@example.com",
                  "pickup_available_days": ["TUESDAY", "WEDNESDAY"],
                  "pickup_duration": 15,
                  "status": "OPEN",
                  "type": "delivery",
                  "parts": 2,
                  "created": "2022-04-29T16:12:08.000Z",
                  "updated": "2022-09-29T10:11:06.000Z",
                  "vehicle_assignment": {
                    "vehicle_id": 67
                  },
                  "emails": [
                    {
                      "email": "example@email.com"
                    },
                    {
                      "email": "example2@email.com"
                    }
                  ],
                  "customer": {
                    "id": 123,
                    "account": "NO123"
                  },
                  "third_party": {
                    "id": 135
                  },
                  "tags": [
                    "Tag1",
                    "Tag2"
                   ],
                  "line_items": [
                    {
                      "product_name": "Widget A",
                      "product_code": "WID-A",
                      "product_quantity": 3,
                      "status": "DELIVERED",
                      "date": "2024-01-01",
                      "custom_fields": [
                        {
                          "id": 123,
                          "value": "Value 1",
                          "name": "Custom Field 1"
                        }
                      ]
                    },
                    {
                      "product_name": "Gadget B",
                      "product_code": "GAD-B",
                      "product_quantity": 2,
                      "capacities": [
                        {
                          "id": 201,
                          "type": "WEIGHT",
                          "capacity": 100
                        }
                      ],
                      "status": "DELIVERED",
                      "date": "2024-01-01",
                      "custom_fields": [
                        {
                          "id": 321,
                          "value": "Value 1",
                          "name": "Custom Field 2"
                        }
                      ]
                    }
                  ],
                  "capacities": [
                    {
                      "id": 201,
                      "type": "WEIGHT",
                      "capacity": 500
                    },
                    {
                      "id": 202,
                      "type": "VOLUME",
                      "capacity": 1000
                    }
                  ],
                  "custom_fields": [
                    {
                      "id": 201,
                      "name": "Cash due on Collection",
                      "value": "Yes"
                    }
                  ],
                  "time_windows": [
                    {
                      "from": "08:00",
                      "to": "12:00",
                      "type": "pickup"
                    },
                    {
                      "from": "14:00",
                      "to": "18:00",
                      "type": "delivery"
                    }
                  ],
                  "skills": [
                    "Skill A",
                    "Skill B"
                  ],
                  "stops": [
                    {
                      "id": 123,
                      "route_id": 456,
                      "address": "123 Main St",
                      "postcode": "D01 AB12",
                      "phone": "555-1234",
                      "lat": 12.345,
                      "lng": -45.678,
                      "planned_distance": 1234.5,
                      "arrival_date": "2023-12-31",
                      "departure_date": "2023-12-31",
                      "delivery_notes": "Leave at the doorstep",
                      "driver_notes": "Customer not available initially",
                      "estimated_arrival_time": "09:00",
                      "estimated_departure_time": "10:00",
                      "actual_completed_ts": "2023-12-31T10:15:00",
                      "actual_arrival_time": "2023-12-31T09:15:00",
                      "actual_completed_lat": 12.345,
                      "actual_completed_lng": -45.678,
                      "actual_duration": 60,
                      "signature": "https://api.smartroutes.io/v2/proof-of-delivery/signatures/111486",
                      "signature_lat": 12.345,
                      "signature_lng": -45.678,
                      "signed_by": "John",
                      "tracking_link": "https://tracksr.io/xyzabc",
                      "photos": [
                        "https://api.smartroutes.io/v2/proof-of-delivery/photos/491548"
                      ],
                      "vehicle_assignment": null,
                      "directions": [
                        {
                          "instruction": "Turn right onto Example Road"
                        },
                        {
                          "instruction": "At the roundabout, take the 2nd exit onto Cook Street"
                        }
                      ],
                      "driver_questionnaire_submissions": [
                        {
                          "id": 1270,
                          "driver_questionnaire": {
                            "type": "VISIT",
                            "title": "Stop Questionaire"
                          }
                        }
                      ],
                      "failed_reason": {
                        "reason": "Wrong Parcel"
                      },
                      "tags": [
                        "Fragile",
                        "Priority"
                      ],
                      "available_days": [],
                      "emails": [
                        "test@example.com"
                      ],
                      "route": {
                        "id": 456,
                        "date": "2023-12-31"
                      }
                    }
                  ],
                  "attachments": [
                    {
                      "id": 35,
                      "name": "OrderFile1.pdf"
                    },
                    {
                      "id": 36,
                      "name": "OrderFile2.png"
                    }
                  ]
                }
              }
            }
          },
          "400": { "$ref": "#/components/responses/InvalidInput" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "500": { "$ref": "#/components/responses/ServerError" }
        }
      },
      "put": {
        "summary": "Update Order by ID",
        "operationId": "updateOrderById",
        "description": "Update an order based on ID.",
        "tags": [
          "Orders"
        ],
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "ID of the order to update."
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "order_number": "ABC123",
                "priority": "P1",
                "customer_id": 101,
                "delivery_contact_name": "John Doe",
                "delivery_contact_number": "+1234567890",
                "delivery_contact_email": "john.doe@example.com",
                "delivery_address": "123 Main St 12345",
                "delivery_lat": 12.345,
                "delivery_lng": -67.890,
                "delivery_notes": "Leave at the doorstep",
                "delivery_time_windows": [
                  {
                    "from": "10:00",
                    "to": "11:00"
                  }
                ],
                "delivery_duration": 30,
                "delivery_date": "2023-01-01",
                "delivery_available_days": ["MONDAY", "TUESDAY", "THURSDAY"],
                "type": "delivery",
                "parts": 2,
                "vehicle_assignment": {
                  "vehicle_id": 1958
                },
                "emails": [
                  {
                    "email": "example@email.com"
                  },
                  {
                    "email": "example2@email.com"
                  }
                ],
                "updated": "2023-01-04T08:45:00Z",
                "third_party": {
                  "id": 134
                },
                "tags": [
                  "Tag1",
                  "Tag2"
                ],
                "line_items": [
                  {
                    "product_name": "Widget A",
                    "product_code": "WID-A",
                    "product_quantity": 3,
                    "date": "2024-01-01",
                    "custom_fields": [
                      {
                        "id": 123,
                        "value": "Value 1"
                      }
                    ]
                  },
                  {
                    "product_name": "Gadget B",
                    "product_code": "GAD-B",
                    "product_quantity": 2,
                    "date": "2024-01-01",
                    "custom_fields": [
                      {
                        "id": 321,
                        "value": "Value 1"
                      }
                    ]
                  }
                ],
                "capacities": [
                  {
                    "id": 201,
                    "type": "WEIGHT",
                    "capacity": 500
                  },
                  {
                    "id": 202,
                    "type": "VOLUME",
                    "capacity": 1000
                  }
                ],
                "skills": [
                  "Skill A",
                  "Skill B"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "order": {
                      "type": "object",
                      "properties": {
                        "order_number": {
                          "type": "string",
                          "description": "Order number."
                        },
                        "priority": {
                          "type": "string",
                          "description": "Priority of the order."
                        },
                        "type": {
                          "type": "string",
                          "enum": [
                            "delivery",
                            "pickup",
                            "shipment"
                          ],
                          "description": "Type of the order (delivery, pickup, or shipment)."
                        },
                        "delivery_contact_name": {
                          "type": "string",
                          "description": "Name of the contact person."
                        },
                        "delivery_contact_number": {
                          "type": "string",
                          "description": "Contact number of the person."
                        },
                        "delivery_contact_email": {
                          "type": "string",
                          "description": "Contact email of the person."
                        },
                        "delivery_address": {
                          "type": "string",
                          "description": "Delivery address."
                        },
                        "delivery_postcode": {
                          "type": "string",
                          "description": "Postcode for delivery address."
                        },
                        "delivery_lat": {
                          "type": "number",
                          "description": "Latitude of the delivery location."
                        },
                        "delivery_lng": {
                          "type": "number",
                          "description": "Longitude of the delivery location."
                        },
                        "delivery_duration": {
                          "type": "number",
                          "description": "Duration for order delivery in minutes."
                        },
                        "delivery_notes": {
                          "type": "string",
                          "description": "Notes for delivery instructions."
                        },
                        "delivery_date": {
                          "type": "string",
                          "format": "date",
                          "description": "Date for order delivery."
                        },
                        "delivery_available_days": {
                          "type": "array",
                          "items": {
                            "type": "string",
                            "description": "Available delivery days for the order.",
                            "enum": [
                              "MONDAY",
                              "TUESDAY",
                              "WEDNESDAY",
                              "THURSDAY",
                              "FRIDAY",
                              "SATURDAY",
                              "SUNDAY"
                            ]
                          },
                          "description": "List of available delivery days for the order."
                        },
                        "pickup_address": {
                          "type": "string",
                          "description": "Address for order pickup."
                        },
                        "pickup_postcode": {
                          "type": "string",
                          "description": "Postcode for pickup address."
                        },
                        "pickup_duration": {
                          "type": "number",
                          "description": "Duration for order pickup in minutes."
                        },
                        "pickup_lat": {
                          "type": "number",
                          "description": "Latitude of the pickup location."
                        },
                        "pickup_lng": {
                          "type": "number",
                          "description": "Longitude of the pickup location."
                        },
                        "pickup_notes": {
                          "type": "string",
                          "description": "Notes for pickup instructions."
                        },
                        "pickup_contact_name": {
                          "type": "string",
                          "description": "Name of the contact person for pickup."
                        },
                        "pickup_contact_number": {
                          "type": "string",
                          "description": "Contact number of the person for pickup."
                        },
                        "pickup_contact_email": {
                          "type": "string",
                          "format": "email",
                          "description": "Email of the contact person for pickup."
                        },
                        "pickup_available_days": {
                          "type": "array",
                          "items": {
                            "type": "string",
                            "description": "Available pickup days for the order.",
                            "enum": [
                              "MONDAY",
                              "TUESDAY",
                              "WEDNESDAY",
                              "THURSDAY",
                              "FRIDAY",
                              "SATURDAY",
                              "SUNDAY"
                            ]
                          },
                          "description": "List of available pickup days for the order."
                        },
                        "parts": {
                          "type": "number",
                          "description": "Number of parts in the order."
                        },
                        "vehicle_assignment": {
                          "type": "object",
                          "properties": {
                            "vehicle_id": {
                              "type": "integer",
                              "description": "ID of the assigned vehicle"
                            }
                          }
                        },
                        "emails": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "email": {
                                "type": "string",
                                "format": "email",
                                "description": "Additional emails"
                              }
                            }
                          }
                        },
                        "third_party": {
                          "type": "object",
                          "properties": {
                            "id": {
                              "type": "integer",
                              "description": "ID of the third party for the order"
                            }
                          },
                          "description": "Third party object"
                        },
                        "tags": {
                          "type": "array",
                          "description": "List of tag names",
                          "items": {
                            "type": "string"
                          }
                        },
                        "line_items": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "product_code": {
                                "type": "string",
                                "description": "Code of the product.",
                                "maxLength": 20
                              },
                              "product_name": {
                                "type": "string",
                                "description": "Name of the product.",
                                "maxLength": 75
                              },
                              "product_quantity": {
                                "type": "integer",
                                "description": "Quantity of the product."
                              },
                              "capacities": {
                                "type": "array",
                                "items": {
                                  "type": "object",
                                  "properties": {
                                    "id": {
                                      "type": "integer",
                                      "description": "Id of capacity (e.g., 1, 2)."
                                    },
                                    "capacity": {
                                      "type": "number",
                                      "format": "float",
                                      "description": "Capacity value for the specified type."
                                    }
                                  },
                                  "required": [
                                    "id",
                                    "capacity"
                                  ],
                                  "description": "List of capacities with their types and values."
                                },
                                "description": "List of capacities for the line item."
                              },
                              "status": {
                                "type": "string",
                                "description": "Status of the line item."
                              },
                              "date": {
                                "type": "string",
                                "format": "date",
                                "description": "Date for the line item."
                              },
                              "custom_fields": {
                                "type": "array",
                                "items": {
                                  "type": "object",
                                  "properties": {
                                    "id": {
                                      "type": "integer",
                                      "description": "Id of custom field (e.g., 1, 2)."
                                    },
                                    "value": {
                                      "type": "string",
                                      "description": "New custom field value"
                                    },
                                    "name": {
                                      "type": "string",
                                      "description": "Name of the custom field."
                                    }
                                  }
                                },
                                "description": "List custom fields for the line item"
                              }
                            },
                            "required": [
                              "product_code",
                              "product_name",
                              "product_quantity"
                            ],
                            "description": "Details of each line item in the order."
                          },
                          "description": "List of line items in the order."
                        },
                        "time_windows": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "from": {
                                "type": "string",
                                "format": "time",
                                "description": "Start time of the time window."
                              },
                              "to": {
                                "type": "string",
                                "format": "time",
                                "description": "End time of the time window."
                              },
                              "type": {
                                "type": "string",
                                "format": "string",
                                "description": "The type of the time window, pickup or delivery."
                              }
                            },
                            "required": [
                              "from",
                              "to"
                            ],
                            "description": "Time windows for order delivery or pickup."
                          },
                          "description": "List of time windows for order delivery or pickup."
                        },
                        "skills": {
                          "type": "array",
                          "items": {
                            "type": "string",
                            "description": "List of required skills for the order."
                          },
                          "description": "List of required skills for the order."
                        },
                        "custom_fields": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "id": {
                                "type": "number",
                                "description": "ID of the custom field."
                              },
                              "name": {
                                "type": "string",
                                "description": "Name of the custom field."
                              },
                              "value": {
                                "type": "string",
                                "description": "Value of the custom field."
                              }
                            },
                            "required": [
                              "value"
                            ],
                            "description": "Custom fields to include on the order. Either id or name is required."
                          },
                          "description": "List of custom fields for the order."
                        },
                        "capacities": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "id": {
                                "type": "integer",
                                "description": "Id of capacity (e.g., 1, 2)."
                              },
                              "type": {
                                "type": "string",
                                "description": "Type of the capacity"
                              },
                              "capacity": {
                                "type": "number",
                                "format": "float",
                                "description": "Capacity value for the specified type."
                              }
                            },
                            "required": [
                              "capacity"
                            ],
                            "description": "List of capacities with their types and values."
                          },
                          "description": "List of capacities for the order. Either id or type is required."
                        }
                      },
                      "required": [],
                      "description": "Details of an order including delivery, pickup, or shipment information."
                    },
                    "errors": {
                      "type": "array"
                    }
                  },
                  "example": {
                    "order": {
                      "order_number": "ORD123",
                      "type": "delivery",
                      "delivery_contact_name": "John Doe",
                      "delivery_contact_number": "+123456789",
                      "delivery_contact_email": "john.doe@example.com",
                      "delivery_address": "123 Main St",
                      "delivery_postcode": "12345",
                      "delivery_lat": 40.7128,
                      "delivery_lng": -74.0060,
                      "delivery_duration": 30,
                      "delivery_notes": "Leave at the doorstep",
                      "delivery_date": "2023-12-31",
                      "delivery_available_days": ["MONDAY", "TUESDAY", "THURSDAY"],
                      "pickup_address": "456 Oak St",
                      "pickup_postcode": "54321",
                      "pickup_duration": 30,
                      "pickup_lat": 40.730610,
                      "pickup_lng": -73.935242,
                      "pickup_notes": "Call upon arrival",
                      "pickup_contact_name": "Jane Smith",
                      "pickup_contact_number": "+987654321",
                      "pickup_contact_email": "jane@example.com",
                      "pickup_available_days": ["MONDAY", "WEDNESDAY", "FRIDAY"],
                      "parts": 2,
                      "vehicle_assignment": {
                        "vehicle_id": 1986
                      },
                      "emails": [
                        {
                          "email": "example@email.com"
                        },
                        {
                          "email": "example2@email.com"
                        }
                      ],
                      "third_party": {
                        "id": 134
                      },
                      "tags": [
                        "Tag1",
                        "Tag2"
                      ],
                      "line_items": [
                        {
                          "product_code": "P001",
                          "product_name": "Product 1",
                          "product_quantity": 2,
                          "status": "DELIVERED",
                          "date": "2024-01-01",
                          "custom_fields": [
                            {
                              "id": 123,
                              "value": "Value 1",
                              "name": "Custom Field 1"
                            }
                          ]
                        },
                        {
                          "product_code": "P002",
                          "product_name": "Product 2",
                          "product_quantity": 1,
                          "capacities": [
                            {
                              "id": 201,
                              "type": "WEIGHT",
                              "capacity": 100
                            }
                          ],
                          "status": "DELIVERED",
                          "date": "2024-01-01",
                          "custom_fields": [
                            {
                              "id": 321,
                              "value": "Value 1",
                              "name": "Custom Field 2"
                            }
                          ]
                        }
                      ],
                      "time_windows": [
                        {
                          "from": "08:00",
                          "to": "12:00",
                          "type": "pickup"
                        },
                        {
                          "from": "14:00",
                          "to": "18:00",
                          "type": "delivery"
                        }
                      ],
                      "skills": [
                        "skill1",
                        "skill2"
                      ],
                      "custom_fields": [
                        {
                          "id": 123,
                          "value": "Value 1"
                        },
                        {
                          "id": 234,
                          "value": "Value 2"
                        }
                      ],
                      "capacities": [
                        {
                          "id": 1,
                          "capacity": 100
                        },
                        {
                          "id": 2,
                          "capacity": 50
                        }
                      ]
                    },
                    "errors": []
                  }
                }
              }
            }
          },
          "400": { "$ref": "#/components/responses/InvalidInput" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "500": { "$ref": "#/components/responses/ServerError" }
        }
      }
    },
    "/orders/{id}/attachments": {
      "post": {
        "summary": "Add Attachment to Order by ID",
        "operationId": "addOrderAttachment",
        "description": "Upload a single attachment file to the order. Only one file can be uploaded per request. Supported file types: pdf, png, jpg, jpeg. Maximum file size: 10MB. Maximum of 2 attachments are allowed per order overall.",
        "tags": [
          "Orders"
        ],
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The ID of the order to attach the file to."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "properties": {
                  "attachment": {
                    "type": "string",
                    "format": "binary",
                    "description": "Upload a single file (allowed types: pdf, png, jpg, jpeg; max size 10MB)."
                  }
                },
                "required": [
                  "attachment"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Attachment successfully uploaded",
            "content": {
              "application/json": {
                "example": {
                  "id": 58,
                  "order_id": "451020",
                  "depot_id": 578,
                  "name": "SmartRoutes-Orders1.pdf",
                  "mime": "application/pdf",
                  "ext": "pdf",
                  "size": 473892,
                  "is_compressed": false,
                  "modified": "2025-09-01T14:02:02.922Z",
                  "created": "2025-09-01T14:02:02.922Z"
                }
              }
            }
          },
          "400": { "$ref": "#/components/responses/InvalidInput" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "500": { "$ref": "#/components/responses/ServerError" }
        }
      }
    },
    "/orders/order-number/{order_number}": {
      "delete": {
        "summary": "Delete Orders by Order Number",
        "operationId": "deleteOrdersByOrderNumber",
        "description": "Delete orders based on order number.",
        "tags": [
          "Orders"
        ],
        "parameters": [
          {
            "in": "path",
            "name": "order_number",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Order number to delete orders."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful response",
            "content": {
              "application/json": {
                "example": {
                  "deleted": {
                    "orders_count": 5,
                    "line_items_count": 15
                  }
                }
              }
            }
          },
          "404": { "$ref": "#/components/responses/NotFound" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "500": { "$ref": "#/components/responses/ServerError" }
        }
      }
    },
    "/plans/optimise/orders": {
      "post": {
        "summary": "Optimise Orders",
        "operationId": "optimisePlanForDate",
        "description": "Async optimisation. Returns 200 immediately with a Plan id and an optimisation job id. The optimisation runs in the background; poll `GET /plans/{id}` to check progress.\n\n**Initial response:** `{ \"optimisation\": { \"id\": \"<uuid>\", \"in_progress\": true }, \"plan\": { \"id\": <integer>, \"dispatched\": false } }`\n\n**Polling** — `GET /plans/{id}`:\n- *Completed:* `plan.routes` is non-empty (or `plan.unserved` is non-empty if no routes are viable). Either signals the optimisation has finished.\n- *Still running:* `plan.routes` and `plan.unserved` are both empty.\n- *Failed:* there is no terminal failure signal on the Plan resource today. A failed job leaves the Plan in the same \"empty arrays\" state as a still-running job. Implement a client-side hard timeout — recommended **10 minutes** — after which the job should be considered abandoned.\n\n**Recommended polling cadence:**\n- First minute: every 2 seconds.\n- After 1 minute: every 10 seconds, exponential backoff up to 30 seconds.\n- Hard timeout: 10 minutes total.\n\n**Webhook coupling:** the `PLANS_CREATED` webhook fires immediately after the Plan is persisted — *before* the optimisation job has completed. A webhook delivery does not imply the optimisation finished. Consumers receiving `PLANS_CREATED` should still poll `GET /plans/{id}` to learn the outcome.\n\n**Concurrency limits per depot** (queue, not timeout): STANDARD 100, LONG 100, DIST 7, BOOKING_CHECK 1. No documented per-job timeout; typical jobs complete in 5–30 seconds.\n\n**Idempotency:** Supports the `idempotency-key` request header for safe retries. See the Idempotency section in the API description.",
        "tags": [
          "Plans"
        ],
        "parameters": [
          { "$ref": "#/components/parameters/IdempotencyKeyHeader" }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "delivery_date": {
                    "type": "string",
                    "format": "date",
                    "description": "The delivery date YYYY-MM-DD for optimizing orders."
                  },
                  "plan": {
                    "type": "object",
                    "properties": {
                      "id": {
                        "type": "integer",
                        "description": "You can provide a plan id to re-use for generating your route"
                      },
                      "name": {
                        "type": "string",
                        "description": "Provide a name for the plan. This will override the existing plan name if an id is provided."
                      }
                    }
                  },
                  "settings": {
                    "type": "object",
                    "properties": {
                      "active_vehicles": {
                        "type": "boolean",
                        "description": "Flag to include only active vehicles."
                      },
                      "auto_dispatch": {
                        "type": "boolean",
                        "description": "Flag for auto_dispatch."
                      }
                    },
                    "required": [
                      "active_vehicles",
                      "auto_dispatch"
                    ]
                  },
                  "vehicles": {
                    "nullable": true,
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "integer",
                          "description": "ID of the vehicle."
                        },
                        "name": {
                          "type": "string",
                          "description": "Name of the vehicle."
                        },
                        "availability": {
                          "type": "string",
                          "description": "Availability status of the vehicle.",
                          "enum": [
                            "shift",
                            "full_day",
                            "always"
                          ]
                        },
                        "shift_start": {
                          "type": "string",
                          "format": "time",
                          "nullable": true,
                          "description": "Start time of the vehicle's shift (if availability is 'shift')."
                        },
                        "shift_end": {
                          "type": "string",
                          "format": "time",
                          "nullable": true,
                          "description": "End time of the vehicle's shift (if availability is 'shift')."
                        },
                        "start_location": {
                          "type": "string",
                          "description": "Location type where the vehicle starts.",
                          "enum": [
                            "depot",
                            "other",
                            "app-location"
                          ]
                        },
                        "start_address": {
                          "type": "string",
                          "nullable": true,
                          "description": "Address where the vehicle starts (if location is 'other')."
                        },
                        "start_lng": {
                          "type": "number",
                          "nullable": true,
                          "description": "Longitude of the starting location (if location is 'other')."
                        },
                        "start_lat": {
                          "type": "number",
                          "nullable": true,
                          "description": "Latitude of the starting location (if location is 'other')."
                        },
                        "end_location": {
                          "type": "string",
                          "description": "Location type where the vehicle ends.",
                          "enum": [
                            "depot",
                            "other",
                            "none"
                          ]
                        },
                        "end_address": {
                          "type": "string",
                          "nullable": true,
                          "description": "Address where the vehicle ends (if location is 'other')."
                        },
                        "end_lng": {
                          "type": "number",
                          "nullable": true,
                          "description": "Longitude of the ending location (if location is 'other')."
                        },
                        "end_lat": {
                          "type": "number",
                          "nullable": true,
                          "description": "Latitude of the ending location (if location is 'other')."
                        },
                        "break": {
                          "type": "boolean",
                          "description": "Flag indicating whether the vehicle has a break."
                        },
                        "break_start": {
                          "type": "string",
                          "format": "time",
                          "nullable": true,
                          "description": "Start time of the vehicle's break (if it has a break)."
                        },
                        "break_end": {
                          "type": "string",
                          "format": "time",
                          "nullable": true,
                          "description": "End time of the vehicle's break (if it has a break)."
                        },
                        "break_duration": {
                          "type": "number",
                          "nullable": true,
                          "description": "Duration of the vehicle's break in minutes (if it has a break)."
                        },
                        "active": {
                          "type": "boolean",
                          "description": "Flag indicating whether the vehicle is active."
                        },
                        "skills": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          },
                          "description": "Array of skills associated with the vehicle."
                        },
                        "capacities": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "id": {
                                "type": "integer",
                                "description": "Id of capacity (e.g., 1, 2)."
                              },
                              "capacity": {
                                "type": "number",
                                "format": "float",
                                "description": "Capacity value for the specified type."
                              }
                            },
                            "required": [
                              "id",
                              "capacity"
                            ],
                            "description": "Details of each capacity associated with the vehicle."
                          },
                          "description": "Array of capacities associated with the vehicle."
                        }
                      },
                      "required": [
                        "id",
                        "availability",
                        "start_location",
                        "end_location"
                      ],
                      "description": "Override details of a vehicle for this optimisation request."
                    }
                  },
                  "zone_group_id": {
                    "type": "integer",
                    "description": "The ID of the zone group for optimization."
                  }
                },
                "required": [
                  "delivery_date",
                  "settings"
                ]
              },
              "example": {
                "delivery_date": "2023-12-31",
                "settings": {
                  "active_vehicles": true,
                  "auto_dispatch": true
                },
                "zone_group_id": 123
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Optimisation accepted and Plan created. The optimisation runs asynchronously; poll `GET /plans/{id}` for completion.",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/PlanOptimisationResponse" },
                "example": {
                  "optimisation": {
                    "id": "123e4567-e89b-12d3-a456-426614174001",
                    "in_progress": true
                  },
                  "plan": {
                    "id": 123,
                    "dispatched": true
                  }
                }
              }
            },
            "headers": {
              "idempotency-replay": { "$ref": "#/components/headers/IdempotencyReplay" }
            }
          },
          "400": { "$ref": "#/components/responses/InvalidInput" },
          "409": { "$ref": "#/components/responses/IdempotencyRequestInProgress" },
          "422": { "$ref": "#/components/responses/IdempotencyKeyReusedWithDifferentBody" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "500": { "$ref": "#/components/responses/ServerError" }
        }
      }
    },
    "/plans/optimise/orders-for-ids": {
      "post": {
        "summary": "Optimise Orders For IDs",
        "operationId": "optimisePlanForOrderIds",
        "description": "Async optimisation for a specific set of order IDs. Same lifecycle and polling semantics as `POST /plans/optimise/orders` — see that endpoint's description for completion detection, polling cadence, and the failure-signal gap. Supports the `idempotency-key` request header for safe retries.",
        "tags": [
          "Plans"
        ],
        "parameters": [
          { "$ref": "#/components/parameters/IdempotencyKeyHeader" }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "orders": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "number",
                          "description": "ID of the order"
                        }
                      }
                    }
                  },
                  "plan": {
                    "type": "object",
                    "properties": {
                      "id": {
                        "type": "integer",
                        "description": "You can provide a plan id to re-use for generating your route"
                      },
                      "name": {
                        "type": "string",
                        "description": "Provide a name for the plan. This will override the existing plan name if an id is provided."
                      },
                      "date": {
                        "type": "string",
                        "format": "date",
                        "description": "The date of your plan. Format YYYY-MM-DD"
                      }
                    }
                  },
                  "settings": {
                    "type": "object",
                    "properties": {
                      "active_vehicles": {
                        "type": "boolean",
                        "description": "Flag to include only active vehicles."
                      },
                      "auto_dispatch": {
                        "type": "boolean",
                        "description": "Flag for auto_dispatch."
                      }
                    },
                    "required": [
                      "active_vehicles",
                      "auto_dispatch"
                    ]
                  },
                  "vehicles": {
                    "nullable": true,
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "integer",
                          "description": "ID of the vehicle."
                        },
                        "name": {
                          "type": "string",
                          "description": "Name of the vehicle."
                        },
                        "availability": {
                          "type": "string",
                          "description": "Availability status of the vehicle.",
                          "enum": [
                            "shift",
                            "full_day",
                            "always"
                          ]
                        },
                        "shift_start": {
                          "type": "string",
                          "format": "time",
                          "nullable": true,
                          "description": "Start time of the vehicle's shift (if availability is 'shift')."
                        },
                        "shift_end": {
                          "type": "string",
                          "format": "time",
                          "nullable": true,
                          "description": "End time of the vehicle's shift (if availability is 'shift')."
                        },
                        "start_location": {
                          "type": "string",
                          "description": "Location type where the vehicle starts.",
                          "enum": [
                            "depot",
                            "other",
                            "app-location"
                          ]
                        },
                        "start_address": {
                          "type": "string",
                          "nullable": true,
                          "description": "Address where the vehicle starts (if location is 'other')."
                        },
                        "start_lng": {
                          "type": "number",
                          "nullable": true,
                          "description": "Longitude of the starting location (if location is 'other')."
                        },
                        "start_lat": {
                          "type": "number",
                          "nullable": true,
                          "description": "Latitude of the starting location (if location is 'other')."
                        },
                        "end_location": {
                          "type": "string",
                          "description": "Location type where the vehicle ends.",
                          "enum": [
                            "depot",
                            "other",
                            "none"
                          ]
                        },
                        "end_address": {
                          "type": "string",
                          "nullable": true,
                          "description": "Address where the vehicle ends (if location is 'other')."
                        },
                        "end_lng": {
                          "type": "number",
                          "nullable": true,
                          "description": "Longitude of the ending location (if location is 'other')."
                        },
                        "end_lat": {
                          "type": "number",
                          "nullable": true,
                          "description": "Latitude of the ending location (if location is 'other')."
                        },
                        "break": {
                          "type": "boolean",
                          "description": "Flag indicating whether the vehicle has a break."
                        },
                        "break_start": {
                          "type": "string",
                          "format": "time",
                          "nullable": true,
                          "description": "Start time of the vehicle's break (if it has a break)."
                        },
                        "break_end": {
                          "type": "string",
                          "format": "time",
                          "nullable": true,
                          "description": "End time of the vehicle's break (if it has a break)."
                        },
                        "break_duration": {
                          "type": "number",
                          "nullable": true,
                          "description": "Duration of the vehicle's break in minutes (if it has a break)."
                        },
                        "active": {
                          "type": "boolean",
                          "description": "Flag indicating whether the vehicle is active."
                        },
                        "skills": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          },
                          "description": "Array of skills associated with the vehicle."
                        },
                        "capacities": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "id": {
                                "type": "integer",
                                "description": "Id of capacity (e.g., 1, 2)."
                              },
                              "capacity": {
                                "type": "number",
                                "format": "float",
                                "description": "Capacity value for the specified type."
                              }
                            },
                            "required": [
                              "id",
                              "capacity"
                            ],
                            "description": "Details of each capacity associated with the vehicle."
                          },
                          "description": "Array of capacities associated with the vehicle."
                        }
                      },
                      "required": [
                        "id",
                        "availability",
                        "start_location",
                        "end_location"
                      ],
                      "description": "Override details of a vehicle for this optimisation request."
                    }
                  },
                  "zone_group_id": {
                    "type": "integer",
                    "description": "The ID of the zone group for optimization."
                  }
                },
                "required": [
                  "settings",
                  "orders"
                ]
              },
              "example": {
                "orders": [
                  {
                    "id": 456
                  },
                  {
                    "id": 789
                  }
                ],
                "settings": {
                  "active_vehicles": true,
                  "auto_dispatch": true
                },
                "zone_group_id": 123
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Optimisation accepted and Plan created. The optimisation runs asynchronously; poll `GET /plans/{id}` for completion.",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/PlanOptimisationResponse" },
                "example": {
                  "optimisation": {
                    "id": "123e4567-e89b-12d3-a456-426614174001",
                    "in_progress": true
                  },
                  "plan": {
                    "id": 123,
                    "dispatched": true
                  }
                }
              }
            },
            "headers": {
              "idempotency-replay": { "$ref": "#/components/headers/IdempotencyReplay" }
            }
          },
          "400": { "$ref": "#/components/responses/InvalidInput" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "409": { "$ref": "#/components/responses/IdempotencyRequestInProgress" },
          "422": { "$ref": "#/components/responses/IdempotencyKeyReusedWithDifferentBody" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "500": { "$ref": "#/components/responses/ServerError" }
        }
      }
    },
    "/plans/optimise/{id}": {
      "get": {
        "summary": "Get Optimisation Job by ID",
        "operationId": "getOptimisationJobById",
        "description": "Retrieve the status of a plan optimisation by UUID.",
        "tags": [
          "Plans"
        ],
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "ID of the current optimisation to retrieve."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful response",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/PlanOptimisationResponse" },
                "example": {
                  "optimisation": {
                    "id": "123e4567-e89b-12d3-a456-426614174001",
                    "in_progress": false
                  },
                  "plan": {
                    "id": 123,
                    "dispatched": true
                  }
                }
              }
            }
          },
          "404": { "$ref": "#/components/responses/NotFound" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "500": { "$ref": "#/components/responses/ServerError" }
        }
      }
    },
    "/plans/{id}": {
      "get": {
        "summary": "Get Plan by ID",
        "operationId": "getPlanById",
        "description": "Retrieve a Plan based on ID. When the plan was just created via the optimise endpoint and the optimisation job has not finished, `routes` and `unserved` are both empty arrays — see the async optimise endpoint description for polling guidance and failure-signal limitations.",
        "tags": [
          "Plans"
        ],
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "number"
            },
            "description": "ID of the plan to retrieve."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful response",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/PlanResponse" },
                "example": {
                  "plan": {
                    "id": 123,
                    "total_time": 120,
                    "routes": [
                      {
                        "id": 1234,
                        "name": "Route 1",
                        "date": "2023-12-12",
                        "start_time": "08:00",
                        "started_ts": "2024-07-09T09:00:00.000Z",
                        "end_time": "16:00",
                        "completed_ts": "2024-07-09T17:18:40.000Z",
                        "total_time": 120,
                        "travel_time": 90,
                        "planned_distance": 50,
                        "actual_distance": 45,
                        "vehicle": {
                          "vehicle_id": "vehicle-1",
                          "name": "Vehicle A",
                          "driver": "John Doe"
                        },
                        "stops": [
                          {
                            "id": 123,
                            "route_id": 456,
                            "address": "123 Main St",
                            "phone": "555-1234",
                            "lat": 12.345,
                            "lng": -45.678,
                            "planned_distance": 1234.5,
                            "arrival_date": "2023-12-31",
                            "departure_date": "2023-12-31",
                            "delivery_notes": "Leave at the doorstep",
                            "driver_notes": "Customer not available initially",
                            "estimated_arrival_time": "09:00",
                            "estimated_departure_time": "10:00",
                            "actual_completed_ts": "2023-12-31T10:15:00",
                            "actual_arrival_time": "2023-12-31T09:15:00",
                            "actual_completed_lat": 12.345,
                            "actual_completed_lng": -45.678,
                            "actual_duration": 60,
                            "signature": "https://api.smartroutes.io/v2/proof-of-delivery/signatures/111486",
                            "signature_lat": 12.345,
                            "signature_lng": -45.678,
                            "signed_by": "John",
                            "tracking_link": "https://tracksr.io/xyzabc",
                            "photos": [
                              "https://api.smartroutes.io/v2/proof-of-delivery/photos/491548"
                            ],
                            "orders": [
                              {
                                "id": 123,
                                "order_number": "ORD123",
                                "custom_fields": {
                                  "id": 789,
                                  "value": "Example Value",
                                  "name": "Example Custom Field"
                                },
                                "type": "delivery",
                                "line_items": [
                                  {
                                    "id": 456,
                                    "product_code": "1",
                                    "product_name": "1",
                                    "quantity": 10,
                                    "status": "OPEN",
                                    "date": "2024-01-12",
                                    "custom_fields": [
                                      {
                                        "id": 123,
                                        "value": "Value 1",
                                        "name": "Custom Field 1"
                                      }
                                    ]
                                  }
                                ]
                              }
                            ],
                            "vehicle_assignment": {
                              "vehicle_id": 45321
                            },
                            "emails": [
                              {
                                "email": "example@email.com"
                              },
                              {
                                "email": "example2@email.com"
                              }
                            ],
                            "driver_questionnaire_submissions": [
                              {
                                "id": 1267,
                                "driver_questionnaire": {
                                  "type": "VISIT",
                                  "title": "Stop Questionaire"
                                }
                              }
                            ],
                            "failed_reason": {
                              "reason": "Wrong Parcel"
                            },
                            "tags": [
                              "Tag1",
                              "Tag2"
                            ],
                            "available_days": ["MONDAY", "THURSDAY"]
                          }
                        ]
                      }
                    ],
                    "unserved": [
                      {
                        "id": 123,
                        "address": "456 Oak St",
                        "postcode": "67890",
                        "phone": "555-5678",
                        "lat": 40.5678,
                        "lng": -75.1234,
                        "delivery_notes": "Delivery notes for unserved visit",
                        "available_days": ["MONDAY, THURSDAY"]
                      }
                    ],
                    "created": "2022-04-29T16:12:08.000Z",
                    "updated": "2022-09-29T10:11:06.000Z",
                    "driver_questionnaire_submissions": [
                      {
                        "id": 1266,
                        "driver_questionnaire": {
                          "type": "ROUTE_VEHICLE_CHECKIN",
                          "title": "Route Start Questionnaire"
                        }
                      },
                      {
                        "id": 1268,
                        "driver_questionnaire": {
                          "type": "ROUTE_VEHICLE_CHECKIN",
                          "title": "Completed Questionnaire"
                        }
                      }
                    ]
                  }
                }
              }
            }
          },
          "404": { "$ref": "#/components/responses/NotFound" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "500": { "$ref": "#/components/responses/ServerError" }
        }
      },
      "delete": {
        "summary": "Delete Plan by ID",
        "operationId": "deletePlanById",
        "description": "Delete a plan based on ID.",
        "tags": [
          "Plans"
        ],
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "number"
            },
            "description": "ID of the plan to delete."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful response",
            "content": {
              "application/json": {
                "example": {
                  "deleted": {
                    "plans_count": 1
                  }
                }
              }
            }
          },
          "404": { "$ref": "#/components/responses/NotFound" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "500": { "$ref": "#/components/responses/ServerError" }
        }
      }
    },
    "/plans": {
      "get": {
        "summary": "Get Plans Page",
        "operationId": "listPlans",
        "description": "Endpoint to retrieve a page of plans.",
        "tags": [
          "Plans"
        ],
        "parameters": [
          {
            "in": "query",
            "name": "page_info",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Information about the page for pagination. Generated by the OpenAPI"
            },
            "description": "Information about the page for pagination. Generated by the OpenAPI"
          },
          {
            "in": "query",
            "name": "updated_at_min",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date-time",
              "description": "Minimum updated date and time for filtering."
            },
            "description": "Minimum updated date and time for filtering."
          },
          {
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 100,
              "description": "Maximum number of plans to retrieve per page."
            },
            "description": "Maximum number of plans to retrieve per page."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful response",
            "headers": {
              "link": {
                "description": "Link to the next page of plans. Use with the page_info parameter for pagination.",
                "schema": {
                  "type": "string"
                },
                "example": "<https://api.smartroutes.io/v2/plans?page_info=PAGE_INFO_STRING&limit=100>; rel=next"
              }
            },
            "content": {
              "application/json": {
                "example": {
                  "plans": [
                    {
                      "id": 123,
                      "dispatched": true,
                      "created": "2024-07-08T17:33:37.000Z",
                      "updated": "2024-07-08T17:33:37.000Z",
                      "total_time": 120,
                      "routes": [
                        {
                          "id": 1234,
                          "name": "Route 1",
                          "stops": 4,
                          "dispatched": true,
                          "started_ts": "2024-07-09T09:00:00.000Z",
                          "completed_ts": "2024-07-09T17:18:40.000Z",
                          "total_time": "595",
                          "travel_time": "475",
                          "operation_time": "120",
                          "date": "2024-07-11",
                          "distance": 100,
                          "actual_distance": null,
                          "created": "2024-07-08T17:18:40.000Z",
                          "updated": "2024-07-08T17:18:40.000Z"
                        }
                      ]
                    },
                    {
                      "id": 124,
                      "dispatched": true,
                      "created": "2024-07-08T17:33:37.000Z",
                      "updated": "2024-07-08T17:33:37.000Z",
                      "total_time": 120,
                      "routes": [
                        {
                          "id": 1235,
                          "name": "Route 2",
                          "stops": 4,
                          "dispatched": true,
                          "started_ts": "2024-07-09T09:00:00.000Z",
                          "completed_ts": "2024-07-09T17:18:40.000Z",
                          "total_time": "595",
                          "travel_time": "475",
                          "operation_time": "120",
                          "date": "2024-07-11",
                          "distance": 100,
                          "actual_distance": null,
                          "created": "2024-07-08T17:18:40.000Z",
                          "updated": "2024-07-08T17:18:40.000Z"
                        }
                      ]
                    }
                  ]
                }
              }
            }
          },
          "400": { "$ref": "#/components/responses/InvalidInput" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "500": { "$ref": "#/components/responses/ServerError" }
        }
      }
    },
    "/routes/{id}": {
      "get": {
        "summary": "Get Route by ID",
        "operationId": "getRouteById",
        "description": "Retrieve a route based on ID.",
        "tags": [
          "Routes"
        ],
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "number"
            },
            "description": "ID of the route to retrieve."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful response",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/RouteResponse" },
                "example": {
                  "id": 12345,
                  "plan_id": 67,
                  "name": "Route 1",
                  "dispatched": true,
                  "date": "2023-12-31",
                  "start_time": "08:00",
                  "started_ts": "2024-07-09T09:00:00.000Z",
                  "end_time": "16:00",
                  "completed_ts": "2024-07-09T17:18:40.000Z",
                  "total_time": 480,
                  "travel_time": 300,
                  "planned_distance": 50,
                  "actual_distance": 45,
                  "vehicle": {
                    "vehicle_id": "vehicle_456",
                    "name": "Delivery Van",
                    "driver": "John Doe"
                  },
                  "stops": [
                    {
                      "id": 123,
                      "route_id": 135,
                      "address": "123 Main St",
                      "phone": "555-1234",
                      "lat": 12.345,
                      "lng": -45.678,
                      "planned_distance": 1234.5,
                      "arrival_date": "2023-12-31",
                      "departure_date": "2023-12-31",
                      "delivery_notes": "Leave at the doorstep",
                      "driver_notes": "Customer not available initially",
                      "estimated_arrival_time": "09:00",
                      "estimated_departure_time": "10:00",
                      "actual_completed_ts": "2023-12-31T10:15:00",
                      "actual_completed_lat": 12.345,
                      "actual_completed_lng": -45.678,
                      "actual_arrival_time": "2023-12-31T09:15:00",
                      "actual_duration": 60,
                      "signature": "https://api.smartroutes.io/v2/proof-of-delivery/signatures/111486",
                      "signature_lat": 12.345,
                      "signature_lng": -45.678,
                      "signed_by": "John",
                      "tracking_link": "https://tracksr.io/xyzabc",
                      "photos": [
                        "https://api.smartroutes.io/v2/proof-of-delivery/photos/491548"
                      ],
                      "orders": [
                        {
                          "id": 123,
                          "order_number": "ORD123",
                          "type": "delivery",
                          "line_items": [
                            {
                              "id": 456,
                              "product_code": "1",
                              "product_name": "1",
                              "quantity": 10,
                              "status": "OPEN",
                              "date": "2024-01-12",
                              "custom_fields": [
                                {
                                  "id": 123,
                                  "value": "Value 1",
                                  "name": "Custom Field 1"
                                }
                              ]
                            }
                          ]
                        }
                      ],
                      "vehicle_assignment": {
                        "vehicle_id": 1958
                      },
                      "emails": [
                        {
                          "email": "example@email.com"
                        },
                        {
                          "email": "example2@email.com"
                        }
                      ],
                      "driver_questionnaire_submissions": [
                        {
                          "id": 1267,
                          "driver_questionnaire": {
                            "type": "VISIT",
                            "title": "Stop Questionnaire"
                          }
                        }
                      ],
                      "failed_reason": {
                        "reason": "Wrong Parcel"
                      },
                      "tags":[
                        "Tag1",
                        "Tag2"
                      ],
                      "available_days": ["MONDAY", "WEDNESDAY", "THURSDAY"]
                    }
                  ],
                  "created": "2024-06-19T08:56:43.000Z",
                  "updated": "2024-06-19T08:56:43.000Z",
                  "driver_questionnaire_submissions": [
                    {
                      "id": 1266,
                      "driver_questionnaire": {
                        "type": "ROUTE_VEHICLE_CHECKIN",
                        "title": "Route Start Questionnaire"
                      }
                    },
                    {
                      "id": 1268,
                      "driver_questionnaire": {
                        "type": "ROUTE_VEHICLE_CHECKIN",
                        "title": "Completed Questionnaire"
                      }
                    }
                  ]
                }
              }
            }
          },
          "404": { "$ref": "#/components/responses/NotFound" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "500": { "$ref": "#/components/responses/ServerError" }
        }
      }
    },
    "/routes/{id}/reverse": {
      "post": {
        "summary": "Reverse Route by ID",
        "operationId": "reverseRouteById",
        "description": "Reverse a route based on ID.",
        "tags": [
          "Routes"
        ],
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "number"
            },
            "description": "ID of the route to reverse."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful response",
            "content": {
              "application/json": {
                "example": {
                  "id": 12345,
                  "plan_id": 67,
                  "name": "Route 1",
                  "date": "2023-12-31",
                  "start_time": "08:00",
                  "started_ts": "2024-07-09T09:00:00.000Z",
                  "end_time": "16:00",
                  "completed_ts": "2024-07-09T17:18:40.000Z",
                  "total_time": 480,
                  "travel_time": 300,
                  "planned_distance": 50,
                  "actual_distance": 45,
                  "vehicle": {
                    "vehicle_id": "vehicle_456",
                    "name": "Delivery Van",
                    "driver": "John Doe"
                  },
                  "stops": [
                    {
                      "id": 123,
                      "route_id": 456,
                      "address": "123 Main St",
                      "phone": "555-1234",
                      "lat": 12.345,
                      "lng": -45.678,
                      "planned_distance": 1278.2,
                      "arrival_date": "2023-12-31",
                      "departure_date": "2023-12-31",
                      "delivery_notes": "Leave at the doorstep",
                      "driver_notes": "Customer not available initially",
                      "estimated_arrival_time": "09:00",
                      "estimated_departure_time": "10:00",
                      "actual_completed_ts": "2023-12-31T10:15:00",
                      "actual_arrival_time": "2023-12-31T09:15:00",
                      "actual_completed_lat": 12.345,
                      "actual_completed_lng": -45.678,
                      "actual_duration": 60,
                      "signature": "https://api.smartroutes.io/v2/proof-of-delivery/signatures/111486",
                      "signature_lng": -45.678,
                      "signature_lat": 12.345,
                      "signed_by": "John",
                      "tracking_link": "https://tracksr.io/xyzabc",
                      "photos": [
                        "https://api.smartroutes.io/v2/proof-of-delivery/photos/491548"
                      ],
                      "orders": [
                        {
                          "id": 123,
                          "order_number": "ORD123"
                        }
                      ],
                      "vehicle_assignment": null,
                      "driver_questionnaire_submissions": [
                        {
                          "id": 1270,
                          "driver_questionnaire": {
                            "type": "VISIT",
                            "title": "Stop Questionaire"
                          }
                        }
                      ],
                      "tags": [
                        "Tag1",
                        "Tag2"
                      ]
                    }
                  ]
                }
              }
            }
          },
          "404": { "$ref": "#/components/responses/NotFound" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "500": { "$ref": "#/components/responses/ServerError" }
        }
      }
    },
    "/routes": {
      "get": {
        "summary": "Get Routes Page",
        "operationId": "listRoutes",
        "description": "Endpoint to retrieve a page of routes.",
        "tags": [
          "Routes"
        ],
        "parameters": [
          {
            "in": "query",
            "name": "page_info",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Information about the page for pagination. Generated by the OpenAPI"
            },
            "description": "Information about the page for pagination. Generated by the OpenAPI"
          },
          {
            "in": "query",
            "name": "updated_at_min",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date-time",
              "description": "Minimum updated date and time for filtering."
            },
            "description": "Minimum updated date and time for filtering."
          },
          {
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 100,
              "description": "Maximum number of routes to retrieve per page."
            },
            "description": "Maximum number of routes to retrieve per page."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful response",
            "headers": {
              "link": {
                "description": "Link to the next page of routes. Use with the page_info parameter for pagination.",
                "schema": {
                  "type": "string"
                },
                "example": "<https://api.smartroutes.io/v2/routes?page_info=PAGE_INFO_STRING&limit=100>; rel=next"
              }
            },
            "content": {
              "application/json": {
                "example": {
                  "routes": [
                    {
                      "id": 12345,
                      "plan_id": 67,
                      "name": "Route 1",
                      "stops": 5,
                      "dispatched": true,
                      "started_ts": "2024-07-09T09:00:00.000Z",
                      "completed_ts": "2024-07-09T17:18:40.000Z",
                      "date": "2023-12-31",
                      "start_time": "08:00",
                      "end_time": "16:00",
                      "total_time": 480,
                      "travel_time": 300,
                      "planned_distance": 50,
                      "actual_distance": 45,
                      "created": "2024-06-19T08:56:43.000Z",
                      "updated": "2024-06-19T08:56:43.000Z"
                    },
                    {
                      "id": 12346,
                      "plan_id": 89,
                      "name": "Route 2",
                      "stops": 5,
                      "dispatched": true,
                      "started_ts": "2024-07-09T09:00:00.000Z",
                      "completed_ts": "2024-07-09T16:38:40.000Z",
                      "date": "2023-12-31",
                      "start_time": "08:00",
                      "end_time": "16:00",
                      "total_time": 480,
                      "travel_time": 300,
                      "planned_distance": 50,
                      "actual_distance": 45,
                      "created": "2024-06-19T08:56:43.000Z",
                      "updated": "2024-06-19T08:56:43.000Z"
                    }
                  ]
                }
              }
            }
          },
          "400": { "$ref": "#/components/responses/InvalidInput" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "500": { "$ref": "#/components/responses/ServerError" }
        }
      }
    },
    "/third-parties": {
      "get": {
        "summary": "Get All Third Parties",
        "operationId": "listThirdParties",
        "description": "Endpoint to retrieve all third parties.",
        "tags": [
          "Third Parties"
        ],
        "responses": {
          "200": {
            "description": "Successful response",
            "content": {
              "application/json": {
                "example": {
                  "third-parties": [
                    {
                      "id": 134,
                      "name": "Third Party 1"
                    },
                    {
                      "id": 135,
                      "name": "Third Party 2"
                    }
                  ]
                }
              }
            }
          },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "500": { "$ref": "#/components/responses/ServerError" }
        }
      }
    },
    "/vehicles": {
      "post": {
        "summary": "Add Vehicle",
        "operationId": "createVehicle",
        "description": "Endpoint to add a vehicle.",
        "tags": [
          "Vehicles"
        ],
        "parameters": [
          { "$ref": "#/components/parameters/IdempotencyKeyHeader" }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "description": "Name of the vehicle."
                  },
                  "availability": {
                    "type": "string",
                    "description": "Availability status of the vehicle.",
                    "enum": [
                      "shift",
                      "full_day",
                      "always"
                    ]
                  },
                  "shift_start": {
                    "type": "string",
                    "format": "time",
                    "nullable": true,
                    "description": "Start time of the vehicle's shift (if availability is 'shift')."
                  },
                  "shift_end": {
                    "type": "string",
                    "format": "time",
                    "nullable": true,
                    "description": "End time of the vehicle's shift (if availability is 'shift')."
                  },
                  "start_location": {
                    "type": "string",
                    "description": "Location type where the vehicle starts.",
                    "enum": [
                      "depot",
                      "other",
                      "app-location"
                    ]
                  },
                  "start_address": {
                    "type": "string",
                    "nullable": true,
                    "description": "Address where the vehicle starts (if location is 'other')."
                  },
                  "start_lng": {
                    "type": "number",
                    "nullable": true,
                    "description": "Longitude of the starting location (if location is 'other')."
                  },
                  "start_lat": {
                    "type": "number",
                    "nullable": true,
                    "description": "Latitude of the starting location (if location is 'other')."
                  },
                  "end_location": {
                    "type": "string",
                    "description": "Location type where the vehicle ends.",
                    "enum": [
                      "depot",
                      "other",
                      "none"
                    ]
                  },
                  "end_address": {
                    "type": "string",
                    "nullable": true,
                    "description": "Address where the vehicle ends (if location is 'other')."
                  },
                  "end_lng": {
                    "type": "number",
                    "nullable": true,
                    "description": "Longitude of the ending location (if location is 'other')."
                  },
                  "end_lat": {
                    "type": "number",
                    "nullable": true,
                    "description": "Latitude of the ending location (if location is 'other')."
                  },
                  "break": {
                    "type": "boolean",
                    "description": "Flag indicating whether the vehicle has a break."
                  },
                  "break_start": {
                    "type": "string",
                    "format": "time",
                    "nullable": true,
                    "description": "Start time of the vehicle's break (if it has a break)."
                  },
                  "break_end": {
                    "type": "string",
                    "format": "time",
                    "nullable": true,
                    "description": "End time of the vehicle's break (if it has a break)."
                  },
                  "break_duration": {
                    "type": "number",
                    "nullable": true,
                    "description": "Duration of the vehicle's break in minutes (if it has a break)."
                  },
                  "active": {
                    "type": "boolean",
                    "description": "Flag indicating whether the vehicle is active."
                  },
                  "skills": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "Array of skills associated with the vehicle."
                  },
                  "capacities": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "integer",
                          "description": "Id of capacity (e.g., 1, 2)."
                        },
                        "capacity": {
                          "type": "number",
                          "format": "float",
                          "description": "Capacity value for the specified type."
                        }
                      },
                      "required": [
                        "id",
                        "capacity"
                      ],
                      "description": "Details of each capacity associated with the vehicle."
                    },
                    "description": "Array of capacities associated with the vehicle."
                  }
                },
                "required": [
                  "availability",
                  "start_location",
                  "end_location"
                ],
                "description": "Request body for creating a new vehicle.",
                "example": {
                  "name": "Vehicle Name",
                  "availability": "shift",
                  "shift_start": "08:00",
                  "shift_end": "17:30",
                  "start_location": "depot",
                  "end_location": "none",
                  "break": false,
                  "capacities": [
                    {
                      "id": 1,
                      "capacity": 500
                    }
                  ]
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Successful response",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/VehicleResponse" },
                "example": {
                  "vehicle": {
                    "id": 123,
                    "name": "Vehicle Name",
                    "active": true,
                    "capacities": [
                      {
                        "id": 1,
                        "type": "Capacity Type 1",
                        "capacity": 10
                      },
                      {
                        "id": 2,
                        "type": "Capacity Type 2",
                        "capacity": 15
                      }
                    ],
                    "skills": [
                      "Skill 1",
                      "Skill 2"
                    ],
                    "availability": "shift",
                    "start_location": "other",
                    "end_location": "other",
                    "shift_start": "08:00",
                    "shift_end": "17:00",
                    "start_address": "Start Location Address",
                    "start_lat": 12.345678,
                    "start_lng": -23.456789,
                    "end_address": "End Location Address",
                    "end_lat": 34.567890,
                    "end_lng": -45.678901,
                    "break": true,
                    "break_start": "12:00",
                    "break_end": "12:30",
                    "break_duration": 30
                  }
                }
              }
            },
            "headers": {
              "idempotency-replay": { "$ref": "#/components/headers/IdempotencyReplay" }
            }
          },
          "400": { "$ref": "#/components/responses/InvalidInput" },
          "409": { "$ref": "#/components/responses/IdempotencyRequestInProgress" },
          "422": { "$ref": "#/components/responses/IdempotencyKeyReusedWithDifferentBody" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "500": { "$ref": "#/components/responses/ServerError" }
        }
      },
      "get": {
        "summary": "Get All Vehicles",
        "operationId": "listVehicles",
        "description": "Endpoint to retrieve all vehicles.",
        "tags": [
          "Vehicles"
        ],
        "responses": {
          "200": {
            "description": "Successful response",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/VehiclesListResponse" },
                "example": {
                  "vehicles": [
                    {
                      "id": 123,
                      "name": "Vehicle Name",
                      "active": true,
                      "capacities": [
                        {
                          "id": 1,
                          "type": "Capacity Type 1",
                          "capacity": 10
                        },
                        {
                          "id": 2,
                          "type": "Capacity Type 2",
                          "capacity": 15
                        }
                      ],
                      "skills": [
                        "Skill 1",
                        "Skill 2"
                      ],
                      "availability": "shift",
                      "start_location": "other",
                      "end_location": "other",
                      "created": "2024-06-19T08:56:43.000Z",
                      "updated": "2024-06-19T08:56:43.000Z",
                      "shift_start": "08:00",
                      "shift_end": "17:00",
                      "start_address": "Start Location Address",
                      "start_lat": 12.345678,
                      "start_lng": -23.456789,
                      "end_address": "End Location Address",
                      "end_lat": 34.567890,
                      "end_lng": -45.678901,
                      "break": true,
                      "break_start": "12:00",
                      "break_end": "12:30",
                      "break_duration": 30,
                      "shift": {
                        "enabled": true,
                        "availability": "shift",
                        "shift_start": "09:30",
                        "shift_end": "17:30",
                        "force_shift_start": false,
                        "max_route_duration": 720,
                        "day_of_week": "MONDAY",
                        "breaks": [
                          {
                            "enabled": true,
                            "break_start": "11:00",
                            "break_end": "13:00",
                            "break_duration": 45
                          },
                          {
                            "enabled": true,
                            "break_start": "11:00",
                            "break_end": "13:00",
                            "break_duration": 50
                          }
                        ]
                      }
                    }
                  ]
                }
              }
            }
          },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "500": { "$ref": "#/components/responses/ServerError" }
        }
      }
    },
    "/vehicles/{id}": {
      "put": {
        "summary": "Update Vehicle by ID",
        "operationId": "updateVehicleById",
        "description": "Update a vehicle based on ID.",
        "tags": [
          "Vehicles"
        ],
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "number"
            },
            "description": "ID of the vehicle to update."
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "description": "Name of the vehicle."
                  },
                  "availability": {
                    "type": "string",
                    "description": "Availability status of the vehicle.",
                    "enum": [
                      "shift",
                      "full_day",
                      "always"
                    ]
                  },
                  "shift_start": {
                    "type": "string",
                    "format": "time",
                    "nullable": true,
                    "description": "Start time of the vehicle's shift (if availability is 'shift')."
                  },
                  "shift_end": {
                    "type": "string",
                    "format": "time",
                    "nullable": true,
                    "description": "End time of the vehicle's shift (if availability is 'shift')."
                  },
                  "start_location": {
                    "type": "string",
                    "description": "Location type where the vehicle starts.",
                    "enum": [
                      "depot",
                      "other",
                      "app-location"
                    ]
                  },
                  "start_address": {
                    "type": "string",
                    "nullable": true,
                    "description": "Address where the vehicle starts (if location is 'other')."
                  },
                  "start_lng": {
                    "type": "number",
                    "nullable": true,
                    "description": "Longitude of the starting location (if location is 'other')."
                  },
                  "start_lat": {
                    "type": "number",
                    "nullable": true,
                    "description": "Latitude of the starting location (if location is 'other')."
                  },
                  "end_location": {
                    "type": "string",
                    "description": "Location type where the vehicle ends.",
                    "enum": [
                      "depot",
                      "other",
                      "none"
                    ]
                  },
                  "end_address": {
                    "type": "string",
                    "nullable": true,
                    "description": "Address where the vehicle ends (if location is 'other')."
                  },
                  "end_lng": {
                    "type": "number",
                    "nullable": true,
                    "description": "Longitude of the ending location (if location is 'other')."
                  },
                  "end_lat": {
                    "type": "number",
                    "nullable": true,
                    "description": "Latitude of the ending location (if location is 'other')."
                  },
                  "break": {
                    "type": "boolean",
                    "description": "Flag indicating whether the vehicle has a break."
                  },
                  "break_start": {
                    "type": "string",
                    "format": "time",
                    "nullable": true,
                    "description": "Start time of the vehicle's break (if it has a break)."
                  },
                  "break_end": {
                    "type": "string",
                    "format": "time",
                    "nullable": true,
                    "description": "End time of the vehicle's break (if it has a break)."
                  },
                  "break_duration": {
                    "type": "number",
                    "nullable": true,
                    "description": "Duration of the vehicle's break in minutes (if it has a break)."
                  },
                  "active": {
                    "type": "boolean",
                    "description": "Flag indicating whether the vehicle is active."
                  },
                  "skills": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "Array of skills associated with the vehicle."
                  },
                  "capacities": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "integer",
                          "description": "Id of capacity (e.g., 1, 2)."
                        },
                        "capacity": {
                          "type": "number",
                          "format": "float",
                          "description": "Capacity value for the specified type."
                        }
                      },
                      "required": [
                        "id",
                        "capacity"
                      ],
                      "description": "Details of each capacity associated with the vehicle."
                    },
                    "description": "Array of capacities associated with the vehicle."
                  }
                },
                "required": [
                  "availability",
                  "start_location",
                  "end_location"
                ],
                "description": "Request body for updating a vehicle.",
                "example": {
                  "name": "Vehicle Name",
                  "availability": "shift",
                  "shift_start": "08:00",
                  "shift_end": "17:30",
                  "start_location": "depot",
                  "end_location": "none",
                  "break": false,
                  "capacities": [
                    {
                      "id": 1,
                      "capacity": 500
                    }
                  ]
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful response",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/VehicleResponse" },
                "example": {
                  "vehicle": {
                    "id": 123,
                    "name": "Vehicle Name",
                    "active": true,
                    "capacities": [
                      {
                        "id": 1,
                        "type": "Capacity Type 1",
                        "capacity": 10
                      },
                      {
                        "id": 2,
                        "type": "Capacity Type 2",
                        "capacity": 15
                      }
                    ],
                    "skills": [
                      "Skill 1",
                      "Skill 2"
                    ],
                    "availability": "shift",
                    "start_location": "other",
                    "end_location": "other",
                    "shift_start": "08:00",
                    "shift_end": "17:00",
                    "start_address": "Start Location Address",
                    "start_lat": 12.345678,
                    "start_lng": -23.456789,
                    "end_address": "End Location Address",
                    "end_lat": 34.567890,
                    "end_lng": -45.678901,
                    "break": true,
                    "break_start": "12:00",
                    "break_end": "12:30",
                    "break_duration": 30,
                    "shift": {
                      "enabled": true,
                      "availability": "shift",
                      "shift_start": "09:30",
                      "shift_end": "17:30",
                      "force_shift_start": false,
                      "max_route_duration": 720,
                      "day_of_week": "MONDAY",
                      "breaks": [
                        {
                          "enabled": true,
                          "break_start": "11:00",
                          "break_end": "13:00",
                          "break_duration": 45
                        },
                        {
                          "id": 4,
                          "vehicle_shift_id": 2533,
                          "enabled": true,
                          "break_start": "11:00",
                          "break_end": "13:00",
                          "break_duration": 50
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "400": { "$ref": "#/components/responses/InvalidInput" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "500": { "$ref": "#/components/responses/ServerError" }
        }
      },
      "get": {
        "summary": "Get Vehicle by ID",
        "operationId": "getVehicleById",
        "description": "Retrieve a vehicle based on ID.",
        "tags": [
          "Vehicles"
        ],
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "number"
            },
            "description": "ID of the vehicle to retrieve."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful response",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/VehicleResponse" },
                "example": {
                  "vehicle": {
                    "id": 123,
                    "name": "Vehicle Name",
                    "active": true,
                    "capacities": [
                      {
                        "id": 1,
                        "type": "Capacity Type 1",
                        "capacity": 10
                      },
                      {
                        "id": 2,
                        "type": "Capacity Type 2",
                        "capacity": 15
                      }
                    ],
                    "skills": [
                      "Skill 1",
                      "Skill 2"
                    ],
                    "availability": "shift",
                    "start_location": "other",
                    "end_location": "other",
                    "created": "2024-06-19T08:56:43.000Z",
                    "updated": "2024-06-19T08:56:43.000Z",
                    "shift_start": "08:00",
                    "shift_end": "17:00",
                    "start_address": "Start Location Address",
                    "start_lat": 12.345678,
                    "start_lng": -23.456789,
                    "end_address": "End Location Address",
                    "end_lat": 34.567890,
                    "end_lng": -45.678901,
                    "break": true,
                    "break_start": "12:00",
                    "break_end": "12:30",
                    "break_duration": 30
                  }
                }
              }
            }
          },
          "404": { "$ref": "#/components/responses/NotFound" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "500": { "$ref": "#/components/responses/ServerError" }
        }
      },
      "delete": {
        "summary": "Delete Vehicle by ID",
        "operationId": "deleteVehicleById",
        "description": "Delete a vehicle based on ID.",
        "tags": [
          "Vehicles"
        ],
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "number"
            },
            "description": "ID of the vehicle to delete."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful response",
            "content": {
              "application/json": {
                "example": {
                  "deleted": {
                    "vehicles_count": 1
                  }
                }
              }
            }
          },
          "404": { "$ref": "#/components/responses/NotFound" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "500": { "$ref": "#/components/responses/ServerError" }
        }
      }
    },
    "/zone-groups": {
      "get": {
        "summary": "Get Zone Groups",
        "operationId": "listZoneGroups",
        "description": "Endpoint to retrieve zone groups.",
        "tags": [
          "Zone Groups"
        ],
        "responses": {
          "200": {
            "description": "Successful response",
            "content": {
              "application/json": {
                "example": {
                  "zone_groups": [
                    {
                      "id": 123,
                      "name": "Zone Group 1",
                      "created": "2024-06-19T08:56:43.000Z",
                      "updated": "2024-06-19T08:56:43.000Z"
                    },
                    {
                      "id": 124,
                      "name": "Zone Group 2",
                      "created": "2024-06-19T08:56:43.000Z",
                      "updated": "2024-06-19T08:56:43.000Z"
                    },
                    {
                      "id": 125,
                      "name": "Zone Group 3",
                      "created": "2024-06-19T08:56:43.000Z",
                      "updated": "2024-06-19T08:56:43.000Z"
                    }
                  ]
                }
              }
            }
          },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "500": { "$ref": "#/components/responses/ServerError" }
        }
      }
    },
    "/zone-groups/{id}/bounds/contains": {
      "post": {
        "summary": "Get Zone for Location",
        "operationId": "getZoneGroupForLocation",
        "description": "Endpoint to return the zone name and zone ID for a given location within a specified zone group.",
        "tags": [
          "Zone Groups"
        ],
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "number"
            },
            "description": "ID of the zone group."
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "location": {
                    "type": "object",
                    "properties": {
                      "lat": {
                        "type": "number",
                        "format": "float",
                        "description": "Latitude of the location for booking availability."
                      },
                      "lng": {
                        "type": "number",
                        "format": "float",
                        "description": "Longitude of the location for booking availability."
                      },
                      "address": {
                        "type": "string",
                        "description": "Address of the location for booking availability."
                      },
                      "postcode": {
                        "type": "string",
                        "description": "Postcode of the location for booking availability."
                      },
                      "country": {
                        "type": "string",
                        "description": "Country of the location for booking availability."
                      }
                    },
                    "required": [],
                    "description": "Location information for zone. If no lat, lng is provided, address or postcode is required."
                  }
                },
                "required": [
                  "location"
                ],
                "description": "Request body for checking availability for bookings."
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful response",
            "content": {
              "application/json": {
                "example": {
                  "zone": {
                    "name": "Cork City",
                    "id": 123,
                    "zone_group": {
                      "name": "Cork County",
                      "id": 321
                    }
                  }
                }
              }
            }
          },
          "400": { "$ref": "#/components/responses/InvalidInput" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "500": { "$ref": "#/components/responses/ServerError" }
        }
      }
    },
    "/driver-questionnaire-submission/{id}": {
      "get": {
        "summary": "Get a driver questionnaire submission by ID",
        "operationId": "getDriverQuestionnaireSubmissionById",
        "tags": [
          "Driver Questionnaires"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "description": "Driver Questionnaire Submission ID"
          }
        ],
        "responses": {
          "200": {
            "description": "Driver Questionnaire Submission",
            "content": {
              "application/json": {
                "example": {
                  "driver_questionnaire_submission": {
                    "id": 1266,
                    "route_id": 101838,
                    "visit_id": null,
                    "driver_questionnaire": {
                      "type": "ROUTE_VEHICLE_CHECKIN",
                      "title": "Route Questionnaire"
                    },
                    "driver_questionnaire_answers": [
                      {
                        "id": 4028,
                        "type": "CHECKBOX",
                        "data": "1",
                        "driver_questionnaire_question": {
                          "type": "CHECKBOX",
                          "question": "Checkbox Question?"
                        },
                        "images": []
                      },
                      {
                        "id": 4029,
                        "type": "TEXT",
                        "data": "Depot",
                        "driver_questionnaire_question": {
                          "type": "TEXT",
                          "question": "What is the starting location?"
                        },
                        "images": []
                      },
                      {
                        "id": 4030,
                        "type": "SELECT",
                        "data": "1",
                        "driver_questionnaire_question": {
                          "type": "SELECT",
                          "question": "Select an option?"
                        },
                        "images": []
                      },
                      {
                        "id": 4031,
                        "type": "MULTI_SELECT",
                        "data": "1",
                        "driver_questionnaire_question": {
                          "type": "MULTI_SELECT",
                          "question": "Select all that applies?"
                        },
                        "images": []
                      },
                      {
                        "id": 4032,
                        "type": "MULTI_SELECT",
                        "data": "3",
                        "driver_questionnaire_question": {
                          "type": "MULTI_SELECT",
                          "question": "Select all that applies?"
                        },
                        "images": []
                      },
                      {
                        "id": 4033,
                        "type": "MULTI_SELECT",
                        "data": "2",
                        "driver_questionnaire_question": {
                          "type": "MULTI_SELECT",
                          "question": "Select all that applies?"
                        },
                        "images": []
                      },
                      {
                        "id": 4034,
                        "type": "SIGNATURE",
                        "data": "90e4486d-dfcf-4007-90d7-7a169b5c89c0",
                        "driver_questionnaire_question": {
                          "type": "SIGNATURE",
                          "question": "Did you get a signature?"
                        },
                        "images": [
                          "https://api.smartroutes.io/v2/driver-questionnaire-submission-images/1034"
                        ]
                      },
                      {
                        "id": 4035,
                        "type": "PHOTO",
                        "data": "f6c356a0-4622-468c-a6c0-78f11446fd09",
                        "driver_questionnaire_question": {
                          "type": "PHOTO",
                          "question": "Uploaded the photo? "
                        },
                        "images": [
                          "https://api.smartroutes.io/v2/driver-questionnaire-submission-images/1035"
                        ]
                      }
                    ]
                  }
                }
              }
            }
          },
          "404": { "$ref": "#/components/responses/NotFound" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "500": { "$ref": "#/components/responses/ServerError" }
        }
      }
    },
    "/proof-of-delivery/photos/{id}": {
      "get": {
        "summary": "Get Proof of Delivery Photo",
        "operationId": "getProofOfDeliveryPhotoById",
        "description": "Retrieve a proof-of-delivery photo by its ID. By default returns the raw image binary. Use the `encoding` query parameter to request a Base64-encoded JSON response instead.",
        "tags": [
          "Proof of Delivery"
        ],
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "integer",
              "description": "The ID of the photo to retrieve."
            },
            "description": "The ID of the photo to retrieve."
          },
          {
            "in": "query",
            "name": "encoding",
            "required": false,
            "schema": {
              "type": "string",
              "enum": ["base64"],
              "description": "Set to `base64` to receive the image as a Base64-encoded string in a JSON response instead of raw binary."
            },
            "description": "Set to `base64` to receive the image as a Base64-encoded string in a JSON response instead of raw binary."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful response. Returns raw image binary by default, or a JSON object when `encoding=base64` is specified.",
            "content": {
              "image/*": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              },
              "application/json": {
                "example": {
                  "data": "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk...",
                  "content_type": "image/jpeg"
                }
              }
            }
          },
          "404": { "$ref": "#/components/responses/NotFound" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "500": { "$ref": "#/components/responses/ServerError" }
        }
      }
    },
    "/proof-of-delivery/signatures/{id}": {
      "get": {
        "summary": "Get Proof of Delivery Signature",
        "operationId": "getProofOfDeliverySignatureById",
        "description": "Retrieve a proof-of-delivery signature by its ID. By default returns the raw image binary. Use the `encoding` query parameter to request a Base64-encoded JSON response instead.",
        "tags": [
          "Proof of Delivery"
        ],
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "integer",
              "description": "The ID of the signature to retrieve."
            },
            "description": "The ID of the signature to retrieve."
          },
          {
            "in": "query",
            "name": "encoding",
            "required": false,
            "schema": {
              "type": "string",
              "enum": ["base64"],
              "description": "Set to `base64` to receive the image as a Base64-encoded string in a JSON response instead of raw binary."
            },
            "description": "Set to `base64` to receive the image as a Base64-encoded string in a JSON response instead of raw binary."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful response. Returns raw image binary by default, or a JSON object when `encoding=base64` is specified.",
            "content": {
              "image/*": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              },
              "application/json": {
                "example": {
                  "data": "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk...",
                  "content_type": "image/png"
                }
              }
            }
          },
          "404": { "$ref": "#/components/responses/NotFound" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "500": { "$ref": "#/components/responses/ServerError" }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "ErrorResponse": {
        "type": "object",
        "description": "Standard error envelope. Returned for any non-2xx response (with the exception of legacy endpoints not yet migrated). The shape is flat — no enclosing `error` wrapper.",
        "required": ["name", "statusCode", "description", "details"],
        "properties": {
          "name": {
            "type": "string",
            "description": "Machine-readable error name. Stable string identifier; safe to switch on programmatically.",
            "enum": [
              "INVALID_INPUT",
              "RESOURCE_NOT_FOUND",
              "UNAUTHORIZED",
              "FORBIDDEN",
              "PERMISSION",
              "GONE",
              "SERVICE_UNAVAILABLE",
              "INTERNAL_SERVER_ERROR",
              "INTERNAL_RESOURCE_MISSING",
              "ERROR_WARNING",
              "LATENCY_WARNING",
              "VALIDATION_REQUEST",
              "GEOCODING_FAILED",
              "REDIS_UNAVAILABLE",
              "SEND_ERROR",
              "IDEMPOTENCY_KEY_REUSED_WITH_DIFFERENT_BODY",
              "IDEMPOTENCY_REQUEST_IN_PROGRESS",
              "IDEMPOTENCY_INVALID_KEY"
            ]
          },
          "statusCode": {
            "type": "integer",
            "description": "HTTP status code matching the response status. Legacy camelCase property name; kept for backwards compatibility."
          },
          "description": {
            "type": "string",
            "description": "Human-readable description of the error. For developers; not intended for end-user display."
          },
          "details": {
            "type": "object",
            "additionalProperties": true,
            "description": "Additional structured details about the error. Always an object — never null. May be empty (`{}`). Validation errors populate this with a `validationErrors` array of Zod issues."
          }
        }
      },
      "OrderStatus": {
        "type": "string",
        "description": "Order status, derived from line-item statuses by the status service. Source: `cORDER_STATUS_TYPES` in `src/models/order-status.js`.",
        "enum": [
          "BOOKED",
          "BOOKING_DECLINED",
          "DELIVERED",
          "LOADED",
          "OPEN",
          "PARTIALLY_BOOKED",
          "PARTIALLY_BOOKING_DECLINED",
          "PARTIALLY_DELIVERED",
          "PARTIALLY_LOADED",
          "PARTIALLY_READY_FOR_COLLECTION",
          "PARTIALLY_ROUTED",
          "PARTIALLY_UNDELIVERED",
          "PARTIALLY_WAITING_CONFIRMATION",
          "READY_FOR_COLLECTION",
          "ROUTED",
          "UNDELIVERED",
          "WAITING_CONFIRMATION"
        ]
      },
      "LineItemStatus": {
        "type": "string",
        "description": "Per-line-item status. Newly-emitted values are drawn from the same set as `OrderStatus` minus the `PARTIALLY_*` aggregated values (those apply only at the order level). Historical rows may still carry legacy values (`CANCEL`, `COMPLETED`, `DECLINED`, `NOT RECEIVED`, `ON HOLD`, `RETURNED`); these are listed for backward compatibility but are no longer written by current SR code.",
        "enum": [
          "BOOKED",
          "BOOKING_DECLINED",
          "CANCEL",
          "COMPLETED",
          "DECLINED",
          "DELIVERED",
          "LOADED",
          "NOT RECEIVED",
          "ON HOLD",
          "OPEN",
          "READY_FOR_COLLECTION",
          "RETURNED",
          "ROUTED",
          "UNDELIVERED",
          "WAITING_CONFIRMATION"
        ]
      },
      "Customer": {
        "type": "object",
        "nullable": true,
        "description": "Trimmed customer reference embedded in Order responses. May be `null` for orders without a customer association.",
        "properties": {
          "id": { "type": "integer", "nullable": true },
          "account": { "type": "string", "nullable": true }
        }
      },
      "CustomField": {
        "type": "object",
        "properties": {
          "id": { "type": "integer" },
          "name": { "type": "string" },
          "value": { "description": "Field value. Type varies by field definition (string, number, or boolean)." }
        }
      },
      "Capacity": {
        "type": "object",
        "properties": {
          "id": { "type": "integer" },
          "type": { "type": "string" },
          "capacity": { "type": "number" }
        }
      },
      "TimeWindow": {
        "type": "object",
        "properties": {
          "from": { "type": "string", "description": "HH:mm:ss" },
          "to": { "type": "string", "description": "HH:mm:ss" },
          "type": { "type": "string" }
        }
      },
      "LineItem": {
        "type": "object",
        "properties": {
          "product_name": { "type": "string" },
          "product_code": { "type": "string" },
          "product_quantity": { "type": "integer" },
          "capacities": { "type": "array", "items": { "$ref": "#/components/schemas/Capacity" } },
          "status": {
            "allOf": [{ "$ref": "#/components/schemas/LineItemStatus" }],
            "nullable": true
          },
          "date": { "type": "string", "format": "date", "nullable": true },
          "custom_fields": { "type": "array", "items": { "$ref": "#/components/schemas/CustomField" } }
        }
      },
      "DriverQuestionnaireSubmission": {
        "type": "object",
        "properties": {
          "id": { "type": "integer" },
          "driver_questionnaire": {
            "type": "object",
            "properties": {
              "type": { "type": "string" },
              "title": { "type": "string" }
            }
          }
        }
      },
      "VehicleRef": {
        "type": "object",
        "description": "Trimmed vehicle reference embedded in Route responses.",
        "properties": {
          "vehicle_id": { "type": "integer" },
          "name": { "type": "string" },
          "driver": { "type": "string", "nullable": true }
        }
      },
      "Stop": {
        "type": "object",
        "description": "A planned or completed stop on a route. POD-related fields populate as the stop is completed.",
        "properties": {
          "id": { "type": "integer" },
          "route_id": { "type": "integer" },
          "address": { "type": "string" },
          "postcode": { "type": "string" },
          "phone": { "type": "string", "nullable": true },
          "lat": { "type": "number" },
          "lng": { "type": "number" },
          "planned_distance": { "type": "number" },
          "arrival_date": { "type": "string", "format": "date" },
          "departure_date": { "type": "string", "format": "date" },
          "estimated_arrival_time": { "type": "string", "description": "HH:mm or HH:mm:ss" },
          "estimated_departure_time": { "type": "string", "description": "HH:mm or HH:mm:ss" },
          "actual_completed_ts": { "type": "string", "format": "date-time", "nullable": true },
          "actual_completed_lat": { "type": "number", "nullable": true },
          "actual_completed_lng": { "type": "number", "nullable": true },
          "delivery_notes": { "type": "string", "nullable": true },
          "driver_notes": { "type": "string", "nullable": true },
          "actual_arrival_time": { "type": "string", "nullable": true },
          "actual_duration": { "type": "number", "nullable": true },
          "signature": { "type": "string", "format": "uri", "nullable": true },
          "signature_lat": { "type": "number", "nullable": true },
          "signature_lng": { "type": "number", "nullable": true },
          "signed_by": { "type": "string", "nullable": true },
          "photos": { "type": "array", "items": { "type": "string", "format": "uri" }, "nullable": true },
          "tracking_link": { "type": "string", "format": "uri", "nullable": true },
          "vehicle_assignment": {
            "type": "object",
            "nullable": true,
            "properties": { "vehicle_id": { "type": "integer" } }
          },
          "directions": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": { "instruction": { "type": "string" } }
            }
          },
          "driver_questionnaire_submissions": {
            "type": "array",
            "items": { "$ref": "#/components/schemas/DriverQuestionnaireSubmission" }
          },
          "failed_reason": {
            "type": "object",
            "nullable": true,
            "properties": { "reason": { "type": "string" } }
          },
          "tags": { "type": "array", "items": { "type": "string" } },
          "available_days": { "type": "array", "items": { "type": "integer" } },
          "orders": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": { "type": "integer" },
                "order_number": { "type": "string" },
                "custom_fields": {
                  "type": "array",
                  "items": { "$ref": "#/components/schemas/CustomField" },
                  "nullable": true
                },
                "line_items": { "type": "array", "items": { "$ref": "#/components/schemas/LineItem" } },
                "type": { "type": "string" }
              }
            }
          },
          "emails": {
            "type": "array",
            "nullable": true,
            "items": {
              "type": "object",
              "properties": { "email": { "type": "string" } }
            }
          },
          "route": {
            "type": "object",
            "properties": {
              "id": { "type": "integer" },
              "date": { "type": "string", "format": "date" },
              "started_ts": { "type": "string", "format": "date-time", "nullable": true }
            }
          }
        }
      },
      "Order": {
        "type": "object",
        "description": "An order. Property set is the union of fields returned by list and get-by-id paths; individual endpoints may return a subset.",
        "properties": {
          "id": { "type": "integer" },
          "order_number": { "type": "string" },
          "type": { "type": "string" },
          "status": { "$ref": "#/components/schemas/OrderStatus" },
          "priority": { "type": "string", "nullable": true, "description": "LOW, MEDIUM, HIGH, or null." },
          "parts": { "type": "integer", "nullable": true },
          "delivery_address": { "type": "string" },
          "delivery_lat": { "type": "number" },
          "delivery_lng": { "type": "number" },
          "delivery_notes": { "type": "string", "nullable": true },
          "delivery_available_days": { "type": "array", "items": { "type": "integer" } },
          "delivery_duration": { "type": "number" },
          "delivery_date": { "type": "string", "format": "date", "nullable": true },
          "delivery_contact_name": { "type": "string", "nullable": true },
          "delivery_contact_number": { "type": "string", "nullable": true },
          "delivery_contact_email": { "type": "string", "nullable": true },
          "pickup_address": { "type": "string", "nullable": true },
          "pickup_duration": { "type": "number", "nullable": true },
          "pickup_lat": { "type": "number", "nullable": true },
          "pickup_lng": { "type": "number", "nullable": true },
          "pickup_notes": { "type": "string", "nullable": true },
          "pickup_contact_name": { "type": "string", "nullable": true },
          "pickup_contact_number": { "type": "string", "nullable": true },
          "pickup_contact_email": { "type": "string", "nullable": true },
          "pickup_available_days": { "type": "array", "items": { "type": "integer" } },
          "customer": { "$ref": "#/components/schemas/Customer" },
          "capacities": { "type": "array", "items": { "$ref": "#/components/schemas/Capacity" } },
          "custom_fields": { "type": "array", "items": { "$ref": "#/components/schemas/CustomField" } },
          "time_windows": { "type": "array", "items": { "$ref": "#/components/schemas/TimeWindow" } },
          "skills": { "type": "array", "items": { "type": "string" } },
          "attachments": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": { "type": "integer" },
                "name": { "type": "string" }
              }
            }
          },
          "vehicle_assignment": {
            "type": "array",
            "nullable": true,
            "items": {
              "type": "object",
              "properties": { "vehicle_id": { "type": "integer" } }
            }
          },
          "emails": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": { "email": { "type": "string" } }
            }
          },
          "third_party": {
            "type": "object",
            "properties": { "id": { "type": "integer", "nullable": true } }
          },
          "tags": { "type": "array", "items": { "type": "string" } },
          "stops": { "type": "array", "items": { "$ref": "#/components/schemas/Stop" } },
          "line_items": { "type": "array", "items": { "$ref": "#/components/schemas/LineItem" } },
          "created": { "type": "string", "format": "date-time" },
          "updated": { "type": "string", "format": "date-time" }
        }
      },
      "Route": {
        "type": "object",
        "description": "A route belonging to a plan.",
        "properties": {
          "id": { "type": "integer" },
          "plan_id": { "type": "integer" },
          "name": { "type": "string" },
          "dispatched": { "type": "boolean" },
          "date": { "type": "string", "format": "date" },
          "start_time": { "type": "string", "description": "HH:mm:ss" },
          "end_time": { "type": "string", "description": "HH:mm:ss" },
          "started_ts": { "type": "string", "format": "date-time", "nullable": true },
          "completed_ts": { "type": "string", "format": "date-time", "nullable": true },
          "total_time": { "type": "number" },
          "travel_time": { "type": "number" },
          "planned_distance": { "type": "number" },
          "actual_distance": { "type": "number", "nullable": true },
          "vehicle": { "$ref": "#/components/schemas/VehicleRef" },
          "stops": { "type": "array", "items": { "$ref": "#/components/schemas/Stop" } },
          "driver_questionnaire_submissions": {
            "type": "array",
            "items": { "$ref": "#/components/schemas/DriverQuestionnaireSubmission" }
          },
          "created": { "type": "string", "format": "date-time" },
          "updated": { "type": "string", "format": "date-time" }
        }
      },
      "Plan": {
        "type": "object",
        "description": "A VRP plan. When no solution has been computed yet, `routes` and `unserved` are empty arrays — see the async optimise endpoint description for polling guidance.",
        "properties": {
          "id": { "type": "integer" },
          "total_time": { "type": "number" },
          "dispatched": { "type": "boolean", "nullable": true },
          "routes": { "type": "array", "items": { "$ref": "#/components/schemas/Route" } },
          "unserved": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": { "type": "integer" },
                "address": { "type": "string" },
                "postcode": { "type": "string" },
                "phone": { "type": "string" },
                "lat": { "type": "number" },
                "lng": { "type": "number" },
                "delivery_notes": { "type": "string" },
                "reference_id": { "type": "string" },
                "available_days": { "type": "array", "items": { "type": "integer" } }
              }
            }
          },
          "created": { "type": "string", "format": "date-time" },
          "updated": { "type": "string", "format": "date-time" }
        }
      },
      "BookingAvailabilityResponse": {
        "type": "object",
        "required": ["booking"],
        "properties": {
          "booking": {
            "type": "object",
            "required": ["available"],
            "properties": {
              "available": { "type": "boolean" }
            }
          }
        }
      },
      "OrdersListResponse": {
        "type": "object",
        "required": ["orders"],
        "properties": {
          "orders": {
            "type": "array",
            "items": { "$ref": "#/components/schemas/Order" }
          }
        }
      },
      "OrderResponse": {
        "type": "object",
        "required": ["order"],
        "properties": {
          "order": { "$ref": "#/components/schemas/Order" }
        }
      },
      "PlanOptimisationResponse": {
        "type": "object",
        "required": ["optimisation", "plan"],
        "properties": {
          "optimisation": {
            "type": "object",
            "required": ["id", "in_progress"],
            "properties": {
              "id": { "type": "string", "format": "uuid" },
              "in_progress": { "type": "boolean" }
            }
          },
          "plan": {
            "type": "object",
            "required": ["id", "dispatched"],
            "properties": {
              "id": { "type": "integer" },
              "dispatched": { "type": "boolean" }
            }
          }
        }
      },
      "PlanResponse": {
        "type": "object",
        "required": ["plan"],
        "properties": {
          "plan": { "$ref": "#/components/schemas/Plan" }
        }
      },
      "RouteResponse": {
        "type": "object",
        "required": ["route"],
        "properties": {
          "route": { "$ref": "#/components/schemas/Route" }
        }
      },
      "Vehicle": {
        "type": "object",
        "description": "A depot vehicle. Property set is the union of fields returned by list and get-by-id paths; conditional fields (shift_*, start_address/lat/lng, end_address/lat/lng, break_*) populate only when the corresponding mode is selected. Source of truth: `getExternalModel` in `src/vehicles/vehicles.service.js`.",
        "properties": {
          "id":             { "type": "integer" },
          "name":           { "type": "string" },
          "active":         { "type": "boolean" },
          "availability":   { "type": "string", "enum": ["shift", "full_day", "always"] },
          "start_location": { "type": "string", "enum": ["depot", "other", "app-location"] },
          "end_location":   { "type": "string", "enum": ["depot", "other", "none"] },
          "capacities":     {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id":       { "type": "integer" },
                "type":     { "type": "string" },
                "capacity": { "type": "number" }
              }
            }
          },
          "skills": { "type": "array", "items": { "type": "string" } },
          "shift": {
            "type": "array",
            "description": "Weekly shift schedule. Each entry is one row of vehicle_shifts (enabled, availability, shift_start, shift_end, force_shift_start, max_route_duration, day_of_week) plus a nested vehicle_breaks array.",
            "items": {
              "type": "object",
              "properties": {
                "enabled":            { "type": "boolean" },
                "availability":       { "type": "string", "enum": ["shift", "full_day", "always"] },
                "shift_start":        { "type": "string", "nullable": true, "description": "HH:mm." },
                "shift_end":          { "type": "string", "nullable": true, "description": "HH:mm." },
                "force_shift_start":  { "type": "boolean" },
                "max_route_duration": { "type": "integer", "nullable": true, "description": "Minutes." },
                "day_of_week":        { "type": "string", "enum": ["MONDAY", "TUESDAY", "WEDNESDAY", "THURSDAY", "FRIDAY", "SATURDAY", "SUNDAY"] },
                "vehicle_breaks":     {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "enabled":        { "type": "boolean" },
                      "break_start":    { "type": "string", "nullable": true, "description": "HH:mm." },
                      "break_end":      { "type": "string", "nullable": true, "description": "HH:mm." },
                      "break_duration": { "type": "integer", "nullable": true, "description": "Minutes." }
                    }
                  }
                }
              }
            }
          },
          "created": { "type": "string", "format": "date-time" },
          "updated": { "type": "string", "format": "date-time" },
          "shift_start":    { "type": "string", "nullable": true, "description": "HH:mm. Present when availability == 'shift'." },
          "shift_end":      { "type": "string", "nullable": true, "description": "HH:mm. Present when availability == 'shift'." },
          "start_address":  { "type": "string", "nullable": true, "description": "Present when start_location == 'other'." },
          "start_lat":      { "type": "number", "nullable": true },
          "start_lng":      { "type": "number", "nullable": true },
          "end_address":    { "type": "string", "nullable": true, "description": "Present when end_location == 'other'." },
          "end_lat":        { "type": "number", "nullable": true },
          "end_lng":        { "type": "number", "nullable": true },
          "break":          { "type": "boolean" },
          "break_start":    { "type": "string", "nullable": true, "description": "HH:mm. Present when break == true." },
          "break_end":      { "type": "string", "nullable": true, "description": "HH:mm. Present when break == true." },
          "break_duration": { "type": "number", "nullable": true, "description": "Minutes. Present when break == true." }
        }
      },
      "VehicleResponse": {
        "type": "object",
        "required": ["vehicle"],
        "properties": {
          "vehicle": { "$ref": "#/components/schemas/Vehicle" }
        }
      },
      "VehiclesListResponse": {
        "type": "object",
        "required": ["vehicles"],
        "properties": {
          "vehicles": {
            "type": "array",
            "items": { "$ref": "#/components/schemas/Vehicle" }
          }
        }
      },
      "WebhookEventType": {
        "type": "string",
        "description": "Event type discriminator emitted on every webhook delivery. The integer type-ids (visible in the receiver's depot_settings.webhook_events row) are: ORDERS_STATUS=2, PLANS_CREATED=4, PLANS_DISPATCHED=5, ROUTES_EDITED=6, ROUTES_DELETED=7, ROUTES_COMPLETED=8, PLANS_DELETED=9.",
        "enum": [
          "ORDERS_STATUS",
          "PLANS_CREATED",
          "PLANS_DISPATCHED",
          "ROUTES_EDITED",
          "ROUTES_DELETED",
          "ROUTES_COMPLETED",
          "PLANS_DELETED"
        ]
      },
      "WebhookOrdersStatusPayload": {
        "type": "object",
        "required": ["order_id", "order_number", "status"],
        "description": "ORDERS_STATUS payload. Produced by order-workflow.service.js whenever an order's status changes.",
        "properties": {
          "order_id":     { "type": "integer", "description": "Internal order id." },
          "order_number": { "type": "string",  "description": "User-facing order number." },
          "status":       { "$ref": "#/components/schemas/OrderStatus" }
        }
      },
      "WebhookPlanIdPayload": {
        "type": "object",
        "required": ["id"],
        "description": "Payload for PLANS_CREATED / PLANS_DISPATCHED / PLANS_DELETED. Carries only the plan id.",
        "properties": {
          "id": { "type": "integer", "description": "Plan id. Fetch with GET /plans/{id}." }
        }
      },
      "WebhookRouteIdPayload": {
        "type": "object",
        "required": ["id"],
        "description": "Payload for ROUTES_EDITED / ROUTES_DELETED / ROUTES_COMPLETED. Carries only the route id.",
        "properties": {
          "id": { "type": "integer", "description": "Route id. Fetch with GET /routes/{id}." }
        }
      },
      "WebhookDelivery": {
        "type": "object",
        "required": ["type", "data"],
        "description": "Wire-shape of every webhook delivery. Always an HTTP POST with Content-Type: application/json and an HTTP Basic Authorization header. `data` is a single payload object (NOT an array) — bulk operations fan out into one delivery per event.",
        "properties": {
          "type": { "$ref": "#/components/schemas/WebhookEventType" },
          "data": {
            "oneOf": [
              { "$ref": "#/components/schemas/WebhookOrdersStatusPayload" },
              { "$ref": "#/components/schemas/WebhookPlanIdPayload" },
              { "$ref": "#/components/schemas/WebhookRouteIdPayload" }
            ],
            "description": "Per-type payload object. Discriminate on the sibling `type` field to know which payload schema applies."
          }
        }
      }
    },
    "responses": {
      "InvalidInput": {
        "description": "Invalid input. The request body failed validation.",
        "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } }
      },
      "NotFound": {
        "description": "The requested resource was not found.",
        "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } }
      },
      "ServerError": {
        "description": "An unexpected server error occurred.",
        "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } }
      },
      "Forbidden": {
        "description": "Forbidden. Returned for rate-limit exhaustion (`error.name = FORBIDDEN`, with `details.retry_after_seconds` and `Retry-After` header) and permission gate failures (`error.name = PERMISSION`). Inspect `error.name` to disambiguate.",
        "headers": {
          "Retry-After": {
            "schema": { "type": "integer" },
            "description": "Seconds to wait before retrying. Present only when the cause is rate-limit exhaustion."
          }
        },
        "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } }
      },
      "IdempotencyRequestInProgress": {
        "description": "A request with this idempotency key is already in progress. Retry after the period given in the `Retry-After` header.",
        "headers": {
          "Retry-After": {
            "schema": { "type": "integer" },
            "description": "Seconds to wait before retrying."
          }
        },
        "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } }
      },
      "IdempotencyKeyReusedWithDifferentBody": {
        "description": "The same idempotency key was used with a different request body for this endpoint.",
        "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } }
      }
    },
    "parameters": {
      "IdempotencyKeyHeader": {
        "name": "idempotency-key",
        "in": "header",
        "required": false,
        "description": "Optional idempotency key for safe retries. See the Idempotency section of the API description for behaviour. 1–255 characters; UUID recommended.",
        "schema": {
          "type": "string",
          "minLength": 1,
          "maxLength": 255
        }
      }
    },
    "headers": {
      "IdempotencyReplay": {
        "description": "Set to `true` when the response is a cached replay of an earlier request with the same `idempotency-key`. Absent otherwise.",
        "schema": {
          "type": "string",
          "enum": ["true"]
        }
      }
    }
  }
}
