{
  "components": {
    "schemas": {
      "AxleLoad": {
        "properties": {
          "name": {
            "description": "`Axle 1`, `Axle 2`… in the order of `axle_positions`.",
            "type": "string"
          },
          "position": {
            "description": "Axle position from the front of the cargo area.",
            "type": "number",
            "x-unit": "cm"
          },
          "load": {
            "description": "Cargo load on the axle.",
            "type": "number",
            "x-unit": "kg"
          },
          "max": {
            "description": "Configured maximum (0 = none).",
            "type": "number",
            "x-unit": "kg"
          },
          "ok": {
            "description": "`load` ≤ `max` (always `true` without a maximum).",
            "type": "boolean"
          }
        },
        "type": "object"
      },
      "Balance": {
        "properties": {
          "available_credits": {
            "description": "What new jobs can use (subscription + purchased − reserved).",
            "type": "number",
            "x-unit": "credits"
          },
          "subscription_credits": {
            "description": "Monthly subscription credits left (spent first; expire at subscription_expires_at).",
            "type": "number",
            "x-unit": "credits"
          },
          "subscription_expires_at": {
            "description": "When the monthly credits expire (RFC 3339).",
            "type": [
              "string",
              "null"
            ]
          },
          "purchased_credits": {
            "description": "Credits from packs (never expire).",
            "type": "number",
            "x-unit": "credits"
          },
          "reserved_credits": {
            "description": "Held by queued/running jobs.",
            "type": "number",
            "x-unit": "credits"
          }
        },
        "type": "object"
      },
      "CostBreakdown": {
        "properties": {
          "base": {
            "description": "Per-job fee.",
            "type": "number",
            "x-unit": "credits"
          },
          "vehicles": {
            "description": "Per loaded vehicle (not charged for canceled or time_limit_exceeded jobs).",
            "type": "number",
            "x-unit": "credits"
          },
          "compute": {
            "description": "Per compute-second, pro-rated per millisecond.",
            "type": "number",
            "x-unit": "credits"
          },
          "large_load": {
            "description": "Surcharge per started 100 items above the large-load threshold.",
            "type": "number",
            "x-unit": "credits"
          }
        },
        "type": "object"
      },
      "CostRange": {
        "properties": {
          "min_credits": {
            "description": "Lowest plausible price (fewest vehicles, no compute).",
            "type": "number",
            "x-unit": "credits"
          },
          "max_credits": {
            "description": "Worst case: max_vehicles loaded and the full compute budget used. This is what POST /v1/pack reserves.",
            "type": "number",
            "x-unit": "credits"
          }
        },
        "type": "object"
      },
      "Deleted": {
        "description": "Answer to a DELETE.",
        "properties": {
          "id": {
            "type": "string"
          },
          "object": {
            "enum": [
              "vehicle",
              "template",
              "project"
            ],
            "type": "string"
          },
          "deleted": {
            "description": "Always `true`.",
            "type": "boolean"
          }
        },
        "type": "object"
      },
      "Error": {
        "description": "Every non-2xx /v1 response.",
        "properties": {
          "error": {
            "$ref": "#/components/schemas/ErrorBody"
          }
        },
        "required": [
          "error"
        ],
        "type": "object"
      },
      "ErrorBody": {
        "properties": {
          "code": {
            "description": "Machine code (snake_case). Branch on this, never on `message`.",
            "type": "string"
          },
          "message": {
            "description": "English explanation.",
            "type": "string"
          },
          "request_id": {
            "description": "Same as the X-Request-Id header. Quote it when contacting support.",
            "type": "string"
          },
          "details": {
            "description": "Per-field problems (`validation_failed`).",
            "items": {
              "$ref": "#/components/schemas/ErrorDetail"
            },
            "type": "array"
          }
        },
        "required": [
          "code",
          "message",
          "request_id"
        ],
        "type": "object"
      },
      "ErrorDetail": {
        "properties": {
          "path": {
            "description": "JSON path of the offending field, e.g. items[3].length.",
            "type": "string"
          },
          "code": {
            "description": "`required`, `invalid_value`, `out_of_range`, `duplicate_id`, `unknown_vehicle`, `unknown_template`, `type_not_allowed`, `unknown_group`, `does_not_fit`, `too_many_items`, `too_many_vehicles`, `unknown_field`, `invalid_json`.",
            "type": "string"
          },
          "message": {
            "description": "English explanation.",
            "type": "string"
          }
        },
        "type": "object"
      },
      "Estimate": {
        "description": "Free validation + price estimate of a `PackRequest`.",
        "properties": {
          "valid": {
            "description": "The request would be accepted by POST /v1/pack.",
            "type": "boolean"
          },
          "errors": {
            "description": "Validation errors (empty when valid).",
            "items": {
              "$ref": "#/components/schemas/ErrorDetail"
            },
            "type": "array"
          },
          "warnings": {
            "description": "Non-blocking remarks.",
            "items": {
              "$ref": "#/components/schemas/Warning"
            },
            "type": "array"
          },
          "items": {
            "description": "Total item units.",
            "type": "integer"
          },
          "max_vehicles": {
            "description": "Most vehicles the job may load.",
            "type": "integer"
          },
          "estimated_cost": {
            "$ref": "#/components/schemas/CostRange",
            "description": "Price range in credits."
          },
          "estimated_seconds": {
            "description": "Compute budget the job would get (an upper bound; most jobs finish sooner).",
            "type": "number",
            "x-unit": "s"
          },
          "balance": {
            "$ref": "#/components/schemas/EstimateBalance",
            "description": "Your available credits."
          }
        },
        "type": "object"
      },
      "EstimateBalance": {
        "properties": {
          "available_credits": {
            "type": "number",
            "x-unit": "credits"
          }
        },
        "type": "object"
      },
      "Group": {
        "description": "A group of items (a customer, a stop, an order). With group routing, group order decides the loading sequence: order 1 is loaded first (deepest, at the front wall), the highest order last (at the door). Items without a group go last.",
        "properties": {
          "name": {
            "description": "Group name, referenced by Item.group.",
            "maxLength": 128,
            "type": "string"
          },
          "order": {
            "description": "Loading order (lower = loaded first). Defaults to the position in the list.",
            "type": "integer"
          },
          "color": {
            "description": "Display colour as #rrggbb.",
            "type": "string"
          }
        },
        "required": [
          "name"
        ],
        "type": "object"
      },
      "Item": {
        "description": "An item definition (one SKU / package type). `quantity` identical units are loaded; each unit is reported as one placement with an `instance` number. Name a saved template with `template_id` and send only what differs.",
        "properties": {
          "id": {
            "description": "Your identifier, unique within the request. Results refer to it as item_id. Defaults to template_id.",
            "maxLength": 128,
            "type": "string"
          },
          "template_id": {
            "description": "A template id (tpl_…) from GET /v1/templates. Supplies every item field; fields sent next to it override them.",
            "type": "string"
          },
          "label": {
            "description": "Display label (defaults to the id).",
            "maxLength": 255,
            "type": "string"
          },
          "shape": {
            "default": "box",
            "description": "Item shape. `cylinder` and `drum` use `radius` + `height` instead of `length` + `width`; `pallet` and `drum` always stay upright.",
            "enum": [
              "box",
              "cylinder",
              "pallet",
              "bag",
              "drum"
            ],
            "type": "string"
          },
          "length": {
            "description": "Length. Required unless `shape` is `cylinder` or `drum`.",
            "type": "number",
            "x-unit": "cm"
          },
          "width": {
            "description": "Width. Required unless `shape` is `cylinder` or `drum`.",
            "type": "number",
            "x-unit": "cm"
          },
          "height": {
            "description": "Height (the vertical side when the item stands as defined).",
            "type": "number",
            "x-unit": "cm"
          },
          "radius": {
            "description": "Radius. Required when `shape` is `cylinder` or `drum`.",
            "type": "number",
            "x-unit": "cm"
          },
          "weight": {
            "description": "Weight of ONE unit.",
            "type": "number",
            "x-unit": "kg"
          },
          "quantity": {
            "default": 1,
            "description": "Number of identical units.",
            "maximum": 10000,
            "minimum": 1,
            "type": "integer"
          },
          "stackable": {
            "default": true,
            "description": "Other items may be placed on top of this one.",
            "type": "boolean"
          },
          "max_stack_weight": {
            "default": 0,
            "description": "Maximum weight that may rest on one unit. 0 = unlimited.",
            "type": "number",
            "x-unit": "kg"
          },
          "rotation": {
            "default": "all",
            "description": "`all` = any of the six orientations; `upright` = may only turn around the vertical axis (this side up); `fixed` = never rotated.",
            "enum": [
              "all",
              "upright",
              "fixed"
            ],
            "type": "string"
          },
          "hazardous": {
            "default": false,
            "description": "Dangerous goods: kept low and separated from other hazardous items.",
            "type": "boolean"
          },
          "priority": {
            "default": 0,
            "description": "Load priority. Higher = loaded first and kept when space runs out. 0 = none.",
            "minimum": 0,
            "type": "integer"
          },
          "group": {
            "description": "Name of the group this item belongs to (see `groups` and `options.group_routing`).",
            "type": "string"
          },
          "color": {
            "description": "Display colour as #rrggbb (viewer and PDF only).",
            "type": "string"
          },
          "nesting_height": {
            "default": 0,
            "description": "Telescoping overlap when identical units stack (nested crates, buckets).",
            "type": "number",
            "x-unit": "cm"
          }
        },
        "required": [
          "height",
          "weight"
        ],
        "type": "object"
      },
      "Job": {
        "description": "A packing job. Created by POST /v1/pack; poll GET /v1/jobs/{id} until `status` is `succeeded`, `failed` or `canceled`.",
        "properties": {
          "id": {
            "description": "Job id (job_…).",
            "type": "string"
          },
          "object": {
            "description": "Always `job`.",
            "enum": [
              "job"
            ],
            "type": "string"
          },
          "status": {
            "description": "`queued` → `running` → `succeeded` | `failed` | `canceled`.",
            "enum": [
              "queued",
              "running",
              "succeeded",
              "failed",
              "canceled"
            ],
            "type": "string"
          },
          "reference": {
            "description": "Your reference from the request.",
            "type": "string"
          },
          "source": {
            "description": "Where the job was created.",
            "enum": [
              "api",
              "playground"
            ],
            "type": "string"
          },
          "project_id": {
            "description": "The project (prj_…) a POST /v1/projects/{id}/pack job saves its plan into. Absent on other jobs.",
            "type": "string"
          },
          "created_at": {
            "description": "RFC 3339 timestamp.",
            "type": "string"
          },
          "started_at": {
            "description": "When computing started (RFC 3339) or `null`.",
            "type": [
              "string",
              "null"
            ]
          },
          "finished_at": {
            "description": "When the job ended (RFC 3339) or `null`.",
            "type": [
              "string",
              "null"
            ]
          },
          "progress": {
            "$ref": "#/components/schemas/JobProgress",
            "description": "Live progress while queued/running."
          },
          "summary": {
            "$ref": "#/components/schemas/JobSummary",
            "description": "Counts and timings."
          },
          "cost": {
            "$ref": "#/components/schemas/JobCost",
            "description": "Credits charged (final once the job ended) and the reservation held while it ran."
          },
          "error": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/JobError"
              },
              {
                "type": "null"
              }
            ],
            "description": "Why the job failed or was canceled; `null` otherwise."
          },
          "warnings": {
            "description": "Non-blocking remarks about the request (also repeated in the result).",
            "items": {
              "$ref": "#/components/schemas/Warning"
            },
            "type": "array"
          },
          "result_url": {
            "description": "GET this URL for the full result once `status` is `succeeded`.",
            "type": "string"
          },
          "pdf_url": {
            "description": "A browser link that renders the load plan as a PDF (3D views + loading steps). Valid until expires_at. Empty after expiry.",
            "type": "string"
          },
          "expires_at": {
            "description": "When the request/result bodies and the PDF link are deleted (RFC 3339). Job metadata and charges are kept.",
            "type": "string"
          },
          "result": {
            "$ref": "#/components/schemas/Result",
            "description": "The full result, inlined only when requested (?include=result) or when POST /v1/pack?wait= finished in time."
          }
        },
        "required": [
          "id",
          "object",
          "status",
          "created_at"
        ],
        "type": "object"
      },
      "JobCost": {
        "properties": {
          "credits": {
            "description": "Credits charged (0 until the job ends). Failed jobs are not charged, except time_limit_exceeded, which is charged like a canceled job.",
            "type": "number",
            "x-unit": "credits"
          },
          "reserved_credits": {
            "description": "Credits held while the job was queued/running (the worst-case price). Released when it ends.",
            "type": "number",
            "x-unit": "credits"
          },
          "rate_card_version": {
            "description": "Rate card the job is priced with.",
            "type": "integer"
          },
          "breakdown": {
            "$ref": "#/components/schemas/CostBreakdown",
            "description": "Itemized price."
          }
        },
        "type": "object"
      },
      "JobError": {
        "properties": {
          "code": {
            "description": "Machine code (see Errors).",
            "type": "string"
          },
          "message": {
            "description": "English explanation.",
            "type": "string"
          }
        },
        "type": "object"
      },
      "JobList": {
        "properties": {
          "data": {
            "items": {
              "$ref": "#/components/schemas/Job"
            },
            "type": "array"
          },
          "next_cursor": {
            "description": "Pass as ?cursor= for the next page; empty on the last page.",
            "type": "string"
          }
        },
        "type": "object"
      },
      "JobProgress": {
        "properties": {
          "stage": {
            "description": "Current stage, such as `queued`, `running`, `finalizing` or `done`. Informational: branch on `Job.status`.",
            "type": "string"
          },
          "vehicles_done": {
            "description": "Vehicles packed so far.",
            "type": "integer"
          },
          "placed_items": {
            "description": "Item units placed so far.",
            "type": "integer"
          }
        },
        "type": "object"
      },
      "JobSummary": {
        "properties": {
          "items_requested": {
            "description": "Total item units (sum of quantities).",
            "type": "integer"
          },
          "items_placed": {
            "description": "Units placed.",
            "type": "integer"
          },
          "items_unplaced": {
            "description": "Units that could not be placed.",
            "type": "integer"
          },
          "vehicles_used": {
            "description": "Vehicles that carry at least one item.",
            "type": "integer"
          },
          "total_weight": {
            "description": "Weight loaded.",
            "type": "number",
            "x-unit": "kg"
          },
          "volume_utilization": {
            "description": "Average volume utilization of the used vehicles, 0–1.",
            "type": "number"
          },
          "queue_ms": {
            "description": "Time spent waiting for a compute slot (not billed).",
            "type": "integer"
          },
          "compute_ms": {
            "description": "Compute time (billed).",
            "type": "integer"
          }
        },
        "type": "object"
      },
      "Limits": {
        "description": "Your organization's effective limits and the rate card new jobs are priced with.",
        "properties": {
          "max_items_per_request": {
            "description": "Most item units (sum of quantities) per job.",
            "type": "integer"
          },
          "max_vehicles_per_request": {
            "description": "Most vehicles a job may list and load (auto-added ones included).",
            "type": "integer"
          },
          "max_time_limit_seconds": {
            "description": "Compute budget ceiling per job.",
            "type": "integer"
          },
          "allowed_vehicle_types": {
            "description": "Vehicle types the API accepts.",
            "items": {
              "type": "string"
            },
            "type": "array"
          },
          "concurrency": {
            "description": "Jobs of your organization computing at the same time; more wait in the queue.",
            "type": "integer"
          },
          "max_queued_jobs": {
            "description": "Queued + running jobs per organization.",
            "type": "integer"
          },
          "rate_limits": {
            "$ref": "#/components/schemas/RateLimits",
            "description": "Requests per window, per key and per organization."
          },
          "retention_days": {
            "description": "Days request/result bodies and PDF links are kept.",
            "type": "integer"
          },
          "rate_card": {
            "$ref": "#/components/schemas/RateCard",
            "description": "Prices in credits (1 credit = 1 USD)."
          }
        },
        "type": "object"
      },
      "Options": {
        "description": "Packing options. Every field is optional.",
        "properties": {
          "packing_mode": {
            "default": "auto",
            "description": "`auto` = when the listed vehicles are full, more copies of the most suitable vehicle are added (up to the job's vehicle limit); `fleet_only` = only the listed vehicles are used, anything that does not fit is reported as unplaced.",
            "enum": [
              "auto",
              "fleet_only"
            ],
            "type": "string"
          },
          "group_routing": {
            "default": "none",
            "description": "`none` = groups are informational; `wall` = each group gets its own section of the vehicle; `routing` = groups load in order and a later group may sit on or beside an earlier one but never below it (multi-stop delivery); `no_stack` = groups load in order side by side, never on top of each other.",
            "enum": [
              "none",
              "wall",
              "routing",
              "no_stack"
            ],
            "type": "string"
          },
          "allow_overweight": {
            "default": false,
            "description": "Ignore vehicle payload limits.",
            "type": "boolean"
          },
          "max_stack_items": {
            "default": 0,
            "description": "Maximum items in one stack. 0 = unlimited.",
            "minimum": 0,
            "type": "integer"
          },
          "max_stack_density_kg_m2": {
            "default": 0,
            "description": "Maximum stack weight per floor area. 0 = unlimited.",
            "minimum": 0,
            "type": "number",
            "x-unit": "kg/m²"
          },
          "lock_rotations": {
            "default": false,
            "description": "Keep the first orientation that fits the vehicle height.",
            "type": "boolean"
          },
          "group_identical_bins": {
            "default": false,
            "description": "Treat identical vehicles as one pool.",
            "type": "boolean"
          },
          "time_limit": {
            "default": 0,
            "description": "Upper bound on compute time for the whole job. 0 = automatic (capped at max_time_limit_seconds from GET /v1/limits). When the limit is reached the best plan found so far is returned. You pay only for the compute time actually used.",
            "minimum": 0,
            "type": "number",
            "x-unit": "s"
          },
          "enforce_axle": {
            "default": false,
            "description": "Reject placements that overload an axle group, on vehicles that carry all ten axle-model fields.",
            "type": "boolean",
            "x-feature": "axle_loads"
          }
        },
        "type": "object"
      },
      "PackRequest": {
        "description": "One packing job: the vehicles available, the items to load, optional groups and options. Same body for POST /v1/pack and POST /v1/estimate.",
        "properties": {
          "reference": {
            "description": "Your own reference (order number, shipment id…). Echoed back on the job.",
            "maxLength": 128,
            "type": "string"
          },
          "vehicles": {
            "description": "Vehicle definitions. Each one may have quantity \u003e 1. At least one.",
            "items": {
              "$ref": "#/components/schemas/Vehicle"
            },
            "type": "array"
          },
          "items": {
            "description": "Item definitions. Each one may have quantity \u003e 1. At least one.",
            "items": {
              "$ref": "#/components/schemas/Item"
            },
            "type": "array"
          },
          "groups": {
            "description": "Optional groups (customers, stops, orders). Required for every group an item names when `options.group_routing` is not `\"none\"`; otherwise groups are created from the item group names in order of appearance.",
            "items": {
              "$ref": "#/components/schemas/Group"
            },
            "type": "array"
          },
          "options": {
            "$ref": "#/components/schemas/Options",
            "description": "Packing options. Every field is optional."
          }
        },
        "required": [
          "vehicles",
          "items"
        ],
        "type": "object"
      },
      "Placement": {
        "properties": {
          "item_id": {
            "description": "Your item definition id (for a project job: the item id, item_…).",
            "type": "string"
          },
          "instance": {
            "description": "1-based unit number within that item definition (unique across the whole plan).",
            "type": "integer"
          },
          "label": {
            "description": "Item label.",
            "type": "string"
          },
          "x": {
            "description": "Min-corner position along the length.",
            "type": "number",
            "x-unit": "cm"
          },
          "y": {
            "description": "Min-corner height above the floor.",
            "type": "number",
            "x-unit": "cm"
          },
          "z": {
            "description": "Min-corner position across the width.",
            "type": "number",
            "x-unit": "cm"
          },
          "length": {
            "description": "Size along x as placed.",
            "type": "number",
            "x-unit": "cm"
          },
          "width": {
            "description": "Size along z as placed.",
            "type": "number",
            "x-unit": "cm"
          },
          "height": {
            "description": "Size along y as placed.",
            "type": "number",
            "x-unit": "cm"
          },
          "rotated": {
            "description": "Placed in a different orientation than defined.",
            "type": "boolean"
          },
          "orientation": {
            "description": "Which defined side lies along x, z and y: `lwh` = as defined, `wlh` = turned 90° around the vertical axis, `lhw`, `hwl`, `whl`, `hlw` = tipped onto a side.",
            "type": "string"
          },
          "step": {
            "description": "1-based loading step within the vehicle (load in ascending order).",
            "type": "integer"
          },
          "weight": {
            "description": "Unit weight.",
            "type": "number",
            "x-unit": "kg"
          }
        },
        "type": "object"
      },
      "Point": {
        "properties": {
          "x": {
            "type": "number",
            "x-unit": "cm"
          },
          "y": {
            "type": "number",
            "x-unit": "cm"
          },
          "z": {
            "type": "number",
            "x-unit": "cm"
          }
        },
        "type": "object"
      },
      "Project": {
        "description": "A load plan of your organization: the same project the app opens in its 3D editor.",
        "properties": {
          "id": {
            "description": "Project id (prj_…).",
            "type": "string"
          },
          "object": {
            "enum": [
              "project"
            ],
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "status": {
            "description": "`draft` = never packed or inputs replaced; `calculated` = has a current plan; `stale` = a setting changed since the plan was made.",
            "enum": [
              "draft",
              "calculated",
              "stale",
              "error"
            ],
            "type": "string"
          },
          "item_count": {
            "description": "Item units (sum of quantities).",
            "type": "integer"
          },
          "vehicle_count": {
            "description": "Vehicles (sum of quantities).",
            "type": "integer"
          },
          "app_url": {
            "description": "Opens the project in the app's 3D editor.",
            "type": "string"
          },
          "created_by": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/UserRef"
              },
              {
                "type": "null"
              }
            ],
            "description": "The member who created it (for API calls: the member who created the key). `null` when unknown."
          },
          "updated_by": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/UserRef"
              },
              {
                "type": "null"
              }
            ],
            "description": "The member who last changed it."
          },
          "created_at": {
            "description": "RFC 3339.",
            "type": "string"
          },
          "updated_at": {
            "description": "RFC 3339.",
            "type": "string"
          },
          "options": {
            "$ref": "#/components/schemas/ProjectOptions"
          },
          "vehicles": {
            "items": {
              "$ref": "#/components/schemas/ProjectVehicle"
            },
            "type": "array"
          },
          "items": {
            "description": "Cargo in the /v1/pack Item shape; ids are item_….",
            "items": {
              "$ref": "#/components/schemas/Item"
            },
            "type": "array"
          },
          "groups": {
            "items": {
              "$ref": "#/components/schemas/Group"
            },
            "type": "array"
          },
          "plan": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/ProjectPlan"
              },
              {
                "type": "null"
              }
            ],
            "description": "The current plan; `null` when the project has none."
          }
        },
        "type": "object"
      },
      "ProjectInput": {
        "description": "A new project. Items take the /v1/pack `Item` shape (`template_id` works; `id` is optional and only fills `label`). Groups an item names but the list leaves out are created.",
        "properties": {
          "name": {
            "maxLength": 255,
            "type": "string"
          },
          "vehicles": {
            "description": "Vehicle slots.",
            "items": {
              "$ref": "#/components/schemas/ProjectVehicle"
            },
            "type": "array"
          },
          "items": {
            "description": "Cargo items (at most 500 definitions).",
            "items": {
              "$ref": "#/components/schemas/Item"
            },
            "type": "array"
          },
          "groups": {
            "description": "Groups, with their loading order.",
            "items": {
              "$ref": "#/components/schemas/Group"
            },
            "type": "array"
          },
          "options": {
            "$ref": "#/components/schemas/ProjectOptions"
          }
        },
        "required": [
          "name"
        ],
        "type": "object"
      },
      "ProjectList": {
        "properties": {
          "data": {
            "description": "Newest first.",
            "items": {
              "$ref": "#/components/schemas/ProjectSummary"
            },
            "type": "array"
          },
          "next_cursor": {
            "description": "Pass as ?cursor= for the next page; empty on the last page.",
            "type": "string"
          }
        },
        "type": "object"
      },
      "ProjectOptions": {
        "description": "The pack options a project stores.",
        "properties": {
          "packing_mode": {
            "default": "auto",
            "description": "`auto` = when the listed vehicles are full, more copies of the most suitable vehicle are added (up to the job's vehicle limit); `fleet_only` = only the listed vehicles are used, anything that does not fit is reported as unplaced.",
            "enum": [
              "auto",
              "fleet_only"
            ],
            "type": "string"
          },
          "group_routing": {
            "default": "none",
            "description": "`none` = groups are informational; `wall` = each group gets its own section of the vehicle; `routing` = groups load in order and a later group may sit on or beside an earlier one but never below it (multi-stop delivery); `no_stack` = groups load in order side by side, never on top of each other.",
            "enum": [
              "none",
              "wall",
              "routing",
              "no_stack"
            ],
            "type": "string"
          },
          "allow_overweight": {
            "default": false,
            "description": "Ignore vehicle payload limits.",
            "type": "boolean"
          }
        },
        "type": "object"
      },
      "ProjectPackOptions": {
        "description": "Run options. `packing_mode` and `allow_overweight` default to the project's and are saved to it with the plan; `group_routing` is set on the project (PATCH).",
        "properties": {
          "packing_mode": {
            "description": "`auto` = when the listed vehicles are full, more copies of the most suitable vehicle are added (up to the job's vehicle limit); `fleet_only` = only the listed vehicles are used, anything that does not fit is reported as unplaced.",
            "enum": [
              "auto",
              "fleet_only"
            ],
            "type": "string"
          },
          "allow_overweight": {
            "description": "Ignore vehicle payload limits.",
            "type": "boolean"
          },
          "max_stack_items": {
            "default": 0,
            "description": "Maximum items in one stack. 0 = unlimited.",
            "minimum": 0,
            "type": "integer"
          },
          "max_stack_density_kg_m2": {
            "default": 0,
            "description": "Maximum stack weight per floor area. 0 = unlimited.",
            "minimum": 0,
            "type": "number",
            "x-unit": "kg/m²"
          },
          "lock_rotations": {
            "default": false,
            "description": "Keep the first orientation that fits the vehicle height.",
            "type": "boolean"
          },
          "group_identical_bins": {
            "default": false,
            "description": "Treat identical vehicles as one pool.",
            "type": "boolean"
          },
          "time_limit": {
            "default": 0,
            "description": "Upper bound on compute time for the whole job. 0 = automatic (capped at max_time_limit_seconds from GET /v1/limits). When the limit is reached the best plan found so far is returned. You pay only for the compute time actually used.",
            "minimum": 0,
            "type": "number",
            "x-unit": "s"
          },
          "enforce_axle": {
            "default": false,
            "description": "Reject placements that overload an axle group, on vehicles that carry all ten axle-model fields.",
            "type": "boolean",
            "x-feature": "axle_loads"
          }
        },
        "type": "object"
      },
      "ProjectPackRequest": {
        "description": "Optional body of POST /v1/projects/{id}/pack. The vehicles, items and groups come from the project.",
        "properties": {
          "reference": {
            "description": "Your reference, echoed on the job. Defaults to the project name.",
            "maxLength": 128,
            "type": "string"
          },
          "options": {
            "$ref": "#/components/schemas/ProjectPackOptions",
            "description": "Run options. Every field is optional."
          }
        },
        "type": "object"
      },
      "ProjectPlan": {
        "description": "The project's current load plan, in short (made by the app or by POST /v1/projects/{id}/pack).",
        "properties": {
          "items_placed": {
            "description": "Units placed.",
            "type": "integer"
          },
          "items_unplaced": {
            "description": "Units that could not be placed.",
            "type": "integer"
          },
          "vehicles_used": {
            "description": "Vehicles carrying at least one item.",
            "type": "integer"
          },
          "total_weight": {
            "description": "Weight loaded.",
            "type": "number",
            "x-unit": "kg"
          },
          "volume_utilization": {
            "description": "Average volume utilization of the used vehicles, 0–1.",
            "type": "number"
          },
          "job_id": {
            "description": "The API job whose plan this is, while nothing changed it since. Empty for a plan made or edited in the app.",
            "type": "string"
          },
          "pdf_url": {
            "description": "That job's PDF link (until its expires_at). Empty otherwise.",
            "type": "string"
          }
        },
        "type": "object"
      },
      "ProjectSummary": {
        "description": "A project in a list.",
        "properties": {
          "id": {
            "description": "Project id (prj_…).",
            "type": "string"
          },
          "object": {
            "enum": [
              "project"
            ],
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "status": {
            "description": "`draft` = never packed or inputs replaced; `calculated` = has a current plan; `stale` = a setting changed since the plan was made.",
            "enum": [
              "draft",
              "calculated",
              "stale",
              "error"
            ],
            "type": "string"
          },
          "item_count": {
            "description": "Item units (sum of quantities).",
            "type": "integer"
          },
          "vehicle_count": {
            "description": "Vehicles (sum of quantities).",
            "type": "integer"
          },
          "app_url": {
            "description": "Opens the project in the app's 3D editor.",
            "type": "string"
          },
          "created_by": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/UserRef"
              },
              {
                "type": "null"
              }
            ],
            "description": "The member who created it (for API calls: the member who created the key). `null` when unknown."
          },
          "updated_by": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/UserRef"
              },
              {
                "type": "null"
              }
            ],
            "description": "The member who last changed it."
          },
          "created_at": {
            "description": "RFC 3339.",
            "type": "string"
          },
          "updated_at": {
            "description": "RFC 3339.",
            "type": "string"
          }
        },
        "type": "object"
      },
      "ProjectUpdate": {
        "description": "What to change. `vehicles` replaces every slot; `items` replaces the cargo and the groups (send `groups` only together with `items`); both clear the stored plan. Changed `options` mark a plan `stale`.",
        "properties": {
          "name": {
            "maxLength": 255,
            "type": "string"
          },
          "vehicles": {
            "description": "Vehicle slots.",
            "items": {
              "$ref": "#/components/schemas/ProjectVehicle"
            },
            "type": "array"
          },
          "items": {
            "description": "Cargo items (at most 500 definitions).",
            "items": {
              "$ref": "#/components/schemas/Item"
            },
            "type": "array"
          },
          "groups": {
            "description": "Groups, with their loading order.",
            "items": {
              "$ref": "#/components/schemas/Group"
            },
            "type": "array"
          },
          "options": {
            "$ref": "#/components/schemas/ProjectOptions"
          }
        },
        "type": "object"
      },
      "ProjectVehicle": {
        "description": "A vehicle slot of a project: a saved vehicle, a quantity and the overrides the app's project editor offers. `id`, `name` and `type` are read-only (ignored when sent). `length`, `width`, `height` and `max_weight` show the sizes the slot packs with; sent, they override only where they differ from the saved vehicle.",
        "properties": {
          "id": {
            "description": "Slot id (pv_…). Results of the project's jobs refer to it as vehicle_id. Read-only.",
            "type": "string"
          },
          "vehicle_id": {
            "description": "A vehicle id from GET /v1/vehicles (preset or veh_…).",
            "type": "string"
          },
          "name": {
            "description": "The saved vehicle's name. Read-only.",
            "type": "string"
          },
          "type": {
            "description": "The saved vehicle's type. Read-only.",
            "enum": [
              "truck",
              "trailer",
              "flatbed",
              "container",
              "pallet",
              "aircraft",
              "ship"
            ],
            "type": "string"
          },
          "length": {
            "description": "The size the slot packs with; sent, an override of the saved vehicle's.",
            "minimum": 0,
            "type": "number",
            "x-unit": "cm"
          },
          "width": {
            "description": "The size the slot packs with; sent, an override of the saved vehicle's.",
            "minimum": 0,
            "type": "number",
            "x-unit": "cm"
          },
          "height": {
            "description": "The size the slot packs with; sent, an override of the saved vehicle's.",
            "minimum": 0,
            "type": "number",
            "x-unit": "cm"
          },
          "max_weight": {
            "description": "The size the slot packs with; sent, an override of the saved vehicle's.",
            "minimum": 0,
            "type": "number",
            "x-unit": "kg"
          },
          "quantity": {
            "default": 1,
            "description": "How many identical vehicles of this definition are available.",
            "maximum": 100,
            "minimum": 1,
            "type": "integer"
          },
          "aux_deck": {
            "default": false,
            "description": "The vehicle has a second deck (double-decker).",
            "type": "boolean"
          },
          "aux_deck_height": {
            "description": "Second deck height above the floor. Required when `aux_deck` is `true`.",
            "type": "number",
            "x-unit": "cm"
          },
          "aux_deck_max_weight": {
            "description": "Load limit of the second deck. Required when `aux_deck` is `true`.",
            "type": "number",
            "x-unit": "kg"
          },
          "blocked_areas": {
            "description": "Floor zones nothing may stand on (wheel arches, damage, reserved space). Each must lie on the vehicle floor.",
            "items": {
              "$ref": "#/components/schemas/Rect"
            },
            "maxItems": 32,
            "type": "array"
          },
          "tractor_weight": {
            "description": "Semi-trailer axle model: tractor unit mass.",
            "type": "number",
            "x-feature": "axle_loads",
            "x-unit": "kg"
          },
          "empty_trailer_weight": {
            "description": "Semi-trailer axle model: unladen trailer mass.",
            "type": "number",
            "x-feature": "axle_loads",
            "x-unit": "kg"
          },
          "front_axle_to_middle_axle": {
            "description": "Semi-trailer axle model: tractor front axle to drive (middle) axle.",
            "type": "number",
            "x-feature": "axle_loads",
            "x-unit": "cm"
          },
          "front_axle_to_tractor_cog": {
            "description": "Semi-trailer axle model: front axle to tractor centre of gravity.",
            "type": "number",
            "x-feature": "axle_loads",
            "x-unit": "cm"
          },
          "front_axle_to_kingpin": {
            "description": "Semi-trailer axle model: front axle to kingpin (fifth wheel).",
            "type": "number",
            "x-feature": "axle_loads",
            "x-unit": "cm"
          },
          "kingpin_to_rear_axle": {
            "description": "Semi-trailer axle model: kingpin to trailer rear axle group.",
            "type": "number",
            "x-feature": "axle_loads",
            "x-unit": "cm"
          },
          "trailer_cog_to_rear_axle": {
            "description": "Semi-trailer axle model: trailer centre of gravity to rear axle group.",
            "type": "number",
            "x-feature": "axle_loads",
            "x-unit": "cm"
          },
          "trailer_start_to_kingpin": {
            "description": "Semi-trailer axle model: trailer front to kingpin.",
            "type": "number",
            "x-feature": "axle_loads",
            "x-unit": "cm"
          },
          "max_middle_axle_weight": {
            "description": "Semi-trailer axle model: legal drive (middle) axle limit.",
            "type": "number",
            "x-feature": "axle_loads",
            "x-unit": "kg"
          },
          "max_rear_axle_weight": {
            "description": "Semi-trailer axle model: legal rear axle group limit.",
            "type": "number",
            "x-feature": "axle_loads",
            "x-unit": "kg"
          }
        },
        "required": [
          "vehicle_id"
        ],
        "type": "object"
      },
      "RateCard": {
        "properties": {
          "version": {
            "type": "integer"
          },
          "per_job": {
            "type": "number",
            "x-unit": "credits"
          },
          "per_vehicle": {
            "description": "Per vehicle actually loaded.",
            "type": "number",
            "x-unit": "credits"
          },
          "per_compute_second": {
            "description": "Pro-rated per millisecond.",
            "type": "number",
            "x-unit": "credits"
          },
          "large_load_threshold": {
            "description": "Item units included before the surcharge applies.",
            "type": "integer"
          },
          "per_hundred_items_over": {
            "description": "Per started 100 units above the threshold.",
            "type": "number",
            "x-unit": "credits"
          }
        },
        "type": "object"
      },
      "RateLimits": {
        "properties": {
          "per_minute": {
            "type": "integer"
          },
          "per_hour": {
            "type": "integer"
          },
          "per_day": {
            "type": "integer"
          }
        },
        "type": "object"
      },
      "Rect": {
        "description": "A rectangle on the vehicle floor (min-corner origin).",
        "properties": {
          "x": {
            "description": "Distance from the front wall to the rectangle's near edge.",
            "type": "number",
            "x-unit": "cm"
          },
          "z": {
            "description": "Distance from the right wall (z = 0; right as seen from the door looking in) to the rectangle's near edge.",
            "type": "number",
            "x-unit": "cm"
          },
          "length": {
            "description": "Extent along x.",
            "type": "number",
            "x-unit": "cm"
          },
          "width": {
            "description": "Extent along z.",
            "type": "number",
            "x-unit": "cm"
          }
        },
        "required": [
          "x",
          "z",
          "length",
          "width"
        ],
        "type": "object"
      },
      "Result": {
        "description": "The load plan. Coordinates are centimetres from the min corner of the cargo space: x along the length (0 = front wall, growing toward the door), y up from the floor, z across the width (0 = the right wall as seen standing at the door looking in, i.e. the driver's right; z grows toward the left wall).",
        "properties": {
          "job_id": {
            "description": "The job.",
            "type": "string"
          },
          "vehicles": {
            "description": "Loaded vehicles in loading order (empty vehicles are left out).",
            "items": {
              "$ref": "#/components/schemas/ResultVehicle"
            },
            "type": "array"
          },
          "unplaced": {
            "description": "Units that could not be placed, with the reason.",
            "items": {
              "$ref": "#/components/schemas/UnplacedItem"
            },
            "type": "array"
          },
          "warnings": {
            "description": "Remarks about the plan.",
            "items": {
              "$ref": "#/components/schemas/Warning"
            },
            "type": "array"
          },
          "pdf_url": {
            "description": "Browser link that renders the plan as a PDF.",
            "type": "string"
          },
          "expires_at": {
            "description": "When this result is deleted (RFC 3339).",
            "type": "string"
          }
        },
        "type": "object"
      },
      "ResultVehicle": {
        "properties": {
          "index": {
            "description": "0-based position in the plan.",
            "type": "integer"
          },
          "vehicle_id": {
            "description": "Your vehicle definition id (for a project job: the slot id, pv_…).",
            "type": "string"
          },
          "copy": {
            "description": "1-based copy number of that definition (quantity \u003e 1, or added in auto mode).",
            "type": "integer"
          },
          "auto_added": {
            "description": "Added by `packing_mode` `auto` beyond the `quantity` you listed.",
            "type": "boolean"
          },
          "name": {
            "description": "Vehicle name.",
            "type": "string"
          },
          "type": {
            "description": "Vehicle type.",
            "type": "string"
          },
          "length": {
            "description": "Cargo-space length.",
            "type": "number",
            "x-unit": "cm"
          },
          "width": {
            "description": "Cargo-space width.",
            "type": "number",
            "x-unit": "cm"
          },
          "height": {
            "description": "Cargo-space height.",
            "type": "number",
            "x-unit": "cm"
          },
          "max_weight": {
            "description": "Payload limit.",
            "type": "number",
            "x-unit": "kg"
          },
          "items_placed": {
            "description": "Units in this vehicle.",
            "type": "integer"
          },
          "total_weight": {
            "description": "Weight in this vehicle.",
            "type": "number",
            "x-unit": "kg"
          },
          "volume_utilization": {
            "description": "Used volume / cargo-space volume, 0–1.",
            "type": "number"
          },
          "weight_utilization": {
            "description": "total_weight / max_weight, 0–1 (may exceed 1 with allow_overweight).",
            "type": "number"
          },
          "center_of_gravity": {
            "$ref": "#/components/schemas/Point",
            "description": "Centre of gravity of the load (cm)."
          },
          "placements": {
            "description": "Every unit in this vehicle.",
            "items": {
              "$ref": "#/components/schemas/Placement"
            },
            "type": "array"
          },
          "axle_loads": {
            "description": "Load per axle (vehicles with axle data only).",
            "items": {
              "$ref": "#/components/schemas/AxleLoad"
            },
            "type": "array",
            "x-feature": "axle_loads"
          }
        },
        "type": "object"
      },
      "SavedVehicle": {
        "description": "A vehicle your organization can name with `vehicle_id`: a preset (`kind` `preset`, read-only) or one of your own (`kind` `custom`, `veh_…`). Your own vehicles are the fleet the app shows.",
        "properties": {
          "id": {
            "description": "Preset id, or veh_… for your own vehicles.",
            "type": "string"
          },
          "object": {
            "enum": [
              "vehicle"
            ],
            "type": "string"
          },
          "kind": {
            "description": "`preset` = the predefined catalogue; `custom` = your organization's.",
            "enum": [
              "preset",
              "custom"
            ],
            "type": "string"
          },
          "type": {
            "description": "Vehicle type. Only the types listed in GET /v1/limits (allowed_vehicle_types) are accepted.",
            "enum": [
              "truck",
              "trailer",
              "flatbed",
              "container",
              "pallet",
              "aircraft",
              "ship"
            ],
            "type": "string"
          },
          "name": {
            "description": "Display name.",
            "type": "string"
          },
          "length": {
            "description": "Internal cargo-space length, along x (from the front wall toward the door).",
            "type": "number",
            "x-unit": "cm"
          },
          "width": {
            "description": "Internal cargo-space width, along z.",
            "type": "number",
            "x-unit": "cm"
          },
          "height": {
            "description": "Internal cargo-space height, along y.",
            "type": "number",
            "x-unit": "cm"
          },
          "max_weight": {
            "description": "Maximum payload.",
            "type": "number",
            "x-unit": "kg"
          },
          "floor_load_capacity": {
            "description": "Floor load capacity: 0 or more (0 = no limit).",
            "type": [
              "number",
              "null"
            ],
            "x-unit": "kg/m²"
          },
          "axle_positions": {
            "description": "Axle (support point) positions measured from the front of the cargo area; negative = in front of it. Same length as axle_max_loads. Each between −300 (an axle ahead of the cargo area, e.g. a rigid truck's front axle under the cab) and the vehicle length.",
            "items": {
              "type": "number"
            },
            "type": "array",
            "x-unit": "cm"
          },
          "axle_max_loads": {
            "description": "Maximum cargo load per axle, in the order of axle_positions. Each greater than 0 and at most 100000.",
            "items": {
              "type": "number"
            },
            "type": "array",
            "x-unit": "kg"
          },
          "cog_range_x": {
            "description": "Allowed centre-of-gravity deviation from the middle of the length: 0 to length / 2.",
            "type": [
              "number",
              "null"
            ],
            "x-unit": "cm"
          },
          "cog_range_y": {
            "description": "Allowed centre-of-gravity deviation from the middle of the width: 0 to width / 2.",
            "type": [
              "number",
              "null"
            ],
            "x-unit": "cm"
          },
          "aux_deck": {
            "description": "The vehicle has a second deck (double-decker).",
            "type": "boolean"
          },
          "aux_deck_height": {
            "description": "Second deck height above the floor. Required when `aux_deck` is `true`.",
            "type": [
              "number",
              "null"
            ],
            "x-unit": "cm"
          },
          "aux_deck_max_weight": {
            "description": "Load limit of the second deck. Required when `aux_deck` is `true`.",
            "type": [
              "number",
              "null"
            ],
            "x-unit": "kg"
          },
          "tractor_weight": {
            "description": "Semi-trailer axle model: tractor unit mass.",
            "type": [
              "number",
              "null"
            ],
            "x-unit": "kg"
          },
          "empty_trailer_weight": {
            "description": "Semi-trailer axle model: unladen trailer mass.",
            "type": [
              "number",
              "null"
            ],
            "x-unit": "kg"
          },
          "front_axle_to_middle_axle": {
            "description": "Semi-trailer axle model: tractor front axle to drive (middle) axle.",
            "type": [
              "number",
              "null"
            ],
            "x-unit": "cm"
          },
          "front_axle_to_tractor_cog": {
            "description": "Semi-trailer axle model: front axle to tractor centre of gravity.",
            "type": [
              "number",
              "null"
            ],
            "x-unit": "cm"
          },
          "front_axle_to_kingpin": {
            "description": "Semi-trailer axle model: front axle to kingpin (fifth wheel).",
            "type": [
              "number",
              "null"
            ],
            "x-unit": "cm"
          },
          "kingpin_to_rear_axle": {
            "description": "Semi-trailer axle model: kingpin to trailer rear axle group.",
            "type": [
              "number",
              "null"
            ],
            "x-unit": "cm"
          },
          "trailer_cog_to_rear_axle": {
            "description": "Semi-trailer axle model: trailer centre of gravity to rear axle group.",
            "type": [
              "number",
              "null"
            ],
            "x-unit": "cm"
          },
          "trailer_start_to_kingpin": {
            "description": "Semi-trailer axle model: trailer front to kingpin.",
            "type": [
              "number",
              "null"
            ],
            "x-unit": "cm"
          },
          "max_middle_axle_weight": {
            "description": "Semi-trailer axle model: legal drive (middle) axle limit.",
            "type": [
              "number",
              "null"
            ],
            "x-unit": "kg"
          },
          "max_rear_axle_weight": {
            "description": "Semi-trailer axle model: legal rear axle group limit.",
            "type": [
              "number",
              "null"
            ],
            "x-unit": "kg"
          },
          "blocked_areas": {
            "description": "Floor zones nothing may stand on (wheel arches, damage, reserved space). Each must lie on the vehicle floor.",
            "items": {
              "$ref": "#/components/schemas/Rect"
            },
            "type": "array"
          },
          "created_by": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/UserRef"
              },
              {
                "type": "null"
              }
            ],
            "description": "The member who created it (for API calls: the member who created the key). `null` when unknown."
          },
          "updated_by": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/UserRef"
              },
              {
                "type": "null"
              }
            ],
            "description": "The member who last changed it."
          },
          "created_at": {
            "description": "RFC 3339; `null` for presets.",
            "type": [
              "string",
              "null"
            ]
          }
        },
        "type": "object"
      },
      "SavedVehicleList": {
        "properties": {
          "data": {
            "description": "Presets first, then your own vehicles, oldest first.",
            "items": {
              "$ref": "#/components/schemas/SavedVehicle"
            },
            "type": "array"
          },
          "next_cursor": {
            "description": "Pass as ?cursor= for the next page; empty on the last page.",
            "type": "string"
          }
        },
        "type": "object"
      },
      "Template": {
        "description": "A saved item (the app's cargo template). Name it in an item with `template_id`.",
        "properties": {
          "id": {
            "description": "Template id (tpl_…).",
            "type": "string"
          },
          "object": {
            "enum": [
              "template"
            ],
            "type": "string"
          },
          "label": {
            "description": "Display label.",
            "type": "string"
          },
          "shape": {
            "description": "Item shape. `cylinder` and `drum` use `radius` + `height` instead of `length` + `width`; `pallet` and `drum` always stay upright.",
            "enum": [
              "box",
              "cylinder",
              "pallet",
              "bag",
              "drum"
            ],
            "type": "string"
          },
          "length": {
            "description": "Length. Required unless `shape` is `cylinder` or `drum`.",
            "type": "number",
            "x-unit": "cm"
          },
          "width": {
            "description": "Width. Required unless `shape` is `cylinder` or `drum`.",
            "type": "number",
            "x-unit": "cm"
          },
          "height": {
            "description": "Height (the vertical side when the item stands as defined).",
            "type": "number",
            "x-unit": "cm"
          },
          "radius": {
            "description": "Radius. Required when `shape` is `cylinder` or `drum`.",
            "type": "number",
            "x-unit": "cm"
          },
          "weight": {
            "description": "Weight of ONE unit.",
            "type": "number",
            "x-unit": "kg"
          },
          "stackable": {
            "description": "Other items may be placed on top of this one.",
            "type": "boolean"
          },
          "max_stack_weight": {
            "description": "Maximum weight that may rest on one unit. 0 = unlimited.",
            "type": "number",
            "x-unit": "kg"
          },
          "rotation": {
            "description": "`all` = any of the six orientations; `upright` = may only turn around the vertical axis (this side up); `fixed` = never rotated.",
            "enum": [
              "all",
              "upright",
              "fixed"
            ],
            "type": "string"
          },
          "hazardous": {
            "description": "Dangerous goods: kept low and separated from other hazardous items.",
            "type": "boolean"
          },
          "priority": {
            "description": "Load priority. Higher = loaded first and kept when space runs out. 0 = none.",
            "type": "integer"
          },
          "color": {
            "description": "Display colour as #rrggbb (viewer and PDF only).",
            "type": "string"
          },
          "nesting_height": {
            "description": "Telescoping overlap when identical units stack (nested crates, buckets).",
            "type": "number",
            "x-unit": "cm"
          },
          "created_by": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/UserRef"
              },
              {
                "type": "null"
              }
            ],
            "description": "The member who created it (for API calls: the member who created the key). `null` when unknown."
          },
          "updated_by": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/UserRef"
              },
              {
                "type": "null"
              }
            ],
            "description": "The member who last changed it."
          },
          "created_at": {
            "description": "RFC 3339.",
            "type": "string"
          },
          "updated_at": {
            "description": "RFC 3339.",
            "type": "string"
          }
        },
        "type": "object"
      },
      "TemplateInput": {
        "description": "A template: the /v1/pack `Item` fields without the per-load ones (`id`, `quantity`, `group`), validated the same way.",
        "properties": {
          "label": {
            "description": "Display label.",
            "maxLength": 255,
            "type": "string"
          },
          "shape": {
            "default": "box",
            "description": "Item shape. `cylinder` and `drum` use `radius` + `height` instead of `length` + `width`; `pallet` and `drum` always stay upright.",
            "enum": [
              "box",
              "cylinder",
              "pallet",
              "bag",
              "drum"
            ],
            "type": "string"
          },
          "length": {
            "description": "Length. Required unless `shape` is `cylinder` or `drum`.",
            "type": "number",
            "x-unit": "cm"
          },
          "width": {
            "description": "Width. Required unless `shape` is `cylinder` or `drum`.",
            "type": "number",
            "x-unit": "cm"
          },
          "height": {
            "description": "Height (the vertical side when the item stands as defined).",
            "type": "number",
            "x-unit": "cm"
          },
          "radius": {
            "description": "Radius. Required when `shape` is `cylinder` or `drum`.",
            "type": "number",
            "x-unit": "cm"
          },
          "weight": {
            "description": "Weight of ONE unit.",
            "type": "number",
            "x-unit": "kg"
          },
          "stackable": {
            "default": true,
            "description": "Other items may be placed on top of this one.",
            "type": "boolean"
          },
          "max_stack_weight": {
            "default": 0,
            "description": "Maximum weight that may rest on one unit. 0 = unlimited.",
            "type": "number",
            "x-unit": "kg"
          },
          "rotation": {
            "default": "all",
            "description": "`all` = any of the six orientations; `upright` = may only turn around the vertical axis (this side up); `fixed` = never rotated.",
            "enum": [
              "all",
              "upright",
              "fixed"
            ],
            "type": "string"
          },
          "hazardous": {
            "default": false,
            "description": "Dangerous goods: kept low and separated from other hazardous items.",
            "type": "boolean"
          },
          "priority": {
            "default": 0,
            "description": "Load priority. Higher = loaded first and kept when space runs out. 0 = none.",
            "minimum": 0,
            "type": "integer"
          },
          "color": {
            "description": "Display colour as #rrggbb (viewer and PDF only).",
            "type": "string"
          },
          "nesting_height": {
            "default": 0,
            "description": "Telescoping overlap when identical units stack (nested crates, buckets).",
            "type": "number",
            "x-unit": "cm"
          }
        },
        "required": [
          "label",
          "height",
          "weight"
        ],
        "type": "object"
      },
      "TemplateList": {
        "properties": {
          "data": {
            "description": "Newest first.",
            "items": {
              "$ref": "#/components/schemas/Template"
            },
            "type": "array"
          },
          "next_cursor": {
            "description": "Pass as ?cursor= for the next page; empty on the last page.",
            "type": "string"
          }
        },
        "type": "object"
      },
      "TemplateUpdate": {
        "description": "The fields to change. Absent fields keep their value.",
        "properties": {
          "label": {
            "description": "Display label.",
            "maxLength": 255,
            "type": "string"
          },
          "shape": {
            "default": "box",
            "description": "Item shape. `cylinder` and `drum` use `radius` + `height` instead of `length` + `width`; `pallet` and `drum` always stay upright.",
            "enum": [
              "box",
              "cylinder",
              "pallet",
              "bag",
              "drum"
            ],
            "type": "string"
          },
          "length": {
            "description": "Length. Required unless `shape` is `cylinder` or `drum`.",
            "type": "number",
            "x-unit": "cm"
          },
          "width": {
            "description": "Width. Required unless `shape` is `cylinder` or `drum`.",
            "type": "number",
            "x-unit": "cm"
          },
          "height": {
            "description": "Height (the vertical side when the item stands as defined).",
            "type": "number",
            "x-unit": "cm"
          },
          "radius": {
            "description": "Radius. Required when `shape` is `cylinder` or `drum`.",
            "type": "number",
            "x-unit": "cm"
          },
          "weight": {
            "description": "Weight of ONE unit.",
            "type": "number",
            "x-unit": "kg"
          },
          "stackable": {
            "default": true,
            "description": "Other items may be placed on top of this one.",
            "type": "boolean"
          },
          "max_stack_weight": {
            "default": 0,
            "description": "Maximum weight that may rest on one unit. 0 = unlimited.",
            "type": "number",
            "x-unit": "kg"
          },
          "rotation": {
            "default": "all",
            "description": "`all` = any of the six orientations; `upright` = may only turn around the vertical axis (this side up); `fixed` = never rotated.",
            "enum": [
              "all",
              "upright",
              "fixed"
            ],
            "type": "string"
          },
          "hazardous": {
            "default": false,
            "description": "Dangerous goods: kept low and separated from other hazardous items.",
            "type": "boolean"
          },
          "priority": {
            "default": 0,
            "description": "Load priority. Higher = loaded first and kept when space runs out. 0 = none.",
            "minimum": 0,
            "type": "integer"
          },
          "color": {
            "description": "Display colour as #rrggbb (viewer and PDF only).",
            "type": "string"
          },
          "nesting_height": {
            "default": 0,
            "description": "Telescoping overlap when identical units stack (nested crates, buckets).",
            "type": "number",
            "x-unit": "cm"
          }
        },
        "type": "object"
      },
      "UnplacedItem": {
        "properties": {
          "item_id": {
            "description": "Your item definition id.",
            "type": "string"
          },
          "instance": {
            "description": "1-based unit number.",
            "type": "integer"
          },
          "label": {
            "description": "Item label.",
            "type": "string"
          },
          "reason": {
            "description": "Why it could not be placed.",
            "type": "string"
          }
        },
        "type": "object"
      },
      "Usage": {
        "properties": {
          "data": {
            "items": {
              "$ref": "#/components/schemas/UsageDay"
            },
            "type": "array"
          }
        },
        "type": "object"
      },
      "UsageDay": {
        "properties": {
          "date": {
            "description": "UTC date YYYY-MM-DD.",
            "type": "string"
          },
          "requests": {
            "type": "integer"
          },
          "jobs": {
            "type": "integer"
          },
          "credits": {
            "type": "number",
            "x-unit": "credits"
          },
          "compute_seconds": {
            "type": "number",
            "x-unit": "s"
          },
          "vehicles": {
            "description": "Vehicles loaded.",
            "type": "integer"
          }
        },
        "type": "object"
      },
      "UserRef": {
        "description": "A member of your organization.",
        "properties": {
          "id": {
            "description": "Member id (usr_…). Filter lists with ?created_by=.",
            "type": "string"
          },
          "name": {
            "type": "string"
          }
        },
        "type": "object"
      },
      "Vehicle": {
        "description": "A vehicle definition: a truck, trailer, container, pallet… Either name a saved vehicle with `vehicle_id` (a preset or one of yours, from GET /v1/vehicles) or give `type` + dimensions + `max_weight`. Fields sent next to `vehicle_id` override the saved values.",
        "properties": {
          "id": {
            "description": "Your identifier, unique within the request. Results refer to it as vehicle_id. Defaults to vehicle_id.",
            "maxLength": 128,
            "type": "string"
          },
          "vehicle_id": {
            "description": "A vehicle id from GET /v1/vehicles: a preset or one of your organization's vehicles (veh_…). Supplies type, name, dimensions, payload and every other saved value.",
            "type": "string"
          },
          "type": {
            "description": "Vehicle type. Required unless vehicle_id is given. Only the types listed in GET /v1/limits (allowed_vehicle_types) are accepted.",
            "enum": [
              "truck",
              "trailer",
              "flatbed",
              "container",
              "pallet",
              "aircraft",
              "ship"
            ],
            "type": "string"
          },
          "name": {
            "description": "Display name (defaults to the saved vehicle's name or the id).",
            "maxLength": 255,
            "type": "string"
          },
          "length": {
            "description": "Internal cargo-space length, along x (from the front wall toward the door). Required unless vehicle_id is given.",
            "minimum": 0,
            "type": "number",
            "x-unit": "cm"
          },
          "width": {
            "description": "Internal cargo-space width, along z. Required unless vehicle_id is given.",
            "minimum": 0,
            "type": "number",
            "x-unit": "cm"
          },
          "height": {
            "description": "Internal cargo-space height, along y. Required unless vehicle_id is given.",
            "minimum": 0,
            "type": "number",
            "x-unit": "cm"
          },
          "max_weight": {
            "description": "Maximum payload. Required unless vehicle_id is given.",
            "minimum": 0,
            "type": "number",
            "x-unit": "kg"
          },
          "quantity": {
            "default": 1,
            "description": "How many identical vehicles of this definition are available.",
            "maximum": 100,
            "minimum": 1,
            "type": "integer"
          },
          "floor_load_capacity": {
            "description": "Floor load capacity: 0 or more (0 = no limit).",
            "minimum": 0,
            "type": "number",
            "x-unit": "kg/m²"
          },
          "aux_deck": {
            "default": false,
            "description": "The vehicle has a second deck (double-decker).",
            "type": "boolean"
          },
          "aux_deck_height": {
            "description": "Second deck height above the floor. Required when `aux_deck` is `true`.",
            "type": "number",
            "x-unit": "cm"
          },
          "aux_deck_max_weight": {
            "description": "Load limit of the second deck. Required when `aux_deck` is `true`.",
            "type": "number",
            "x-unit": "kg"
          },
          "blocked_areas": {
            "description": "Floor zones nothing may stand on (wheel arches, damage, reserved space). Each must lie on the vehicle floor.",
            "items": {
              "$ref": "#/components/schemas/Rect"
            },
            "maxItems": 32,
            "type": "array"
          },
          "axle_positions": {
            "description": "Axle (support point) positions measured from the front of the cargo area; negative = in front of it. Same length as axle_max_loads. Each between −300 (an axle ahead of the cargo area, e.g. a rigid truck's front axle under the cab) and the vehicle length.",
            "items": {
              "type": "number"
            },
            "maxItems": 10,
            "type": "array",
            "x-feature": "axle_loads",
            "x-unit": "cm"
          },
          "axle_max_loads": {
            "description": "Maximum cargo load per axle, in the order of axle_positions. Each greater than 0 and at most 100000.",
            "items": {
              "type": "number"
            },
            "maxItems": 10,
            "type": "array",
            "x-feature": "axle_loads",
            "x-unit": "kg"
          },
          "cog_range_x": {
            "description": "Allowed centre-of-gravity deviation from the middle of the length: 0 to length / 2.",
            "minimum": 0,
            "type": "number",
            "x-feature": "axle_loads",
            "x-unit": "cm"
          },
          "cog_range_y": {
            "description": "Allowed centre-of-gravity deviation from the middle of the width: 0 to width / 2.",
            "minimum": 0,
            "type": "number",
            "x-feature": "axle_loads",
            "x-unit": "cm"
          },
          "tractor_weight": {
            "description": "Semi-trailer axle model: tractor unit mass.",
            "type": "number",
            "x-feature": "axle_loads",
            "x-unit": "kg"
          },
          "empty_trailer_weight": {
            "description": "Semi-trailer axle model: unladen trailer mass.",
            "type": "number",
            "x-feature": "axle_loads",
            "x-unit": "kg"
          },
          "front_axle_to_middle_axle": {
            "description": "Semi-trailer axle model: tractor front axle to drive (middle) axle.",
            "type": "number",
            "x-feature": "axle_loads",
            "x-unit": "cm"
          },
          "front_axle_to_tractor_cog": {
            "description": "Semi-trailer axle model: front axle to tractor centre of gravity.",
            "type": "number",
            "x-feature": "axle_loads",
            "x-unit": "cm"
          },
          "front_axle_to_kingpin": {
            "description": "Semi-trailer axle model: front axle to kingpin (fifth wheel).",
            "type": "number",
            "x-feature": "axle_loads",
            "x-unit": "cm"
          },
          "kingpin_to_rear_axle": {
            "description": "Semi-trailer axle model: kingpin to trailer rear axle group.",
            "type": "number",
            "x-feature": "axle_loads",
            "x-unit": "cm"
          },
          "trailer_cog_to_rear_axle": {
            "description": "Semi-trailer axle model: trailer centre of gravity to rear axle group.",
            "type": "number",
            "x-feature": "axle_loads",
            "x-unit": "cm"
          },
          "trailer_start_to_kingpin": {
            "description": "Semi-trailer axle model: trailer front to kingpin.",
            "type": "number",
            "x-feature": "axle_loads",
            "x-unit": "cm"
          },
          "max_middle_axle_weight": {
            "description": "Semi-trailer axle model: legal drive (middle) axle limit.",
            "type": "number",
            "x-feature": "axle_loads",
            "x-unit": "kg"
          },
          "max_rear_axle_weight": {
            "description": "Semi-trailer axle model: legal rear axle group limit.",
            "type": "number",
            "x-feature": "axle_loads",
            "x-unit": "kg"
          }
        },
        "type": "object"
      },
      "VehicleInput": {
        "description": "A vehicle of your own: the /v1/pack `Vehicle` fields without the per-job ones (`id`, `vehicle_id`, `quantity`). Judged by the app's plausibility limits for its type.",
        "properties": {
          "type": {
            "description": "Vehicle type. Only the types listed in GET /v1/limits (allowed_vehicle_types) are accepted.",
            "enum": [
              "truck",
              "trailer",
              "flatbed",
              "container",
              "pallet",
              "aircraft",
              "ship"
            ],
            "type": "string"
          },
          "name": {
            "description": "Display name.",
            "maxLength": 255,
            "type": "string"
          },
          "length": {
            "description": "Internal cargo-space length, along x (from the front wall toward the door).",
            "minimum": 0,
            "type": "number",
            "x-unit": "cm"
          },
          "width": {
            "description": "Internal cargo-space width, along z.",
            "minimum": 0,
            "type": "number",
            "x-unit": "cm"
          },
          "height": {
            "description": "Internal cargo-space height, along y.",
            "minimum": 0,
            "type": "number",
            "x-unit": "cm"
          },
          "max_weight": {
            "description": "Maximum payload.",
            "minimum": 0,
            "type": "number",
            "x-unit": "kg"
          },
          "floor_load_capacity": {
            "description": "Floor load capacity: 0 or more (0 = no limit).",
            "minimum": 0,
            "type": "number",
            "x-unit": "kg/m²"
          },
          "aux_deck": {
            "default": false,
            "description": "The vehicle has a second deck (double-decker).",
            "type": "boolean"
          },
          "aux_deck_height": {
            "description": "Second deck height above the floor. Required when `aux_deck` is `true`.",
            "type": "number",
            "x-unit": "cm"
          },
          "aux_deck_max_weight": {
            "description": "Load limit of the second deck. Required when `aux_deck` is `true`.",
            "type": "number",
            "x-unit": "kg"
          },
          "blocked_areas": {
            "description": "Floor zones nothing may stand on (wheel arches, damage, reserved space). Each must lie on the vehicle floor.",
            "items": {
              "$ref": "#/components/schemas/Rect"
            },
            "maxItems": 32,
            "type": "array"
          },
          "axle_positions": {
            "description": "Axle (support point) positions measured from the front of the cargo area; negative = in front of it. Same length as axle_max_loads. Each between −300 (an axle ahead of the cargo area, e.g. a rigid truck's front axle under the cab) and the vehicle length.",
            "items": {
              "type": "number"
            },
            "maxItems": 10,
            "type": "array",
            "x-feature": "axle_loads",
            "x-unit": "cm"
          },
          "axle_max_loads": {
            "description": "Maximum cargo load per axle, in the order of axle_positions. Each greater than 0 and at most 100000.",
            "items": {
              "type": "number"
            },
            "maxItems": 10,
            "type": "array",
            "x-feature": "axle_loads",
            "x-unit": "kg"
          },
          "cog_range_x": {
            "description": "Allowed centre-of-gravity deviation from the middle of the length: 0 to length / 2.",
            "minimum": 0,
            "type": "number",
            "x-feature": "axle_loads",
            "x-unit": "cm"
          },
          "cog_range_y": {
            "description": "Allowed centre-of-gravity deviation from the middle of the width: 0 to width / 2.",
            "minimum": 0,
            "type": "number",
            "x-feature": "axle_loads",
            "x-unit": "cm"
          },
          "tractor_weight": {
            "description": "Semi-trailer axle model: tractor unit mass.",
            "type": "number",
            "x-feature": "axle_loads",
            "x-unit": "kg"
          },
          "empty_trailer_weight": {
            "description": "Semi-trailer axle model: unladen trailer mass.",
            "type": "number",
            "x-feature": "axle_loads",
            "x-unit": "kg"
          },
          "front_axle_to_middle_axle": {
            "description": "Semi-trailer axle model: tractor front axle to drive (middle) axle.",
            "type": "number",
            "x-feature": "axle_loads",
            "x-unit": "cm"
          },
          "front_axle_to_tractor_cog": {
            "description": "Semi-trailer axle model: front axle to tractor centre of gravity.",
            "type": "number",
            "x-feature": "axle_loads",
            "x-unit": "cm"
          },
          "front_axle_to_kingpin": {
            "description": "Semi-trailer axle model: front axle to kingpin (fifth wheel).",
            "type": "number",
            "x-feature": "axle_loads",
            "x-unit": "cm"
          },
          "kingpin_to_rear_axle": {
            "description": "Semi-trailer axle model: kingpin to trailer rear axle group.",
            "type": "number",
            "x-feature": "axle_loads",
            "x-unit": "cm"
          },
          "trailer_cog_to_rear_axle": {
            "description": "Semi-trailer axle model: trailer centre of gravity to rear axle group.",
            "type": "number",
            "x-feature": "axle_loads",
            "x-unit": "cm"
          },
          "trailer_start_to_kingpin": {
            "description": "Semi-trailer axle model: trailer front to kingpin.",
            "type": "number",
            "x-feature": "axle_loads",
            "x-unit": "cm"
          },
          "max_middle_axle_weight": {
            "description": "Semi-trailer axle model: legal drive (middle) axle limit.",
            "type": "number",
            "x-feature": "axle_loads",
            "x-unit": "kg"
          },
          "max_rear_axle_weight": {
            "description": "Semi-trailer axle model: legal rear axle group limit.",
            "type": "number",
            "x-feature": "axle_loads",
            "x-unit": "kg"
          }
        },
        "required": [
          "type",
          "name",
          "length",
          "width",
          "height",
          "max_weight"
        ],
        "type": "object"
      },
      "VehicleUpdate": {
        "description": "The fields to change. Absent fields keep their value; `null` clears an optional one.",
        "properties": {
          "type": {
            "description": "Vehicle type. Only the types listed in GET /v1/limits (allowed_vehicle_types) are accepted.",
            "enum": [
              "truck",
              "trailer",
              "flatbed",
              "container",
              "pallet",
              "aircraft",
              "ship"
            ],
            "type": "string"
          },
          "name": {
            "description": "Display name.",
            "maxLength": 255,
            "type": "string"
          },
          "length": {
            "description": "Internal cargo-space length, along x (from the front wall toward the door).",
            "minimum": 0,
            "type": "number",
            "x-unit": "cm"
          },
          "width": {
            "description": "Internal cargo-space width, along z.",
            "minimum": 0,
            "type": "number",
            "x-unit": "cm"
          },
          "height": {
            "description": "Internal cargo-space height, along y.",
            "minimum": 0,
            "type": "number",
            "x-unit": "cm"
          },
          "max_weight": {
            "description": "Maximum payload.",
            "minimum": 0,
            "type": "number",
            "x-unit": "kg"
          },
          "floor_load_capacity": {
            "description": "Floor load capacity: 0 or more (0 = no limit).",
            "minimum": 0,
            "type": "number",
            "x-unit": "kg/m²"
          },
          "aux_deck": {
            "default": false,
            "description": "The vehicle has a second deck (double-decker).",
            "type": "boolean"
          },
          "aux_deck_height": {
            "description": "Second deck height above the floor. Required when `aux_deck` is `true`.",
            "type": "number",
            "x-unit": "cm"
          },
          "aux_deck_max_weight": {
            "description": "Load limit of the second deck. Required when `aux_deck` is `true`.",
            "type": "number",
            "x-unit": "kg"
          },
          "blocked_areas": {
            "description": "Floor zones nothing may stand on (wheel arches, damage, reserved space). Each must lie on the vehicle floor.",
            "items": {
              "$ref": "#/components/schemas/Rect"
            },
            "maxItems": 32,
            "type": "array"
          },
          "axle_positions": {
            "description": "Axle (support point) positions measured from the front of the cargo area; negative = in front of it. Same length as axle_max_loads. Each between −300 (an axle ahead of the cargo area, e.g. a rigid truck's front axle under the cab) and the vehicle length.",
            "items": {
              "type": "number"
            },
            "maxItems": 10,
            "type": "array",
            "x-feature": "axle_loads",
            "x-unit": "cm"
          },
          "axle_max_loads": {
            "description": "Maximum cargo load per axle, in the order of axle_positions. Each greater than 0 and at most 100000.",
            "items": {
              "type": "number"
            },
            "maxItems": 10,
            "type": "array",
            "x-feature": "axle_loads",
            "x-unit": "kg"
          },
          "cog_range_x": {
            "description": "Allowed centre-of-gravity deviation from the middle of the length: 0 to length / 2.",
            "minimum": 0,
            "type": "number",
            "x-feature": "axle_loads",
            "x-unit": "cm"
          },
          "cog_range_y": {
            "description": "Allowed centre-of-gravity deviation from the middle of the width: 0 to width / 2.",
            "minimum": 0,
            "type": "number",
            "x-feature": "axle_loads",
            "x-unit": "cm"
          },
          "tractor_weight": {
            "description": "Semi-trailer axle model: tractor unit mass.",
            "type": "number",
            "x-feature": "axle_loads",
            "x-unit": "kg"
          },
          "empty_trailer_weight": {
            "description": "Semi-trailer axle model: unladen trailer mass.",
            "type": "number",
            "x-feature": "axle_loads",
            "x-unit": "kg"
          },
          "front_axle_to_middle_axle": {
            "description": "Semi-trailer axle model: tractor front axle to drive (middle) axle.",
            "type": "number",
            "x-feature": "axle_loads",
            "x-unit": "cm"
          },
          "front_axle_to_tractor_cog": {
            "description": "Semi-trailer axle model: front axle to tractor centre of gravity.",
            "type": "number",
            "x-feature": "axle_loads",
            "x-unit": "cm"
          },
          "front_axle_to_kingpin": {
            "description": "Semi-trailer axle model: front axle to kingpin (fifth wheel).",
            "type": "number",
            "x-feature": "axle_loads",
            "x-unit": "cm"
          },
          "kingpin_to_rear_axle": {
            "description": "Semi-trailer axle model: kingpin to trailer rear axle group.",
            "type": "number",
            "x-feature": "axle_loads",
            "x-unit": "cm"
          },
          "trailer_cog_to_rear_axle": {
            "description": "Semi-trailer axle model: trailer centre of gravity to rear axle group.",
            "type": "number",
            "x-feature": "axle_loads",
            "x-unit": "cm"
          },
          "trailer_start_to_kingpin": {
            "description": "Semi-trailer axle model: trailer front to kingpin.",
            "type": "number",
            "x-feature": "axle_loads",
            "x-unit": "cm"
          },
          "max_middle_axle_weight": {
            "description": "Semi-trailer axle model: legal drive (middle) axle limit.",
            "type": "number",
            "x-feature": "axle_loads",
            "x-unit": "kg"
          },
          "max_rear_axle_weight": {
            "description": "Semi-trailer axle model: legal rear axle group limit.",
            "type": "number",
            "x-feature": "axle_loads",
            "x-unit": "kg"
          }
        },
        "type": "object"
      },
      "Warning": {
        "properties": {
          "code": {
            "description": "Machine code.",
            "type": "string"
          },
          "message": {
            "description": "English explanation.",
            "type": "string"
          }
        },
        "type": "object"
      }
    },
    "securitySchemes": {
      "bearerAuth": {
        "bearerFormat": "cd_live_\u003c40 base62 chars\u003e",
        "description": "API key from the developer console, sent as `Authorization: Bearer cd_live_…`. Keep it server-side.",
        "scheme": "bearer",
        "type": "http"
      }
    }
  },
  "externalDocs": {
    "description": "Docs",
    "url": "https://runner.cargoduo.com/api/public/api-docs/llms.txt"
  },
  "info": {
    "description": "Send vehicles and items, get a 3D load plan: positions, orientations, loading steps and a PDF link.\n\nUnits: centimetres and kilograms. Billing: credits, in US dollars (1 credit = $1); most jobs cost 0.27–0.34 credits. POST /v1/estimate prices a request for free; vehicle, template and project calls cost nothing.\n\nLimits: 2000 items and 20 vehicles per job, 60/1000/5000 requests per minute/hour/day. Bodies and results are kept 14 days.\n\nIntegration playbook for coding agents: https://runner.cargoduo.com/api/public/api-docs/llms-full.txt",
    "title": "CargoDuo Packing API",
    "version": "1.0.0"
  },
  "openapi": "3.1.0",
  "paths": {
    "/v1/balance": {
      "get": {
        "description": "Available, plan, purchased and reserved credits.",
        "externalDocs": {
          "url": "https://runner.cargoduo.com/api/public/api-docs/pages/get-balance.md"
        },
        "operationId": "getBalance",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "example": {
                  "available_credits": 147.75,
                  "subscription_credits": 98.5,
                  "subscription_expires_at": "2026-11-07T00:00:00Z",
                  "purchased_credits": 50,
                  "reserved_credits": 0.75
                },
                "schema": {
                  "$ref": "#/components/schemas/Balance"
                }
              }
            },
            "description": "Balance.",
            "headers": {
              "X-Credits-Remaining": {
                "description": "Available credits after this request (decimal).",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Limit of the tightest rate window.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix time (seconds) when that window resets.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`unauthorized`: Missing, malformed or unknown API key.\n\n`key_revoked`: The key was revoked.\n\n`key_expired`: The key passed its expiry date.",
            "headers": {
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "x-error-codes": [
              "unauthorized",
              "key_revoked",
              "key_expired"
            ]
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`ip_not_allowed`: The calling IP is not on the key's allowlist.\n\n`subscription_inactive`: The organization has no active subscription that includes the API.\n\n`account_inactive`: The organization is suspended, or has no owner whose account is active.\n\n`scope_missing`: The key lacks a scope this endpoint needs.",
            "headers": {
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "x-error-codes": [
              "ip_not_allowed",
              "subscription_inactive",
              "account_inactive",
              "scope_missing"
            ]
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`rate_limited`: Too many requests in the current minute, hour or day (per key or per organization), or more than 60 failed authentications per minute from your IP address.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "x-error-codes": [
              "rate_limited"
            ]
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`internal_error`: Something failed on our side.",
            "headers": {
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "x-error-codes": [
              "internal_error"
            ]
          },
          "503": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`api_disabled`: The API is temporarily disabled (maintenance) or switched off for the organization.",
            "headers": {
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "x-error-codes": [
              "api_disabled"
            ]
          }
        },
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "summary": "Get the balance",
        "tags": [
          "Account"
        ],
        "x-example-request": {},
        "x-scope": "account:read",
        "x-scopes": [
          "account:read"
        ]
      }
    },
    "/v1/estimate": {
      "post": {
        "description": "Runs the same validation as POST /v1/pack and returns the price range, without creating a job or reserving credits. Free. An invalid request answers 200 with `valid: false` and every problem in `errors[]`.",
        "externalDocs": {
          "url": "https://runner.cargoduo.com/api/public/api-docs/pages/estimate-pack-job.md"
        },
        "operationId": "estimatePackJob",
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "reference": "order-1042",
                "vehicles": [
                  {
                    "id": "trailer",
                    "type": "trailer",
                    "name": "13.6 m trailer",
                    "length": 1360,
                    "width": 245,
                    "height": 270,
                    "max_weight": 24000
                  }
                ],
                "items": [
                  {
                    "id": "pallet-eu",
                    "label": "Euro pallet",
                    "length": 120,
                    "width": 80,
                    "height": 140,
                    "weight": 450,
                    "quantity": 18,
                    "stackable": false
                  },
                  {
                    "id": "carton-a",
                    "label": "Carton A",
                    "length": 60,
                    "width": 40,
                    "height": 40,
                    "weight": 12,
                    "quantity": 40,
                    "rotation": "upright"
                  }
                ],
                "options": {
                  "packing_mode": "auto"
                }
              },
              "schema": {
                "$ref": "#/components/schemas/PackRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "example": {
                  "valid": true,
                  "errors": [],
                  "warnings": [],
                  "items": 58,
                  "max_vehicles": 3,
                  "estimated_cost": {
                    "min_credits": 0.26,
                    "max_credits": 1.11
                  },
                  "estimated_seconds": 90,
                  "balance": {
                    "available_credits": 147.75
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/Estimate"
                }
              }
            },
            "description": "Validation result and price range.",
            "headers": {
              "X-Credits-Remaining": {
                "description": "Available credits after this request (decimal).",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Limit of the tightest rate window.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix time (seconds) when that window resets.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`invalid_json`: The body is not valid JSON or a field has the wrong type.",
            "headers": {
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "x-error-codes": [
              "invalid_json"
            ]
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`unauthorized`: Missing, malformed or unknown API key.\n\n`key_revoked`: The key was revoked.\n\n`key_expired`: The key passed its expiry date.",
            "headers": {
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "x-error-codes": [
              "unauthorized",
              "key_revoked",
              "key_expired"
            ]
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`ip_not_allowed`: The calling IP is not on the key's allowlist.\n\n`subscription_inactive`: The organization has no active subscription that includes the API.\n\n`account_inactive`: The organization is suspended, or has no owner whose account is active.\n\n`scope_missing`: The key lacks a scope this endpoint needs.",
            "headers": {
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "x-error-codes": [
              "ip_not_allowed",
              "subscription_inactive",
              "account_inactive",
              "scope_missing"
            ]
          },
          "413": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`payload_too_large`: The request body exceeds 10 MB.",
            "headers": {
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "x-error-codes": [
              "payload_too_large"
            ]
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`rate_limited`: Too many requests in the current minute, hour or day (per key or per organization), or more than 60 failed authentications per minute from your IP address.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "x-error-codes": [
              "rate_limited"
            ]
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`internal_error`: Something failed on our side.",
            "headers": {
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "x-error-codes": [
              "internal_error"
            ]
          },
          "503": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`api_disabled`: The API is temporarily disabled (maintenance) or switched off for the organization.",
            "headers": {
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "x-error-codes": [
              "api_disabled"
            ]
          }
        },
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "summary": "Estimate a packing job",
        "tags": [
          "Pack"
        ],
        "x-example-request": {},
        "x-scope": "pack:write",
        "x-scopes": [
          "pack:write"
        ]
      }
    },
    "/v1/jobs": {
      "get": {
        "description": "Your organization's jobs, newest first, one page at a time.",
        "externalDocs": {
          "url": "https://runner.cargoduo.com/api/public/api-docs/pages/list-jobs.md"
        },
        "operationId": "listJobs",
        "parameters": [
          {
            "description": "Page size.",
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": {
              "default": 20,
              "maximum": 100,
              "minimum": 1,
              "type": "integer"
            }
          },
          {
            "description": "next_cursor of the previous page.",
            "in": "query",
            "name": "cursor",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Only jobs in this status.",
            "in": "query",
            "name": "status",
            "required": false,
            "schema": {
              "enum": [
                "queued",
                "running",
                "succeeded",
                "failed",
                "canceled"
              ],
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "example": {
                  "data": [
                    {
                      "id": "job_4bK9mT2xQe7LpW1zRc8VdN3f",
                      "object": "job",
                      "status": "succeeded",
                      "reference": "order-1042",
                      "source": "api",
                      "created_at": "2026-10-19T09:12:03Z",
                      "started_at": "2026-10-19T09:12:03Z",
                      "finished_at": "2026-10-19T09:12:07Z",
                      "progress": {
                        "stage": "done",
                        "vehicles_done": 1,
                        "placed_items": 58
                      },
                      "summary": {
                        "items_requested": 58,
                        "items_placed": 58,
                        "items_unplaced": 0,
                        "vehicles_used": 1,
                        "total_weight": 8580,
                        "volume_utilization": 0.3116,
                        "queue_ms": 12,
                        "compute_ms": 4210
                      },
                      "cost": {
                        "credits": 0.28105,
                        "reserved_credits": 1.11,
                        "rate_card_version": 1,
                        "breakdown": {
                          "base": 0.06,
                          "vehicles": 0.2,
                          "compute": 0.02105,
                          "large_load": 0
                        }
                      },
                      "error": null,
                      "warnings": [],
                      "result_url": "https://runner.cargoduo.com/v1/jobs/job_4bK9mT2xQe7LpW1zRc8VdN3f/result",
                      "pdf_url": "https://app.cargoduo.com/r/Xq7Lm2Vt9KbR4cN8wZp1Hs6Yd3Fg5Jk0Ta2Ue7Wn4Ci",
                      "expires_at": "2026-11-02T09:12:03Z"
                    },
                    {
                      "id": "job_7hN2wQ5rTb9xKc3LmP8sVa1d",
                      "object": "job",
                      "status": "succeeded",
                      "reference": "order-1039",
                      "source": "api",
                      "created_at": "2026-10-18T07:12:03Z",
                      "started_at": "2026-10-18T07:12:03Z",
                      "finished_at": "2026-10-18T07:12:05Z",
                      "progress": {
                        "stage": "done",
                        "vehicles_done": 1,
                        "placed_items": 24
                      },
                      "summary": {
                        "items_requested": 24,
                        "items_placed": 24,
                        "items_unplaced": 0,
                        "vehicles_used": 1,
                        "total_weight": 6240,
                        "volume_utilization": 0.2213,
                        "queue_ms": 9,
                        "compute_ms": 2870
                      },
                      "cost": {
                        "credits": 0.27435,
                        "reserved_credits": 1.11,
                        "rate_card_version": 1,
                        "breakdown": {
                          "base": 0.06,
                          "vehicles": 0.2,
                          "compute": 0.01435,
                          "large_load": 0
                        }
                      },
                      "error": null,
                      "warnings": [],
                      "result_url": "https://runner.cargoduo.com/v1/jobs/job_7hN2wQ5rTb9xKc3LmP8sVa1d/result",
                      "pdf_url": "https://app.cargoduo.com/r/Xq7Lm2Vt9KbR4cN8wZp1Hs6Yd3Fg5Jk0Ta2Ue7Wn4Ci",
                      "expires_at": "2026-11-01T07:12:03Z"
                    }
                  ],
                  "next_cursor": "job_7hN2wQ5rTb9xKc3LmP8sVa1d"
                },
                "schema": {
                  "$ref": "#/components/schemas/JobList"
                }
              }
            },
            "description": "One page of jobs.",
            "headers": {
              "X-Credits-Remaining": {
                "description": "Available credits after this request (decimal).",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Limit of the tightest rate window.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix time (seconds) when that window resets.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`unauthorized`: Missing, malformed or unknown API key.\n\n`key_revoked`: The key was revoked.\n\n`key_expired`: The key passed its expiry date.",
            "headers": {
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "x-error-codes": [
              "unauthorized",
              "key_revoked",
              "key_expired"
            ]
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`ip_not_allowed`: The calling IP is not on the key's allowlist.\n\n`subscription_inactive`: The organization has no active subscription that includes the API.\n\n`account_inactive`: The organization is suspended, or has no owner whose account is active.\n\n`scope_missing`: The key lacks a scope this endpoint needs.",
            "headers": {
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "x-error-codes": [
              "ip_not_allowed",
              "subscription_inactive",
              "account_inactive",
              "scope_missing"
            ]
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`validation_failed`: The request is well-formed JSON but describes an invalid job. details[] lists every problem.",
            "headers": {
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "x-error-codes": [
              "validation_failed"
            ]
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`rate_limited`: Too many requests in the current minute, hour or day (per key or per organization), or more than 60 failed authentications per minute from your IP address.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "x-error-codes": [
              "rate_limited"
            ]
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`internal_error`: Something failed on our side.",
            "headers": {
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "x-error-codes": [
              "internal_error"
            ]
          },
          "503": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`api_disabled`: The API is temporarily disabled (maintenance) or switched off for the organization.",
            "headers": {
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "x-error-codes": [
              "api_disabled"
            ]
          }
        },
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "summary": "List jobs",
        "tags": [
          "Jobs"
        ],
        "x-example-request": {
          "query": {
            "limit": 2,
            "status": "succeeded"
          }
        },
        "x-scope": "jobs:read",
        "x-scopes": [
          "jobs:read"
        ]
      }
    },
    "/v1/jobs/{id}": {
      "delete": {
        "description": "Stops a queued or running job. A canceled job pays the per-job fee, any large-load surcharge and the compute used so far, never the per-vehicle fee. Canceling a canceled job returns it unchanged.",
        "externalDocs": {
          "url": "https://runner.cargoduo.com/api/public/api-docs/pages/cancel-job.md"
        },
        "operationId": "cancelJob",
        "parameters": [
          {
            "description": "Job id (job_…).",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "example": {
                  "id": "job_2cR8vL4nXp6tQb1mZk9WsH5e",
                  "object": "job",
                  "status": "canceled",
                  "reference": "order-1043",
                  "source": "api",
                  "created_at": "2026-10-19T09:15:03Z",
                  "started_at": "2026-10-19T09:15:03Z",
                  "finished_at": "2026-10-19T09:15:05Z",
                  "progress": {
                    "stage": "done",
                    "vehicles_done": 0,
                    "placed_items": 0
                  },
                  "summary": {
                    "items_requested": 58,
                    "items_placed": 0,
                    "items_unplaced": 0,
                    "vehicles_used": 0,
                    "total_weight": 0,
                    "volume_utilization": 0,
                    "queue_ms": 15,
                    "compute_ms": 2300
                  },
                  "cost": {
                    "credits": 0.0715,
                    "reserved_credits": 1.11,
                    "rate_card_version": 1,
                    "breakdown": {
                      "base": 0.06,
                      "vehicles": 0,
                      "compute": 0.0115,
                      "large_load": 0
                    }
                  },
                  "error": {
                    "code": "canceled",
                    "message": "Canceled by request."
                  },
                  "warnings": [],
                  "result_url": "https://runner.cargoduo.com/v1/jobs/job_2cR8vL4nXp6tQb1mZk9WsH5e/result",
                  "pdf_url": "",
                  "expires_at": "2026-11-02T09:15:03Z"
                },
                "schema": {
                  "$ref": "#/components/schemas/Job"
                }
              }
            },
            "description": "The canceled job.",
            "headers": {
              "X-Credits-Remaining": {
                "description": "Available credits after this request (decimal).",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Limit of the tightest rate window.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix time (seconds) when that window resets.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`unauthorized`: Missing, malformed or unknown API key.\n\n`key_revoked`: The key was revoked.\n\n`key_expired`: The key passed its expiry date.",
            "headers": {
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "x-error-codes": [
              "unauthorized",
              "key_revoked",
              "key_expired"
            ]
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`ip_not_allowed`: The calling IP is not on the key's allowlist.\n\n`subscription_inactive`: The organization has no active subscription that includes the API.\n\n`account_inactive`: The organization is suspended, or has no owner whose account is active.\n\n`scope_missing`: The key lacks a scope this endpoint needs.",
            "headers": {
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "x-error-codes": [
              "ip_not_allowed",
              "subscription_inactive",
              "account_inactive",
              "scope_missing"
            ]
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`job_not_found`: No job with this id in your organization.",
            "headers": {
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "x-error-codes": [
              "job_not_found"
            ]
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`job_already_finished`: The job already ended and cannot be canceled.",
            "headers": {
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "x-error-codes": [
              "job_already_finished"
            ]
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`rate_limited`: Too many requests in the current minute, hour or day (per key or per organization), or more than 60 failed authentications per minute from your IP address.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "x-error-codes": [
              "rate_limited"
            ]
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`internal_error`: Something failed on our side.",
            "headers": {
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "x-error-codes": [
              "internal_error"
            ]
          },
          "503": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`api_disabled`: The API is temporarily disabled (maintenance) or switched off for the organization.",
            "headers": {
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "x-error-codes": [
              "api_disabled"
            ]
          }
        },
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "summary": "Cancel a job",
        "tags": [
          "Jobs"
        ],
        "x-example-request": {
          "path": {
            "id": "job_2cR8vL4nXp6tQb1mZk9WsH5e"
          }
        },
        "x-scope": "pack:write",
        "x-scopes": [
          "pack:write"
        ]
      },
      "get": {
        "description": "A job's status, progress, summary and cost. Poll it every 1–2 s until `status` is `succeeded`, `failed` or `canceled`.",
        "externalDocs": {
          "url": "https://runner.cargoduo.com/api/public/api-docs/pages/get-job.md"
        },
        "operationId": "getJob",
        "parameters": [
          {
            "description": "Job id (job_…).",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "`result` inlines the load plan once the job succeeded.",
            "in": "query",
            "name": "include",
            "required": false,
            "schema": {
              "enum": [
                "result"
              ],
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "example": {
                  "id": "job_4bK9mT2xQe7LpW1zRc8VdN3f",
                  "object": "job",
                  "status": "succeeded",
                  "reference": "order-1042",
                  "source": "api",
                  "created_at": "2026-10-19T09:12:03Z",
                  "started_at": "2026-10-19T09:12:03Z",
                  "finished_at": "2026-10-19T09:12:07Z",
                  "progress": {
                    "stage": "done",
                    "vehicles_done": 1,
                    "placed_items": 58
                  },
                  "summary": {
                    "items_requested": 58,
                    "items_placed": 58,
                    "items_unplaced": 0,
                    "vehicles_used": 1,
                    "total_weight": 8580,
                    "volume_utilization": 0.3116,
                    "queue_ms": 12,
                    "compute_ms": 4210
                  },
                  "cost": {
                    "credits": 0.28105,
                    "reserved_credits": 1.11,
                    "rate_card_version": 1,
                    "breakdown": {
                      "base": 0.06,
                      "vehicles": 0.2,
                      "compute": 0.02105,
                      "large_load": 0
                    }
                  },
                  "error": null,
                  "warnings": [],
                  "result_url": "https://runner.cargoduo.com/v1/jobs/job_4bK9mT2xQe7LpW1zRc8VdN3f/result",
                  "pdf_url": "https://app.cargoduo.com/r/Xq7Lm2Vt9KbR4cN8wZp1Hs6Yd3Fg5Jk0Ta2Ue7Wn4Ci",
                  "expires_at": "2026-11-02T09:12:03Z"
                },
                "schema": {
                  "$ref": "#/components/schemas/Job"
                }
              }
            },
            "description": "The job.",
            "headers": {
              "X-Credits-Remaining": {
                "description": "Available credits after this request (decimal).",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Limit of the tightest rate window.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix time (seconds) when that window resets.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`unauthorized`: Missing, malformed or unknown API key.\n\n`key_revoked`: The key was revoked.\n\n`key_expired`: The key passed its expiry date.",
            "headers": {
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "x-error-codes": [
              "unauthorized",
              "key_revoked",
              "key_expired"
            ]
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`ip_not_allowed`: The calling IP is not on the key's allowlist.\n\n`subscription_inactive`: The organization has no active subscription that includes the API.\n\n`account_inactive`: The organization is suspended, or has no owner whose account is active.\n\n`scope_missing`: The key lacks a scope this endpoint needs.",
            "headers": {
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "x-error-codes": [
              "ip_not_allowed",
              "subscription_inactive",
              "account_inactive",
              "scope_missing"
            ]
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`job_not_found`: No job with this id in your organization.",
            "headers": {
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "x-error-codes": [
              "job_not_found"
            ]
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`rate_limited`: Too many requests in the current minute, hour or day (per key or per organization), or more than 60 failed authentications per minute from your IP address.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "x-error-codes": [
              "rate_limited"
            ]
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`internal_error`: Something failed on our side.",
            "headers": {
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "x-error-codes": [
              "internal_error"
            ]
          },
          "503": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`api_disabled`: The API is temporarily disabled (maintenance) or switched off for the organization.",
            "headers": {
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "x-error-codes": [
              "api_disabled"
            ]
          }
        },
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "summary": "Get a job",
        "tags": [
          "Jobs"
        ],
        "x-example-request": {
          "path": {
            "id": "job_4bK9mT2xQe7LpW1zRc8VdN3f"
          }
        },
        "x-scope": "jobs:read",
        "x-scopes": [
          "jobs:read"
        ]
      }
    },
    "/v1/jobs/{id}/result": {
      "get": {
        "description": "The load plan of a succeeded job: every vehicle used, every placement, what did not fit and the PDF link.",
        "externalDocs": {
          "url": "https://runner.cargoduo.com/api/public/api-docs/pages/get-job-result.md"
        },
        "operationId": "getJobResult",
        "parameters": [
          {
            "description": "Job id (job_…).",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "example": {
                  "job_id": "job_4bK9mT2xQe7LpW1zRc8VdN3f",
                  "vehicles": [
                    {
                      "index": 0,
                      "vehicle_id": "trailer",
                      "copy": 1,
                      "auto_added": false,
                      "name": "13.6 m trailer",
                      "type": "trailer",
                      "length": 1360,
                      "width": 245,
                      "height": 270,
                      "max_weight": 24000,
                      "items_placed": 58,
                      "total_weight": 8580,
                      "volume_utilization": 0.3116,
                      "weight_utilization": 0.3575,
                      "center_of_gravity": {
                        "x": 452.6,
                        "y": 68.4,
                        "z": 121.8
                      },
                      "axle_loads": [],
                      "placements": [
                        {
                          "item_id": "pallet-eu",
                          "instance": 1,
                          "label": "Euro pallet",
                          "x": 0,
                          "y": 0,
                          "z": 0,
                          "length": 80,
                          "width": 120,
                          "height": 140,
                          "rotated": true,
                          "orientation": "wlh",
                          "step": 1,
                          "weight": 450
                        },
                        {
                          "item_id": "pallet-eu",
                          "instance": 2,
                          "label": "Euro pallet",
                          "x": 0,
                          "y": 0,
                          "z": 120,
                          "length": 80,
                          "width": 120,
                          "height": 140,
                          "rotated": true,
                          "orientation": "wlh",
                          "step": 2,
                          "weight": 450
                        },
                        {
                          "item_id": "carton-a",
                          "instance": 1,
                          "label": "Carton A",
                          "x": 720,
                          "y": 0,
                          "z": 0,
                          "length": 60,
                          "width": 40,
                          "height": 40,
                          "rotated": false,
                          "orientation": "lwh",
                          "step": 19,
                          "weight": 12
                        }
                      ]
                    }
                  ],
                  "unplaced": [],
                  "warnings": [],
                  "pdf_url": "https://app.cargoduo.com/r/Xq7Lm2Vt9KbR4cN8wZp1Hs6Yd3Fg5Jk0Ta2Ue7Wn4Ci",
                  "expires_at": "2026-11-02T09:12:03Z"
                },
                "schema": {
                  "$ref": "#/components/schemas/Result"
                }
              }
            },
            "description": "The load plan.",
            "headers": {
              "X-Credits-Remaining": {
                "description": "Available credits after this request (decimal).",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Limit of the tightest rate window.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix time (seconds) when that window resets.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`unauthorized`: Missing, malformed or unknown API key.\n\n`key_revoked`: The key was revoked.\n\n`key_expired`: The key passed its expiry date.",
            "headers": {
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "x-error-codes": [
              "unauthorized",
              "key_revoked",
              "key_expired"
            ]
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`ip_not_allowed`: The calling IP is not on the key's allowlist.\n\n`subscription_inactive`: The organization has no active subscription that includes the API.\n\n`account_inactive`: The organization is suspended, or has no owner whose account is active.\n\n`scope_missing`: The key lacks a scope this endpoint needs.",
            "headers": {
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "x-error-codes": [
              "ip_not_allowed",
              "subscription_inactive",
              "account_inactive",
              "scope_missing"
            ]
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`job_not_found`: No job with this id in your organization.",
            "headers": {
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "x-error-codes": [
              "job_not_found"
            ]
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`job_not_finished`: The job is still queued or running.\n\n`job_failed`: The job failed; it has no result.\n\n`job_canceled`: The job was canceled; it has no result.",
            "headers": {
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "x-error-codes": [
              "job_not_finished",
              "job_failed",
              "job_canceled"
            ]
          },
          "410": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`result_expired`: The result passed the retention window and was deleted.",
            "headers": {
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "x-error-codes": [
              "result_expired"
            ]
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`rate_limited`: Too many requests in the current minute, hour or day (per key or per organization), or more than 60 failed authentications per minute from your IP address.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "x-error-codes": [
              "rate_limited"
            ]
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`internal_error`: Something failed on our side.",
            "headers": {
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "x-error-codes": [
              "internal_error"
            ]
          },
          "503": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`api_disabled`: The API is temporarily disabled (maintenance) or switched off for the organization.",
            "headers": {
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "x-error-codes": [
              "api_disabled"
            ]
          }
        },
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "summary": "Get a job result",
        "tags": [
          "Jobs"
        ],
        "x-example-note": "Abridged: 3 of the 58 placements are shown.",
        "x-example-request": {
          "path": {
            "id": "job_4bK9mT2xQe7LpW1zRc8VdN3f"
          }
        },
        "x-scope": "jobs:read",
        "x-scopes": [
          "jobs:read"
        ]
      }
    },
    "/v1/limits": {
      "get": {
        "description": "The limits that apply to your organization and the rate card new jobs are priced with.",
        "externalDocs": {
          "url": "https://runner.cargoduo.com/api/public/api-docs/pages/get-limits.md"
        },
        "operationId": "getLimits",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "example": {
                  "max_items_per_request": 2000,
                  "max_vehicles_per_request": 20,
                  "max_time_limit_seconds": 90,
                  "allowed_vehicle_types": [
                    "truck",
                    "trailer",
                    "container",
                    "pallet"
                  ],
                  "concurrency": 1,
                  "max_queued_jobs": 20,
                  "rate_limits": {
                    "per_minute": 60,
                    "per_hour": 1000,
                    "per_day": 5000
                  },
                  "retention_days": 14,
                  "rate_card": {
                    "version": 1,
                    "per_job": 0.06,
                    "per_vehicle": 0.2,
                    "per_compute_second": 0.005,
                    "large_load_threshold": 500,
                    "per_hundred_items_over": 0.02
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/Limits"
                }
              }
            },
            "description": "Limits and rate card.",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Limit of the tightest rate window.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix time (seconds) when that window resets.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`unauthorized`: Missing, malformed or unknown API key.\n\n`key_revoked`: The key was revoked.\n\n`key_expired`: The key passed its expiry date.",
            "headers": {
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "x-error-codes": [
              "unauthorized",
              "key_revoked",
              "key_expired"
            ]
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`ip_not_allowed`: The calling IP is not on the key's allowlist.\n\n`subscription_inactive`: The organization has no active subscription that includes the API.\n\n`account_inactive`: The organization is suspended, or has no owner whose account is active.\n\n`scope_missing`: The key lacks a scope this endpoint needs.",
            "headers": {
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "x-error-codes": [
              "ip_not_allowed",
              "subscription_inactive",
              "account_inactive",
              "scope_missing"
            ]
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`rate_limited`: Too many requests in the current minute, hour or day (per key or per organization), or more than 60 failed authentications per minute from your IP address.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "x-error-codes": [
              "rate_limited"
            ]
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`internal_error`: Something failed on our side.",
            "headers": {
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "x-error-codes": [
              "internal_error"
            ]
          },
          "503": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`api_disabled`: The API is temporarily disabled (maintenance) or switched off for the organization.",
            "headers": {
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "x-error-codes": [
              "api_disabled"
            ]
          }
        },
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "summary": "Get limits",
        "tags": [
          "Account"
        ],
        "x-example-request": {},
        "x-scope": "account:read",
        "x-scopes": [
          "account:read"
        ]
      }
    },
    "/v1/llms-full.txt": {
      "get": {
        "description": "The integration playbook for coding agents in one Markdown document. Public, no key.",
        "operationId": "getLLMsFullTxt",
        "responses": {
          "200": {
            "content": {
              "text/plain": {
                "schema": {
                  "type": "string"
                }
              }
            },
            "description": "Markdown."
          }
        },
        "security": [],
        "summary": "llms-full.txt",
        "tags": [
          "Docs"
        ]
      }
    },
    "/v1/llms.txt": {
      "get": {
        "description": "Markdown index of the docs for language models. Public, no key.",
        "operationId": "getLLMsTxt",
        "responses": {
          "200": {
            "content": {
              "text/plain": {
                "schema": {
                  "type": "string"
                }
              }
            },
            "description": "Markdown."
          }
        },
        "security": [],
        "summary": "llms.txt",
        "tags": [
          "Docs"
        ]
      }
    },
    "/v1/openapi.json": {
      "get": {
        "description": "This document. Public, no key.",
        "operationId": "getOpenAPI",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "OpenAPI 3.1 document."
          }
        },
        "security": [],
        "summary": "OpenAPI document",
        "tags": [
          "Docs"
        ]
      }
    },
    "/v1/pack": {
      "post": {
        "description": "Validates the request, reserves the worst-case price from your credits and queues a job. Answers 202 with the job; poll GET /v1/jobs/{id}, or pass ?wait= to hold the response until it ends. Validation failures (422) are free and create no job.",
        "externalDocs": {
          "url": "https://runner.cargoduo.com/api/public/api-docs/pages/create-pack-job.md"
        },
        "operationId": "createPackJob",
        "parameters": [
          {
            "description": "Seconds to hold the response for the job to finish. Finished in time: 200 with the result inlined. Otherwise: 202.",
            "in": "query",
            "name": "wait",
            "required": false,
            "schema": {
              "default": 0,
              "maximum": 60,
              "minimum": 0,
              "type": "integer"
            }
          },
          {
            "description": "Any unique string, such as a UUID or your order id. The same key within 24 h returns the original job instead of creating and charging a new one.",
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "maxLength": 128,
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "reference": "order-1042",
                "vehicles": [
                  {
                    "id": "trailer",
                    "type": "trailer",
                    "name": "13.6 m trailer",
                    "length": 1360,
                    "width": 245,
                    "height": 270,
                    "max_weight": 24000
                  }
                ],
                "items": [
                  {
                    "id": "pallet-eu",
                    "label": "Euro pallet",
                    "length": 120,
                    "width": 80,
                    "height": 140,
                    "weight": 450,
                    "quantity": 18,
                    "stackable": false
                  },
                  {
                    "id": "carton-a",
                    "label": "Carton A",
                    "length": 60,
                    "width": 40,
                    "height": 40,
                    "weight": 12,
                    "quantity": 40,
                    "rotation": "upright"
                  }
                ],
                "options": {
                  "packing_mode": "auto"
                }
              },
              "schema": {
                "$ref": "#/components/schemas/PackRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Job"
                }
              }
            },
            "description": "Job finished within ?wait, result inlined. Also an idempotent replay of a finished job.",
            "headers": {
              "X-Credits-Remaining": {
                "description": "Available credits after this request (decimal).",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Limit of the tightest rate window.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix time (seconds) when that window resets.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "202": {
            "content": {
              "application/json": {
                "example": {
                  "id": "job_4bK9mT2xQe7LpW1zRc8VdN3f",
                  "object": "job",
                  "status": "queued",
                  "reference": "order-1042",
                  "source": "api",
                  "created_at": "2026-10-19T09:12:03Z",
                  "started_at": null,
                  "finished_at": null,
                  "progress": {
                    "stage": "queued",
                    "vehicles_done": 0,
                    "placed_items": 0
                  },
                  "summary": {
                    "items_requested": 58,
                    "items_placed": 0,
                    "items_unplaced": 0,
                    "vehicles_used": 0,
                    "total_weight": 0,
                    "volume_utilization": 0,
                    "queue_ms": 0,
                    "compute_ms": 0
                  },
                  "cost": {
                    "credits": 0,
                    "reserved_credits": 1.11,
                    "rate_card_version": 1,
                    "breakdown": {
                      "base": 0,
                      "vehicles": 0,
                      "compute": 0,
                      "large_load": 0
                    }
                  },
                  "error": null,
                  "warnings": [],
                  "result_url": "https://runner.cargoduo.com/v1/jobs/job_4bK9mT2xQe7LpW1zRc8VdN3f/result",
                  "pdf_url": "",
                  "expires_at": "2026-11-02T09:12:03Z"
                },
                "schema": {
                  "$ref": "#/components/schemas/Job"
                }
              }
            },
            "description": "Job accepted (queued or running).",
            "headers": {
              "X-Credits-Remaining": {
                "description": "Available credits after this request (decimal).",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Limit of the tightest rate window.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix time (seconds) when that window resets.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`invalid_json`: The body is not valid JSON or a field has the wrong type.\n\n`idempotency_key_invalid`: The Idempotency-Key header is longer than 128 characters.",
            "headers": {
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "x-error-codes": [
              "invalid_json",
              "idempotency_key_invalid"
            ]
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`unauthorized`: Missing, malformed or unknown API key.\n\n`key_revoked`: The key was revoked.\n\n`key_expired`: The key passed its expiry date.",
            "headers": {
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "x-error-codes": [
              "unauthorized",
              "key_revoked",
              "key_expired"
            ]
          },
          "402": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`insufficient_credits`: Available credits do not cover the smallest possible run of this job.",
            "headers": {
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "x-error-codes": [
              "insufficient_credits"
            ]
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`ip_not_allowed`: The calling IP is not on the key's allowlist.\n\n`subscription_inactive`: The organization has no active subscription that includes the API.\n\n`account_inactive`: The organization is suspended, or has no owner whose account is active.\n\n`scope_missing`: The key lacks a scope this endpoint needs.",
            "headers": {
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "x-error-codes": [
              "ip_not_allowed",
              "subscription_inactive",
              "account_inactive",
              "scope_missing"
            ]
          },
          "413": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`payload_too_large`: The request body exceeds 10 MB.",
            "headers": {
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "x-error-codes": [
              "payload_too_large"
            ]
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`validation_failed`: The request is well-formed JSON but describes an invalid job. details[] lists every problem.",
            "headers": {
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "x-error-codes": [
              "validation_failed"
            ]
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`too_many_jobs`: The organization already has the maximum number of queued + running jobs.\n\n`rate_limited`: Too many requests in the current minute, hour or day (per key or per organization), or more than 60 failed authentications per minute from your IP address.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "x-error-codes": [
              "too_many_jobs",
              "rate_limited"
            ]
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`internal_error`: Something failed on our side.",
            "headers": {
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "x-error-codes": [
              "internal_error"
            ]
          },
          "503": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`api_disabled`: The API is temporarily disabled (maintenance) or switched off for the organization.",
            "headers": {
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "x-error-codes": [
              "api_disabled"
            ]
          }
        },
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "summary": "Create a packing job",
        "tags": [
          "Pack"
        ],
        "x-example-request": {
          "headers": {
            "Idempotency-Key": "order-1042-v1"
          }
        },
        "x-scope": "pack:write",
        "x-scopes": [
          "pack:write"
        ]
      }
    },
    "/v1/projects": {
      "get": {
        "description": "Your organization's projects (the app's load plans), newest first, one page at a time. Free: no credits are charged.",
        "externalDocs": {
          "url": "https://runner.cargoduo.com/api/public/api-docs/pages/list-projects.md"
        },
        "operationId": "listProjects",
        "parameters": [
          {
            "description": "Page size.",
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": {
              "default": 20,
              "maximum": 100,
              "minimum": 1,
              "type": "integer"
            }
          },
          {
            "description": "next_cursor of the previous page.",
            "in": "query",
            "name": "cursor",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Only projects whose name contains this text.",
            "in": "query",
            "name": "q",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Only what this member created: `me` (the key's creator) or a member id (`usr_…`).",
            "in": "query",
            "name": "created_by",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "example": {
                  "data": [
                    {
                      "id": "prj_3051",
                      "object": "project",
                      "name": "Order 1042",
                      "status": "calculated",
                      "item_count": 58,
                      "vehicle_count": 1,
                      "app_url": "https://app.cargoduo.com/projects/3051",
                      "created_by": {
                        "id": "usr_7",
                        "name": "Elif Kaya"
                      },
                      "updated_by": {
                        "id": "usr_7",
                        "name": "Elif Kaya"
                      },
                      "created_at": "2026-10-19T09:10:03Z",
                      "updated_at": "2026-10-19T09:12:07Z"
                    },
                    {
                      "id": "prj_3048",
                      "object": "project",
                      "name": "Order 1039",
                      "status": "draft",
                      "item_count": 24,
                      "vehicle_count": 1,
                      "app_url": "https://app.cargoduo.com/projects/3048",
                      "created_by": {
                        "id": "usr_7",
                        "name": "Elif Kaya"
                      },
                      "updated_by": {
                        "id": "usr_7",
                        "name": "Elif Kaya"
                      },
                      "created_at": "2026-10-17T07:12:03Z",
                      "updated_at": "2026-10-17T07:12:03Z"
                    }
                  ],
                  "next_cursor": "prj_3048"
                },
                "schema": {
                  "$ref": "#/components/schemas/ProjectList"
                }
              }
            },
            "description": "One page of projects.",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Limit of the tightest rate window.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix time (seconds) when that window resets.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`unauthorized`: Missing, malformed or unknown API key.\n\n`key_revoked`: The key was revoked.\n\n`key_expired`: The key passed its expiry date.",
            "headers": {
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "x-error-codes": [
              "unauthorized",
              "key_revoked",
              "key_expired"
            ]
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`ip_not_allowed`: The calling IP is not on the key's allowlist.\n\n`subscription_inactive`: The organization has no active subscription that includes the API.\n\n`account_inactive`: The organization is suspended, or has no owner whose account is active.\n\n`scope_missing`: The key lacks a scope this endpoint needs.",
            "headers": {
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "x-error-codes": [
              "ip_not_allowed",
              "subscription_inactive",
              "account_inactive",
              "scope_missing"
            ]
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`validation_failed`: The request is well-formed JSON but describes an invalid job. details[] lists every problem.",
            "headers": {
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "x-error-codes": [
              "validation_failed"
            ]
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`rate_limited`: Too many requests in the current minute, hour or day (per key or per organization), or more than 60 failed authentications per minute from your IP address.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "x-error-codes": [
              "rate_limited"
            ]
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`internal_error`: Something failed on our side.",
            "headers": {
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "x-error-codes": [
              "internal_error"
            ]
          },
          "503": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`api_disabled`: The API is temporarily disabled (maintenance) or switched off for the organization.",
            "headers": {
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "x-error-codes": [
              "api_disabled"
            ]
          }
        },
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "summary": "List projects",
        "tags": [
          "Projects"
        ],
        "x-example-request": {
          "query": {
            "limit": 2,
            "created_by": "me"
          }
        },
        "x-scope": "resources:read",
        "x-scopes": [
          "resources:read"
        ]
      },
      "post": {
        "description": "Creates a project that opens in the app: a name, and optionally vehicles (saved vehicles by vehicle_id), items and groups in the /v1/pack shapes and the stored options. Pack it with POST /v1/projects/{id}/pack. Free: no credits are charged.",
        "externalDocs": {
          "url": "https://runner.cargoduo.com/api/public/api-docs/pages/create-project.md"
        },
        "operationId": "createProject",
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "name": "Order 1042",
                "vehicles": [
                  {
                    "vehicle_id": "standard-trailer-13-6m"
                  }
                ],
                "items": [
                  {
                    "template_id": "tpl_42",
                    "quantity": 18
                  },
                  {
                    "template_id": "tpl_43",
                    "quantity": 40
                  }
                ]
              },
              "schema": {
                "$ref": "#/components/schemas/ProjectInput"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "example": {
                  "id": "prj_3051",
                  "object": "project",
                  "name": "Order 1042",
                  "status": "draft",
                  "item_count": 58,
                  "vehicle_count": 1,
                  "app_url": "https://app.cargoduo.com/projects/3051",
                  "created_by": {
                    "id": "usr_7",
                    "name": "Elif Kaya"
                  },
                  "updated_by": {
                    "id": "usr_7",
                    "name": "Elif Kaya"
                  },
                  "created_at": "2026-10-19T09:10:03Z",
                  "updated_at": "2026-10-19T09:10:03Z",
                  "options": {
                    "packing_mode": "auto",
                    "group_routing": "none",
                    "allow_overweight": false
                  },
                  "vehicles": [
                    {
                      "id": "pv_5120",
                      "vehicle_id": "standard-trailer-13-6m",
                      "name": "Standard Trailer (13.6m)",
                      "type": "trailer",
                      "quantity": 1,
                      "length": 1362,
                      "width": 248,
                      "height": 270,
                      "max_weight": 24000
                    }
                  ],
                  "items": [
                    {
                      "id": "item_88410",
                      "label": "Euro pallet",
                      "shape": "box",
                      "length": 120,
                      "width": 80,
                      "height": 140,
                      "weight": 450,
                      "quantity": 18,
                      "stackable": false,
                      "rotation": "all",
                      "color": "#3b82f6"
                    },
                    {
                      "id": "item_88411",
                      "label": "Carton A",
                      "shape": "box",
                      "length": 60,
                      "width": 40,
                      "height": 40,
                      "weight": 12,
                      "quantity": 40,
                      "stackable": true,
                      "rotation": "upright",
                      "color": "#f59e0b"
                    }
                  ],
                  "groups": [],
                  "plan": null
                },
                "schema": {
                  "$ref": "#/components/schemas/Project"
                }
              }
            },
            "description": "The new project.",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Limit of the tightest rate window.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix time (seconds) when that window resets.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`invalid_json`: The body is not valid JSON or a field has the wrong type.",
            "headers": {
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "x-error-codes": [
              "invalid_json"
            ]
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`unauthorized`: Missing, malformed or unknown API key.\n\n`key_revoked`: The key was revoked.\n\n`key_expired`: The key passed its expiry date.",
            "headers": {
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "x-error-codes": [
              "unauthorized",
              "key_revoked",
              "key_expired"
            ]
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`plan_limit_reached`: The organization's plan allows no more projects or cargo items.\n\n`ip_not_allowed`: The calling IP is not on the key's allowlist.\n\n`subscription_inactive`: The organization has no active subscription that includes the API.\n\n`account_inactive`: The organization is suspended, or has no owner whose account is active.\n\n`scope_missing`: The key lacks a scope this endpoint needs.",
            "headers": {
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "x-error-codes": [
              "plan_limit_reached",
              "ip_not_allowed",
              "subscription_inactive",
              "account_inactive",
              "scope_missing"
            ]
          },
          "413": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`payload_too_large`: The request body exceeds 10 MB.",
            "headers": {
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "x-error-codes": [
              "payload_too_large"
            ]
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`validation_failed`: The request is well-formed JSON but describes an invalid job. details[] lists every problem.",
            "headers": {
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "x-error-codes": [
              "validation_failed"
            ]
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`rate_limited`: Too many requests in the current minute, hour or day (per key or per organization), or more than 60 failed authentications per minute from your IP address.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "x-error-codes": [
              "rate_limited"
            ]
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`internal_error`: Something failed on our side.",
            "headers": {
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "x-error-codes": [
              "internal_error"
            ]
          },
          "503": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`api_disabled`: The API is temporarily disabled (maintenance) or switched off for the organization.",
            "headers": {
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "x-error-codes": [
              "api_disabled"
            ]
          }
        },
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "summary": "Create a project",
        "tags": [
          "Projects"
        ],
        "x-example-request": {},
        "x-scope": "resources:write",
        "x-scopes": [
          "resources:write"
        ]
      }
    },
    "/v1/projects/{id}": {
      "delete": {
        "description": "Deletes a project with its vehicles, items and plan history, in the app too. Free: no credits are charged.",
        "externalDocs": {
          "url": "https://runner.cargoduo.com/api/public/api-docs/pages/delete-project.md"
        },
        "operationId": "deleteProject",
        "parameters": [
          {
            "description": "Project id (prj_…).",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "example": {
                  "id": "prj_3051",
                  "object": "project",
                  "deleted": true
                },
                "schema": {
                  "$ref": "#/components/schemas/Deleted"
                }
              }
            },
            "description": "Deleted.",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Limit of the tightest rate window.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix time (seconds) when that window resets.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`unauthorized`: Missing, malformed or unknown API key.\n\n`key_revoked`: The key was revoked.\n\n`key_expired`: The key passed its expiry date.",
            "headers": {
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "x-error-codes": [
              "unauthorized",
              "key_revoked",
              "key_expired"
            ]
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`ip_not_allowed`: The calling IP is not on the key's allowlist.\n\n`subscription_inactive`: The organization has no active subscription that includes the API.\n\n`account_inactive`: The organization is suspended, or has no owner whose account is active.\n\n`scope_missing`: The key lacks a scope this endpoint needs.",
            "headers": {
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "x-error-codes": [
              "ip_not_allowed",
              "subscription_inactive",
              "account_inactive",
              "scope_missing"
            ]
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`project_not_found`: No project with this id in your organization.",
            "headers": {
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "x-error-codes": [
              "project_not_found"
            ]
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`rate_limited`: Too many requests in the current minute, hour or day (per key or per organization), or more than 60 failed authentications per minute from your IP address.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "x-error-codes": [
              "rate_limited"
            ]
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`internal_error`: Something failed on our side.",
            "headers": {
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "x-error-codes": [
              "internal_error"
            ]
          },
          "503": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`api_disabled`: The API is temporarily disabled (maintenance) or switched off for the organization.",
            "headers": {
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "x-error-codes": [
              "api_disabled"
            ]
          }
        },
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "summary": "Delete a project",
        "tags": [
          "Projects"
        ],
        "x-example-request": {
          "path": {
            "id": "prj_3051"
          }
        },
        "x-scope": "resources:write",
        "x-scopes": [
          "resources:write"
        ]
      },
      "get": {
        "description": "A project with its vehicles, items, groups, options and a summary of its current plan (with the PDF link while the plan is the one an API job saved). Free: no credits are charged.",
        "externalDocs": {
          "url": "https://runner.cargoduo.com/api/public/api-docs/pages/get-project.md"
        },
        "operationId": "getProject",
        "parameters": [
          {
            "description": "Project id (prj_…).",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "example": {
                  "id": "prj_3051",
                  "object": "project",
                  "name": "Order 1042",
                  "status": "calculated",
                  "item_count": 58,
                  "vehicle_count": 1,
                  "app_url": "https://app.cargoduo.com/projects/3051",
                  "created_by": {
                    "id": "usr_7",
                    "name": "Elif Kaya"
                  },
                  "updated_by": {
                    "id": "usr_7",
                    "name": "Elif Kaya"
                  },
                  "created_at": "2026-10-19T09:10:03Z",
                  "updated_at": "2026-10-19T09:12:07Z",
                  "options": {
                    "packing_mode": "auto",
                    "group_routing": "none",
                    "allow_overweight": false
                  },
                  "vehicles": [
                    {
                      "id": "pv_5120",
                      "vehicle_id": "standard-trailer-13-6m",
                      "name": "Standard Trailer (13.6m)",
                      "type": "trailer",
                      "quantity": 1,
                      "length": 1362,
                      "width": 248,
                      "height": 270,
                      "max_weight": 24000
                    }
                  ],
                  "items": [
                    {
                      "id": "item_88410",
                      "label": "Euro pallet",
                      "shape": "box",
                      "length": 120,
                      "width": 80,
                      "height": 140,
                      "weight": 450,
                      "quantity": 18,
                      "stackable": false,
                      "rotation": "all",
                      "color": "#3b82f6"
                    },
                    {
                      "id": "item_88411",
                      "label": "Carton A",
                      "shape": "box",
                      "length": 60,
                      "width": 40,
                      "height": 40,
                      "weight": 12,
                      "quantity": 40,
                      "stackable": true,
                      "rotation": "upright",
                      "color": "#f59e0b"
                    }
                  ],
                  "groups": [],
                  "plan": {
                    "items_placed": 58,
                    "items_unplaced": 0,
                    "vehicles_used": 1,
                    "total_weight": 8580,
                    "volume_utilization": 0.3116,
                    "job_id": "job_4bK9mT2xQe7LpW1zRc8VdN3f",
                    "pdf_url": "https://app.cargoduo.com/r/Xq7Lm2Vt9KbR4cN8wZp1Hs6Yd3Fg5Jk0Ta2Ue7Wn4Ci"
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/Project"
                }
              }
            },
            "description": "The project.",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Limit of the tightest rate window.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix time (seconds) when that window resets.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`unauthorized`: Missing, malformed or unknown API key.\n\n`key_revoked`: The key was revoked.\n\n`key_expired`: The key passed its expiry date.",
            "headers": {
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "x-error-codes": [
              "unauthorized",
              "key_revoked",
              "key_expired"
            ]
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`ip_not_allowed`: The calling IP is not on the key's allowlist.\n\n`subscription_inactive`: The organization has no active subscription that includes the API.\n\n`account_inactive`: The organization is suspended, or has no owner whose account is active.\n\n`scope_missing`: The key lacks a scope this endpoint needs.",
            "headers": {
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "x-error-codes": [
              "ip_not_allowed",
              "subscription_inactive",
              "account_inactive",
              "scope_missing"
            ]
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`project_not_found`: No project with this id in your organization.",
            "headers": {
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "x-error-codes": [
              "project_not_found"
            ]
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`rate_limited`: Too many requests in the current minute, hour or day (per key or per organization), or more than 60 failed authentications per minute from your IP address.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "x-error-codes": [
              "rate_limited"
            ]
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`internal_error`: Something failed on our side.",
            "headers": {
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "x-error-codes": [
              "internal_error"
            ]
          },
          "503": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`api_disabled`: The API is temporarily disabled (maintenance) or switched off for the organization.",
            "headers": {
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "x-error-codes": [
              "api_disabled"
            ]
          }
        },
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "summary": "Get a project",
        "tags": [
          "Projects"
        ],
        "x-example-request": {
          "path": {
            "id": "prj_3051"
          }
        },
        "x-scope": "resources:read",
        "x-scopes": [
          "resources:read"
        ]
      },
      "patch": {
        "description": "Renames a project, changes its options, or replaces its vehicles or its items (with groups). Replacing vehicles or items clears the stored plan; open app sessions reload. Free: no credits are charged.",
        "externalDocs": {
          "url": "https://runner.cargoduo.com/api/public/api-docs/pages/update-project.md"
        },
        "operationId": "updateProject",
        "parameters": [
          {
            "description": "Project id (prj_…).",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "vehicles": [
                  {
                    "vehicle_id": "veh_118",
                    "quantity": 2
                  }
                ]
              },
              "schema": {
                "$ref": "#/components/schemas/ProjectUpdate"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "example": {
                  "id": "prj_3051",
                  "object": "project",
                  "name": "Order 1042",
                  "status": "draft",
                  "item_count": 58,
                  "vehicle_count": 2,
                  "app_url": "https://app.cargoduo.com/projects/3051",
                  "created_by": {
                    "id": "usr_7",
                    "name": "Elif Kaya"
                  },
                  "updated_by": {
                    "id": "usr_7",
                    "name": "Elif Kaya"
                  },
                  "created_at": "2026-10-19T09:10:03Z",
                  "updated_at": "2026-10-19T09:22:03Z",
                  "options": {
                    "packing_mode": "auto",
                    "group_routing": "none",
                    "allow_overweight": false
                  },
                  "vehicles": [
                    {
                      "id": "pv_5121",
                      "vehicle_id": "veh_118",
                      "name": "Mega trailer 13.6 m",
                      "type": "trailer",
                      "quantity": 2,
                      "length": 1360,
                      "width": 248,
                      "height": 300,
                      "max_weight": 24000
                    }
                  ],
                  "items": [
                    {
                      "id": "item_88410",
                      "label": "Euro pallet",
                      "shape": "box",
                      "length": 120,
                      "width": 80,
                      "height": 140,
                      "weight": 450,
                      "quantity": 18,
                      "stackable": false,
                      "rotation": "all",
                      "color": "#3b82f6"
                    },
                    {
                      "id": "item_88411",
                      "label": "Carton A",
                      "shape": "box",
                      "length": 60,
                      "width": 40,
                      "height": 40,
                      "weight": 12,
                      "quantity": 40,
                      "stackable": true,
                      "rotation": "upright",
                      "color": "#f59e0b"
                    }
                  ],
                  "groups": [],
                  "plan": null
                },
                "schema": {
                  "$ref": "#/components/schemas/Project"
                }
              }
            },
            "description": "The project after the change.",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Limit of the tightest rate window.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix time (seconds) when that window resets.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`invalid_json`: The body is not valid JSON or a field has the wrong type.",
            "headers": {
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "x-error-codes": [
              "invalid_json"
            ]
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`unauthorized`: Missing, malformed or unknown API key.\n\n`key_revoked`: The key was revoked.\n\n`key_expired`: The key passed its expiry date.",
            "headers": {
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "x-error-codes": [
              "unauthorized",
              "key_revoked",
              "key_expired"
            ]
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`plan_limit_reached`: The organization's plan allows no more projects or cargo items.\n\n`ip_not_allowed`: The calling IP is not on the key's allowlist.\n\n`subscription_inactive`: The organization has no active subscription that includes the API.\n\n`account_inactive`: The organization is suspended, or has no owner whose account is active.\n\n`scope_missing`: The key lacks a scope this endpoint needs.",
            "headers": {
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "x-error-codes": [
              "plan_limit_reached",
              "ip_not_allowed",
              "subscription_inactive",
              "account_inactive",
              "scope_missing"
            ]
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`project_not_found`: No project with this id in your organization.",
            "headers": {
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "x-error-codes": [
              "project_not_found"
            ]
          },
          "413": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`payload_too_large`: The request body exceeds 10 MB.",
            "headers": {
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "x-error-codes": [
              "payload_too_large"
            ]
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`validation_failed`: The request is well-formed JSON but describes an invalid job. details[] lists every problem.",
            "headers": {
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "x-error-codes": [
              "validation_failed"
            ]
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`rate_limited`: Too many requests in the current minute, hour or day (per key or per organization), or more than 60 failed authentications per minute from your IP address.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "x-error-codes": [
              "rate_limited"
            ]
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`internal_error`: Something failed on our side.",
            "headers": {
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "x-error-codes": [
              "internal_error"
            ]
          },
          "503": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`api_disabled`: The API is temporarily disabled (maintenance) or switched off for the organization.",
            "headers": {
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "x-error-codes": [
              "api_disabled"
            ]
          }
        },
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "summary": "Update a project",
        "tags": [
          "Projects"
        ],
        "x-example-request": {
          "path": {
            "id": "prj_3051"
          }
        },
        "x-scope": "resources:write",
        "x-scopes": [
          "resources:write"
        ]
      }
    },
    "/v1/projects/{id}/pack": {
      "post": {
        "description": "Packs the project's vehicles and items exactly like POST /v1/pack: same price, credit reservation, limits, Idempotency-Key, ?wait= and job. When the job succeeds its plan is saved into the project, which then opens in the app with that plan. If the project changed while the job ran, the plan stays on the job only (warning project_not_saved). Result ids are the project's: vehicle_id is the slot id (pv_…), item_id the item id (item_…).",
        "externalDocs": {
          "url": "https://runner.cargoduo.com/api/public/api-docs/pages/pack-project.md"
        },
        "operationId": "packProject",
        "parameters": [
          {
            "description": "Project id (prj_…).",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Seconds to hold the response for the job to finish. Finished in time: 200 with the result inlined. Otherwise: 202.",
            "in": "query",
            "name": "wait",
            "required": false,
            "schema": {
              "default": 0,
              "maximum": 60,
              "minimum": 0,
              "type": "integer"
            }
          },
          {
            "description": "Any unique string, such as a UUID or your order id. The same key within 24 h returns the original job instead of creating and charging a new one.",
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "maxLength": 128,
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "reference": "order-1042"
              },
              "schema": {
                "$ref": "#/components/schemas/ProjectPackRequest"
              }
            }
          },
          "required": false
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Job"
                }
              }
            },
            "description": "Job finished within ?wait, result inlined. Also an idempotent replay of a finished job.",
            "headers": {
              "X-Credits-Remaining": {
                "description": "Available credits after this request (decimal).",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Limit of the tightest rate window.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix time (seconds) when that window resets.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "202": {
            "content": {
              "application/json": {
                "example": {
                  "id": "job_4bK9mT2xQe7LpW1zRc8VdN3f",
                  "object": "job",
                  "status": "queued",
                  "reference": "order-1042",
                  "source": "api",
                  "project_id": "prj_3051",
                  "created_at": "2026-10-19T09:12:03Z",
                  "started_at": null,
                  "finished_at": null,
                  "progress": {
                    "stage": "queued",
                    "vehicles_done": 0,
                    "placed_items": 0
                  },
                  "summary": {
                    "items_requested": 58,
                    "items_placed": 0,
                    "items_unplaced": 0,
                    "vehicles_used": 0,
                    "total_weight": 0,
                    "volume_utilization": 0,
                    "queue_ms": 0,
                    "compute_ms": 0
                  },
                  "cost": {
                    "credits": 0,
                    "reserved_credits": 1.11,
                    "rate_card_version": 1,
                    "breakdown": {
                      "base": 0,
                      "vehicles": 0,
                      "compute": 0,
                      "large_load": 0
                    }
                  },
                  "error": null,
                  "warnings": [],
                  "result_url": "https://runner.cargoduo.com/v1/jobs/job_4bK9mT2xQe7LpW1zRc8VdN3f/result",
                  "pdf_url": "",
                  "expires_at": "2026-11-02T09:12:03Z"
                },
                "schema": {
                  "$ref": "#/components/schemas/Job"
                }
              }
            },
            "description": "Job accepted (queued or running).",
            "headers": {
              "X-Credits-Remaining": {
                "description": "Available credits after this request (decimal).",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Limit of the tightest rate window.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix time (seconds) when that window resets.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`invalid_json`: The body is not valid JSON or a field has the wrong type.\n\n`idempotency_key_invalid`: The Idempotency-Key header is longer than 128 characters.",
            "headers": {
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "x-error-codes": [
              "invalid_json",
              "idempotency_key_invalid"
            ]
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`unauthorized`: Missing, malformed or unknown API key.\n\n`key_revoked`: The key was revoked.\n\n`key_expired`: The key passed its expiry date.",
            "headers": {
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "x-error-codes": [
              "unauthorized",
              "key_revoked",
              "key_expired"
            ]
          },
          "402": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`insufficient_credits`: Available credits do not cover the smallest possible run of this job.",
            "headers": {
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "x-error-codes": [
              "insufficient_credits"
            ]
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`ip_not_allowed`: The calling IP is not on the key's allowlist.\n\n`subscription_inactive`: The organization has no active subscription that includes the API.\n\n`account_inactive`: The organization is suspended, or has no owner whose account is active.\n\n`scope_missing`: The key lacks a scope this endpoint needs.",
            "headers": {
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "x-error-codes": [
              "ip_not_allowed",
              "subscription_inactive",
              "account_inactive",
              "scope_missing"
            ]
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`project_not_found`: No project with this id in your organization.",
            "headers": {
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "x-error-codes": [
              "project_not_found"
            ]
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`project_busy`: The project is being packed right now (in the app or by another job).",
            "headers": {
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "x-error-codes": [
              "project_busy"
            ]
          },
          "413": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`payload_too_large`: The request body exceeds 10 MB.",
            "headers": {
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "x-error-codes": [
              "payload_too_large"
            ]
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`validation_failed`: The request is well-formed JSON but describes an invalid job. details[] lists every problem.",
            "headers": {
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "x-error-codes": [
              "validation_failed"
            ]
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`too_many_jobs`: The organization already has the maximum number of queued + running jobs.\n\n`rate_limited`: Too many requests in the current minute, hour or day (per key or per organization), or more than 60 failed authentications per minute from your IP address.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "x-error-codes": [
              "too_many_jobs",
              "rate_limited"
            ]
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`internal_error`: Something failed on our side.",
            "headers": {
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "x-error-codes": [
              "internal_error"
            ]
          },
          "503": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`api_disabled`: The API is temporarily disabled (maintenance) or switched off for the organization.",
            "headers": {
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "x-error-codes": [
              "api_disabled"
            ]
          }
        },
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "summary": "Pack a project",
        "tags": [
          "Projects"
        ],
        "x-example-request": {
          "headers": {
            "Idempotency-Key": "order-1042-v1"
          },
          "path": {
            "id": "prj_3051"
          }
        },
        "x-scope": "pack:write resources:write",
        "x-scopes": [
          "pack:write",
          "resources:write"
        ]
      }
    },
    "/v1/templates": {
      "get": {
        "description": "Your organization's cargo templates (saved items), newest first. Name one in an item with template_id. Free: no credits are charged.",
        "externalDocs": {
          "url": "https://runner.cargoduo.com/api/public/api-docs/pages/list-templates.md"
        },
        "operationId": "listTemplates",
        "parameters": [
          {
            "description": "Page size.",
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": {
              "default": 20,
              "maximum": 100,
              "minimum": 1,
              "type": "integer"
            }
          },
          {
            "description": "next_cursor of the previous page.",
            "in": "query",
            "name": "cursor",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Only templates whose label contains this text.",
            "in": "query",
            "name": "q",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Only what this member created: `me` (the key's creator) or a member id (`usr_…`).",
            "in": "query",
            "name": "created_by",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "example": {
                  "data": [
                    {
                      "id": "tpl_43",
                      "object": "template",
                      "label": "Carton A",
                      "shape": "box",
                      "length": 60,
                      "width": 40,
                      "height": 40,
                      "radius": 0,
                      "weight": 12,
                      "stackable": true,
                      "max_stack_weight": 0,
                      "rotation": "upright",
                      "hazardous": false,
                      "priority": 0,
                      "color": "#f59e0b",
                      "nesting_height": 0,
                      "created_by": {
                        "id": "usr_7",
                        "name": "Elif Kaya"
                      },
                      "updated_by": {
                        "id": "usr_7",
                        "name": "Elif Kaya"
                      },
                      "created_at": "2026-09-28T14:05:52Z",
                      "updated_at": "2026-09-28T14:05:52Z"
                    },
                    {
                      "id": "tpl_42",
                      "object": "template",
                      "label": "Euro pallet",
                      "shape": "box",
                      "length": 120,
                      "width": 80,
                      "height": 140,
                      "radius": 0,
                      "weight": 450,
                      "stackable": false,
                      "max_stack_weight": 0,
                      "rotation": "all",
                      "hazardous": false,
                      "priority": 0,
                      "color": "#3b82f6",
                      "nesting_height": 0,
                      "created_by": {
                        "id": "usr_7",
                        "name": "Elif Kaya"
                      },
                      "updated_by": {
                        "id": "usr_7",
                        "name": "Elif Kaya"
                      },
                      "created_at": "2026-09-28T14:05:52Z",
                      "updated_at": "2026-09-28T14:05:52Z"
                    }
                  ],
                  "next_cursor": ""
                },
                "schema": {
                  "$ref": "#/components/schemas/TemplateList"
                }
              }
            },
            "description": "One page of templates.",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Limit of the tightest rate window.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix time (seconds) when that window resets.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`unauthorized`: Missing, malformed or unknown API key.\n\n`key_revoked`: The key was revoked.\n\n`key_expired`: The key passed its expiry date.",
            "headers": {
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "x-error-codes": [
              "unauthorized",
              "key_revoked",
              "key_expired"
            ]
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`ip_not_allowed`: The calling IP is not on the key's allowlist.\n\n`subscription_inactive`: The organization has no active subscription that includes the API.\n\n`account_inactive`: The organization is suspended, or has no owner whose account is active.\n\n`scope_missing`: The key lacks a scope this endpoint needs.",
            "headers": {
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "x-error-codes": [
              "ip_not_allowed",
              "subscription_inactive",
              "account_inactive",
              "scope_missing"
            ]
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`validation_failed`: The request is well-formed JSON but describes an invalid job. details[] lists every problem.",
            "headers": {
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "x-error-codes": [
              "validation_failed"
            ]
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`rate_limited`: Too many requests in the current minute, hour or day (per key or per organization), or more than 60 failed authentications per minute from your IP address.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "x-error-codes": [
              "rate_limited"
            ]
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`internal_error`: Something failed on our side.",
            "headers": {
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "x-error-codes": [
              "internal_error"
            ]
          },
          "503": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`api_disabled`: The API is temporarily disabled (maintenance) or switched off for the organization.",
            "headers": {
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "x-error-codes": [
              "api_disabled"
            ]
          }
        },
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "summary": "List templates",
        "tags": [
          "Templates"
        ],
        "x-example-request": {
          "query": {
            "created_by": "me"
          }
        },
        "x-scope": "resources:read",
        "x-scopes": [
          "resources:read"
        ]
      },
      "post": {
        "description": "Saves an item as a template (it shows in the app too). Same fields and checks as a /v1/pack item. Free: no credits are charged.",
        "externalDocs": {
          "url": "https://runner.cargoduo.com/api/public/api-docs/pages/create-template.md"
        },
        "operationId": "createTemplate",
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "label": "Euro pallet",
                "length": 120,
                "width": 80,
                "height": 140,
                "weight": 450,
                "stackable": false,
                "color": "#3b82f6"
              },
              "schema": {
                "$ref": "#/components/schemas/TemplateInput"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "example": {
                  "id": "tpl_42",
                  "object": "template",
                  "label": "Euro pallet",
                  "shape": "box",
                  "length": 120,
                  "width": 80,
                  "height": 140,
                  "radius": 0,
                  "weight": 450,
                  "stackable": false,
                  "max_stack_weight": 0,
                  "rotation": "all",
                  "hazardous": false,
                  "priority": 0,
                  "color": "#3b82f6",
                  "nesting_height": 0,
                  "created_by": {
                    "id": "usr_7",
                    "name": "Elif Kaya"
                  },
                  "updated_by": {
                    "id": "usr_7",
                    "name": "Elif Kaya"
                  },
                  "created_at": "2026-09-28T14:05:52Z",
                  "updated_at": "2026-09-28T14:05:52Z"
                },
                "schema": {
                  "$ref": "#/components/schemas/Template"
                }
              }
            },
            "description": "The new template.",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Limit of the tightest rate window.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix time (seconds) when that window resets.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`invalid_json`: The body is not valid JSON or a field has the wrong type.",
            "headers": {
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "x-error-codes": [
              "invalid_json"
            ]
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`unauthorized`: Missing, malformed or unknown API key.\n\n`key_revoked`: The key was revoked.\n\n`key_expired`: The key passed its expiry date.",
            "headers": {
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "x-error-codes": [
              "unauthorized",
              "key_revoked",
              "key_expired"
            ]
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`ip_not_allowed`: The calling IP is not on the key's allowlist.\n\n`subscription_inactive`: The organization has no active subscription that includes the API.\n\n`account_inactive`: The organization is suspended, or has no owner whose account is active.\n\n`scope_missing`: The key lacks a scope this endpoint needs.",
            "headers": {
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "x-error-codes": [
              "ip_not_allowed",
              "subscription_inactive",
              "account_inactive",
              "scope_missing"
            ]
          },
          "413": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`payload_too_large`: The request body exceeds 10 MB.",
            "headers": {
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "x-error-codes": [
              "payload_too_large"
            ]
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`validation_failed`: The request is well-formed JSON but describes an invalid job. details[] lists every problem.",
            "headers": {
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "x-error-codes": [
              "validation_failed"
            ]
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`rate_limited`: Too many requests in the current minute, hour or day (per key or per organization), or more than 60 failed authentications per minute from your IP address.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "x-error-codes": [
              "rate_limited"
            ]
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`internal_error`: Something failed on our side.",
            "headers": {
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "x-error-codes": [
              "internal_error"
            ]
          },
          "503": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`api_disabled`: The API is temporarily disabled (maintenance) or switched off for the organization.",
            "headers": {
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "x-error-codes": [
              "api_disabled"
            ]
          }
        },
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "summary": "Create a template",
        "tags": [
          "Templates"
        ],
        "x-example-request": {},
        "x-scope": "resources:write",
        "x-scopes": [
          "resources:write"
        ]
      }
    },
    "/v1/templates/{id}": {
      "delete": {
        "description": "Deletes a template. Items already in projects stay. Free: no credits are charged.",
        "externalDocs": {
          "url": "https://runner.cargoduo.com/api/public/api-docs/pages/delete-template.md"
        },
        "operationId": "deleteTemplate",
        "parameters": [
          {
            "description": "Template id (tpl_…).",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "example": {
                  "id": "tpl_42",
                  "object": "template",
                  "deleted": true
                },
                "schema": {
                  "$ref": "#/components/schemas/Deleted"
                }
              }
            },
            "description": "Deleted.",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Limit of the tightest rate window.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix time (seconds) when that window resets.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`unauthorized`: Missing, malformed or unknown API key.\n\n`key_revoked`: The key was revoked.\n\n`key_expired`: The key passed its expiry date.",
            "headers": {
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "x-error-codes": [
              "unauthorized",
              "key_revoked",
              "key_expired"
            ]
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`ip_not_allowed`: The calling IP is not on the key's allowlist.\n\n`subscription_inactive`: The organization has no active subscription that includes the API.\n\n`account_inactive`: The organization is suspended, or has no owner whose account is active.\n\n`scope_missing`: The key lacks a scope this endpoint needs.",
            "headers": {
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "x-error-codes": [
              "ip_not_allowed",
              "subscription_inactive",
              "account_inactive",
              "scope_missing"
            ]
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`template_not_found`: No template with this id in your organization.",
            "headers": {
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "x-error-codes": [
              "template_not_found"
            ]
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`rate_limited`: Too many requests in the current minute, hour or day (per key or per organization), or more than 60 failed authentications per minute from your IP address.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "x-error-codes": [
              "rate_limited"
            ]
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`internal_error`: Something failed on our side.",
            "headers": {
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "x-error-codes": [
              "internal_error"
            ]
          },
          "503": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`api_disabled`: The API is temporarily disabled (maintenance) or switched off for the organization.",
            "headers": {
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "x-error-codes": [
              "api_disabled"
            ]
          }
        },
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "summary": "Delete a template",
        "tags": [
          "Templates"
        ],
        "x-example-request": {
          "path": {
            "id": "tpl_42"
          }
        },
        "x-scope": "resources:write",
        "x-scopes": [
          "resources:write"
        ]
      },
      "get": {
        "description": "One template. Free: no credits are charged.",
        "externalDocs": {
          "url": "https://runner.cargoduo.com/api/public/api-docs/pages/get-template.md"
        },
        "operationId": "getTemplate",
        "parameters": [
          {
            "description": "Template id (tpl_…).",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "example": {
                  "id": "tpl_42",
                  "object": "template",
                  "label": "Euro pallet",
                  "shape": "box",
                  "length": 120,
                  "width": 80,
                  "height": 140,
                  "radius": 0,
                  "weight": 450,
                  "stackable": false,
                  "max_stack_weight": 0,
                  "rotation": "all",
                  "hazardous": false,
                  "priority": 0,
                  "color": "#3b82f6",
                  "nesting_height": 0,
                  "created_by": {
                    "id": "usr_7",
                    "name": "Elif Kaya"
                  },
                  "updated_by": {
                    "id": "usr_7",
                    "name": "Elif Kaya"
                  },
                  "created_at": "2026-09-28T14:05:52Z",
                  "updated_at": "2026-09-28T14:05:52Z"
                },
                "schema": {
                  "$ref": "#/components/schemas/Template"
                }
              }
            },
            "description": "The template.",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Limit of the tightest rate window.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix time (seconds) when that window resets.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`unauthorized`: Missing, malformed or unknown API key.\n\n`key_revoked`: The key was revoked.\n\n`key_expired`: The key passed its expiry date.",
            "headers": {
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "x-error-codes": [
              "unauthorized",
              "key_revoked",
              "key_expired"
            ]
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`ip_not_allowed`: The calling IP is not on the key's allowlist.\n\n`subscription_inactive`: The organization has no active subscription that includes the API.\n\n`account_inactive`: The organization is suspended, or has no owner whose account is active.\n\n`scope_missing`: The key lacks a scope this endpoint needs.",
            "headers": {
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "x-error-codes": [
              "ip_not_allowed",
              "subscription_inactive",
              "account_inactive",
              "scope_missing"
            ]
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`template_not_found`: No template with this id in your organization.",
            "headers": {
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "x-error-codes": [
              "template_not_found"
            ]
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`rate_limited`: Too many requests in the current minute, hour or day (per key or per organization), or more than 60 failed authentications per minute from your IP address.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "x-error-codes": [
              "rate_limited"
            ]
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`internal_error`: Something failed on our side.",
            "headers": {
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "x-error-codes": [
              "internal_error"
            ]
          },
          "503": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`api_disabled`: The API is temporarily disabled (maintenance) or switched off for the organization.",
            "headers": {
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "x-error-codes": [
              "api_disabled"
            ]
          }
        },
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "summary": "Get a template",
        "tags": [
          "Templates"
        ],
        "x-example-request": {
          "path": {
            "id": "tpl_42"
          }
        },
        "x-scope": "resources:read",
        "x-scopes": [
          "resources:read"
        ]
      },
      "patch": {
        "description": "Changes a template. Items already in projects keep their own copy. Free: no credits are charged.",
        "externalDocs": {
          "url": "https://runner.cargoduo.com/api/public/api-docs/pages/update-template.md"
        },
        "operationId": "updateTemplate",
        "parameters": [
          {
            "description": "Template id (tpl_…).",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "weight": 480
              },
              "schema": {
                "$ref": "#/components/schemas/TemplateUpdate"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "example": {
                  "id": "tpl_42",
                  "object": "template",
                  "label": "Euro pallet",
                  "shape": "box",
                  "length": 120,
                  "width": 80,
                  "height": 140,
                  "radius": 0,
                  "weight": 480,
                  "stackable": false,
                  "max_stack_weight": 0,
                  "rotation": "all",
                  "hazardous": false,
                  "priority": 0,
                  "color": "#3b82f6",
                  "nesting_height": 0,
                  "created_by": {
                    "id": "usr_7",
                    "name": "Elif Kaya"
                  },
                  "updated_by": {
                    "id": "usr_7",
                    "name": "Elif Kaya"
                  },
                  "created_at": "2026-09-28T14:05:52Z",
                  "updated_at": "2026-10-19T09:12:03Z"
                },
                "schema": {
                  "$ref": "#/components/schemas/Template"
                }
              }
            },
            "description": "The template after the change.",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Limit of the tightest rate window.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix time (seconds) when that window resets.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`invalid_json`: The body is not valid JSON or a field has the wrong type.",
            "headers": {
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "x-error-codes": [
              "invalid_json"
            ]
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`unauthorized`: Missing, malformed or unknown API key.\n\n`key_revoked`: The key was revoked.\n\n`key_expired`: The key passed its expiry date.",
            "headers": {
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "x-error-codes": [
              "unauthorized",
              "key_revoked",
              "key_expired"
            ]
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`ip_not_allowed`: The calling IP is not on the key's allowlist.\n\n`subscription_inactive`: The organization has no active subscription that includes the API.\n\n`account_inactive`: The organization is suspended, or has no owner whose account is active.\n\n`scope_missing`: The key lacks a scope this endpoint needs.",
            "headers": {
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "x-error-codes": [
              "ip_not_allowed",
              "subscription_inactive",
              "account_inactive",
              "scope_missing"
            ]
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`template_not_found`: No template with this id in your organization.",
            "headers": {
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "x-error-codes": [
              "template_not_found"
            ]
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`validation_failed`: The request is well-formed JSON but describes an invalid job. details[] lists every problem.",
            "headers": {
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "x-error-codes": [
              "validation_failed"
            ]
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`rate_limited`: Too many requests in the current minute, hour or day (per key or per organization), or more than 60 failed authentications per minute from your IP address.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "x-error-codes": [
              "rate_limited"
            ]
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`internal_error`: Something failed on our side.",
            "headers": {
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "x-error-codes": [
              "internal_error"
            ]
          },
          "503": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`api_disabled`: The API is temporarily disabled (maintenance) or switched off for the organization.",
            "headers": {
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "x-error-codes": [
              "api_disabled"
            ]
          }
        },
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "summary": "Update a template",
        "tags": [
          "Templates"
        ],
        "x-example-request": {
          "path": {
            "id": "tpl_42"
          }
        },
        "x-scope": "resources:write",
        "x-scopes": [
          "resources:write"
        ]
      }
    },
    "/v1/usage": {
      "get": {
        "description": "Requests, jobs, credits, compute seconds and vehicles per UTC day. Without from/to: the last 30 days. At most 92 days per call.",
        "externalDocs": {
          "url": "https://runner.cargoduo.com/api/public/api-docs/pages/get-usage.md"
        },
        "operationId": "getUsage",
        "parameters": [
          {
            "description": "First day, YYYY-MM-DD (UTC).",
            "in": "query",
            "name": "from",
            "required": false,
            "schema": {
              "format": "date",
              "type": "string"
            }
          },
          {
            "description": "Last day, YYYY-MM-DD (UTC). Defaults to today.",
            "in": "query",
            "name": "to",
            "required": false,
            "schema": {
              "format": "date",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "example": {
                  "data": [
                    {
                      "date": "2026-10-17",
                      "requests": 41,
                      "jobs": 9,
                      "credits": 2.931,
                      "compute_seconds": 38.2,
                      "vehicles": 11
                    },
                    {
                      "date": "2026-10-18",
                      "requests": 12,
                      "jobs": 3,
                      "credits": 0.829,
                      "compute_seconds": 9.8,
                      "vehicles": 3
                    },
                    {
                      "date": "2026-10-19",
                      "requests": 27,
                      "jobs": 6,
                      "credits": 1.867,
                      "compute_seconds": 21.4,
                      "vehicles": 7
                    }
                  ]
                },
                "schema": {
                  "$ref": "#/components/schemas/Usage"
                }
              }
            },
            "description": "One row per day.",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Limit of the tightest rate window.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix time (seconds) when that window resets.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`unauthorized`: Missing, malformed or unknown API key.\n\n`key_revoked`: The key was revoked.\n\n`key_expired`: The key passed its expiry date.",
            "headers": {
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "x-error-codes": [
              "unauthorized",
              "key_revoked",
              "key_expired"
            ]
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`ip_not_allowed`: The calling IP is not on the key's allowlist.\n\n`subscription_inactive`: The organization has no active subscription that includes the API.\n\n`account_inactive`: The organization is suspended, or has no owner whose account is active.\n\n`scope_missing`: The key lacks a scope this endpoint needs.",
            "headers": {
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "x-error-codes": [
              "ip_not_allowed",
              "subscription_inactive",
              "account_inactive",
              "scope_missing"
            ]
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`validation_failed`: The request is well-formed JSON but describes an invalid job. details[] lists every problem.",
            "headers": {
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "x-error-codes": [
              "validation_failed"
            ]
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`rate_limited`: Too many requests in the current minute, hour or day (per key or per organization), or more than 60 failed authentications per minute from your IP address.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "x-error-codes": [
              "rate_limited"
            ]
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`internal_error`: Something failed on our side.",
            "headers": {
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "x-error-codes": [
              "internal_error"
            ]
          },
          "503": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`api_disabled`: The API is temporarily disabled (maintenance) or switched off for the organization.",
            "headers": {
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "x-error-codes": [
              "api_disabled"
            ]
          }
        },
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "summary": "Get usage",
        "tags": [
          "Account"
        ],
        "x-example-request": {
          "query": {
            "from": "2026-10-17",
            "to": "2026-10-19"
          }
        },
        "x-scope": "account:read",
        "x-scopes": [
          "account:read"
        ]
      }
    },
    "/v1/vehicles": {
      "get": {
        "description": "Every vehicle you can name with vehicle_id: the presets (containers, trailers, trucks, pallets of the types your organization may use), then your organization's own vehicles. Free: no credits are charged.",
        "externalDocs": {
          "url": "https://runner.cargoduo.com/api/public/api-docs/pages/list-vehicles.md"
        },
        "operationId": "listVehicles",
        "parameters": [
          {
            "description": "Page size.",
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": {
              "default": 20,
              "maximum": 100,
              "minimum": 1,
              "type": "integer"
            }
          },
          {
            "description": "next_cursor of the previous page.",
            "in": "query",
            "name": "cursor",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Only presets (`preset`), or only your own vehicles (`custom`).",
            "in": "query",
            "name": "kind",
            "required": false,
            "schema": {
              "enum": [
                "preset",
                "custom"
              ],
              "type": "string"
            }
          },
          {
            "description": "Only vehicles of this type.",
            "in": "query",
            "name": "type",
            "required": false,
            "schema": {
              "enum": [
                "truck",
                "trailer",
                "flatbed",
                "container",
                "pallet",
                "aircraft",
                "ship"
              ],
              "type": "string"
            }
          },
          {
            "description": "Only vehicles whose name contains this text.",
            "in": "query",
            "name": "q",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Only what this member created: `me` (the key's creator) or a member id (`usr_…`).",
            "in": "query",
            "name": "created_by",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "example": {
                  "data": [
                    {
                      "id": "standard-trailer-13-6m",
                      "object": "vehicle",
                      "kind": "preset",
                      "name": "Standard Trailer (13.6m)",
                      "type": "trailer",
                      "length": 1362,
                      "width": 248,
                      "height": 270,
                      "max_weight": 24000,
                      "floor_load_capacity": 1800,
                      "axle_positions": [
                        30,
                        938,
                        1069,
                        1200
                      ],
                      "axle_max_loads": [
                        10000,
                        8000,
                        8000,
                        8000
                      ],
                      "cog_range_x": 50,
                      "cog_range_y": 20,
                      "aux_deck": false,
                      "aux_deck_height": null,
                      "aux_deck_max_weight": null,
                      "tractor_weight": null,
                      "empty_trailer_weight": null,
                      "front_axle_to_middle_axle": null,
                      "front_axle_to_tractor_cog": null,
                      "front_axle_to_kingpin": null,
                      "kingpin_to_rear_axle": null,
                      "trailer_cog_to_rear_axle": null,
                      "trailer_start_to_kingpin": null,
                      "max_middle_axle_weight": null,
                      "max_rear_axle_weight": null,
                      "blocked_areas": [],
                      "created_by": null,
                      "updated_by": null,
                      "created_at": null
                    },
                    {
                      "id": "veh_118",
                      "object": "vehicle",
                      "kind": "custom",
                      "name": "Mega trailer 13.6 m",
                      "type": "trailer",
                      "length": 1360,
                      "width": 248,
                      "height": 300,
                      "max_weight": 24000,
                      "floor_load_capacity": null,
                      "axle_positions": [],
                      "axle_max_loads": [],
                      "cog_range_x": null,
                      "cog_range_y": null,
                      "aux_deck": false,
                      "aux_deck_height": null,
                      "aux_deck_max_weight": null,
                      "tractor_weight": null,
                      "empty_trailer_weight": null,
                      "front_axle_to_middle_axle": null,
                      "front_axle_to_tractor_cog": null,
                      "front_axle_to_kingpin": null,
                      "kingpin_to_rear_axle": null,
                      "trailer_cog_to_rear_axle": null,
                      "trailer_start_to_kingpin": null,
                      "max_middle_axle_weight": null,
                      "max_rear_axle_weight": null,
                      "blocked_areas": [],
                      "created_by": {
                        "id": "usr_7",
                        "name": "Elif Kaya"
                      },
                      "updated_by": {
                        "id": "usr_7",
                        "name": "Elif Kaya"
                      },
                      "created_at": "2026-10-02T08:41:17Z"
                    }
                  ],
                  "next_cursor": ""
                },
                "schema": {
                  "$ref": "#/components/schemas/SavedVehicleList"
                }
              }
            },
            "description": "One page of vehicles.",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Limit of the tightest rate window.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix time (seconds) when that window resets.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`unauthorized`: Missing, malformed or unknown API key.\n\n`key_revoked`: The key was revoked.\n\n`key_expired`: The key passed its expiry date.",
            "headers": {
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "x-error-codes": [
              "unauthorized",
              "key_revoked",
              "key_expired"
            ]
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`ip_not_allowed`: The calling IP is not on the key's allowlist.\n\n`subscription_inactive`: The organization has no active subscription that includes the API.\n\n`account_inactive`: The organization is suspended, or has no owner whose account is active.\n\n`scope_missing`: The key lacks a scope this endpoint needs.",
            "headers": {
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "x-error-codes": [
              "ip_not_allowed",
              "subscription_inactive",
              "account_inactive",
              "scope_missing"
            ]
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`validation_failed`: The request is well-formed JSON but describes an invalid job. details[] lists every problem.",
            "headers": {
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "x-error-codes": [
              "validation_failed"
            ]
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`rate_limited`: Too many requests in the current minute, hour or day (per key or per organization), or more than 60 failed authentications per minute from your IP address.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "x-error-codes": [
              "rate_limited"
            ]
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`internal_error`: Something failed on our side.",
            "headers": {
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "x-error-codes": [
              "internal_error"
            ]
          },
          "503": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`api_disabled`: The API is temporarily disabled (maintenance) or switched off for the organization.",
            "headers": {
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "x-error-codes": [
              "api_disabled"
            ]
          }
        },
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "summary": "List vehicles",
        "tags": [
          "Vehicles"
        ],
        "x-example-note": "Abridged: one preset and one of your vehicles are shown.",
        "x-example-request": {
          "query": {
            "type": "trailer"
          }
        },
        "x-scope": "resources:read",
        "x-scopes": [
          "resources:read"
        ]
      },
      "post": {
        "description": "Saves a vehicle to your organization's fleet (it shows in the app too). Same fields and access rules as a /v1/pack vehicle, judged by the app's size and payload limits for its type. Free: no credits are charged.",
        "externalDocs": {
          "url": "https://runner.cargoduo.com/api/public/api-docs/pages/create-vehicle.md"
        },
        "operationId": "createVehicle",
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "name": "Mega trailer 13.6 m",
                "type": "trailer",
                "length": 1360,
                "width": 248,
                "height": 300,
                "max_weight": 24000
              },
              "schema": {
                "$ref": "#/components/schemas/VehicleInput"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "example": {
                  "id": "veh_118",
                  "object": "vehicle",
                  "kind": "custom",
                  "name": "Mega trailer 13.6 m",
                  "type": "trailer",
                  "length": 1360,
                  "width": 248,
                  "height": 300,
                  "max_weight": 24000,
                  "floor_load_capacity": null,
                  "axle_positions": [],
                  "axle_max_loads": [],
                  "cog_range_x": null,
                  "cog_range_y": null,
                  "aux_deck": false,
                  "aux_deck_height": null,
                  "aux_deck_max_weight": null,
                  "tractor_weight": null,
                  "empty_trailer_weight": null,
                  "front_axle_to_middle_axle": null,
                  "front_axle_to_tractor_cog": null,
                  "front_axle_to_kingpin": null,
                  "kingpin_to_rear_axle": null,
                  "trailer_cog_to_rear_axle": null,
                  "trailer_start_to_kingpin": null,
                  "max_middle_axle_weight": null,
                  "max_rear_axle_weight": null,
                  "blocked_areas": [],
                  "created_by": {
                    "id": "usr_7",
                    "name": "Elif Kaya"
                  },
                  "updated_by": {
                    "id": "usr_7",
                    "name": "Elif Kaya"
                  },
                  "created_at": "2026-10-02T08:41:17Z"
                },
                "schema": {
                  "$ref": "#/components/schemas/SavedVehicle"
                }
              }
            },
            "description": "The new vehicle.",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Limit of the tightest rate window.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix time (seconds) when that window resets.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`invalid_json`: The body is not valid JSON or a field has the wrong type.",
            "headers": {
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "x-error-codes": [
              "invalid_json"
            ]
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`unauthorized`: Missing, malformed or unknown API key.\n\n`key_revoked`: The key was revoked.\n\n`key_expired`: The key passed its expiry date.",
            "headers": {
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "x-error-codes": [
              "unauthorized",
              "key_revoked",
              "key_expired"
            ]
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`ip_not_allowed`: The calling IP is not on the key's allowlist.\n\n`subscription_inactive`: The organization has no active subscription that includes the API.\n\n`account_inactive`: The organization is suspended, or has no owner whose account is active.\n\n`scope_missing`: The key lacks a scope this endpoint needs.",
            "headers": {
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "x-error-codes": [
              "ip_not_allowed",
              "subscription_inactive",
              "account_inactive",
              "scope_missing"
            ]
          },
          "413": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`payload_too_large`: The request body exceeds 10 MB.",
            "headers": {
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "x-error-codes": [
              "payload_too_large"
            ]
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`validation_failed`: The request is well-formed JSON but describes an invalid job. details[] lists every problem.",
            "headers": {
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "x-error-codes": [
              "validation_failed"
            ]
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`rate_limited`: Too many requests in the current minute, hour or day (per key or per organization), or more than 60 failed authentications per minute from your IP address.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "x-error-codes": [
              "rate_limited"
            ]
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`internal_error`: Something failed on our side.",
            "headers": {
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "x-error-codes": [
              "internal_error"
            ]
          },
          "503": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`api_disabled`: The API is temporarily disabled (maintenance) or switched off for the organization.",
            "headers": {
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "x-error-codes": [
              "api_disabled"
            ]
          }
        },
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "summary": "Create a vehicle",
        "tags": [
          "Vehicles"
        ],
        "x-example-request": {},
        "x-scope": "resources:write",
        "x-scopes": [
          "resources:write"
        ]
      }
    },
    "/v1/vehicles/{id}": {
      "delete": {
        "description": "Deletes one of your vehicles. Presets are read-only. Free: no credits are charged.",
        "externalDocs": {
          "url": "https://runner.cargoduo.com/api/public/api-docs/pages/delete-vehicle.md"
        },
        "operationId": "deleteVehicle",
        "parameters": [
          {
            "description": "A preset id or one of your vehicles (veh_…).",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "example": {
                  "id": "veh_118",
                  "object": "vehicle",
                  "deleted": true
                },
                "schema": {
                  "$ref": "#/components/schemas/Deleted"
                }
              }
            },
            "description": "Deleted.",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Limit of the tightest rate window.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix time (seconds) when that window resets.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`unauthorized`: Missing, malformed or unknown API key.\n\n`key_revoked`: The key was revoked.\n\n`key_expired`: The key passed its expiry date.",
            "headers": {
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "x-error-codes": [
              "unauthorized",
              "key_revoked",
              "key_expired"
            ]
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`preset_read_only`: Presets cannot be changed or deleted.\n\n`ip_not_allowed`: The calling IP is not on the key's allowlist.\n\n`subscription_inactive`: The organization has no active subscription that includes the API.\n\n`account_inactive`: The organization is suspended, or has no owner whose account is active.\n\n`scope_missing`: The key lacks a scope this endpoint needs.",
            "headers": {
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "x-error-codes": [
              "preset_read_only",
              "ip_not_allowed",
              "subscription_inactive",
              "account_inactive",
              "scope_missing"
            ]
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`vehicle_not_found`: No vehicle with this id among the presets or your organization's vehicles.",
            "headers": {
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "x-error-codes": [
              "vehicle_not_found"
            ]
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`rate_limited`: Too many requests in the current minute, hour or day (per key or per organization), or more than 60 failed authentications per minute from your IP address.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "x-error-codes": [
              "rate_limited"
            ]
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`internal_error`: Something failed on our side.",
            "headers": {
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "x-error-codes": [
              "internal_error"
            ]
          },
          "503": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`api_disabled`: The API is temporarily disabled (maintenance) or switched off for the organization.",
            "headers": {
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "x-error-codes": [
              "api_disabled"
            ]
          }
        },
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "summary": "Delete a vehicle",
        "tags": [
          "Vehicles"
        ],
        "x-example-request": {
          "path": {
            "id": "veh_118"
          }
        },
        "x-scope": "resources:write",
        "x-scopes": [
          "resources:write"
        ]
      },
      "get": {
        "description": "A preset or one of your vehicles. Free: no credits are charged.",
        "externalDocs": {
          "url": "https://runner.cargoduo.com/api/public/api-docs/pages/get-vehicle.md"
        },
        "operationId": "getVehicle",
        "parameters": [
          {
            "description": "A preset id or one of your vehicles (veh_…).",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "example": {
                  "id": "veh_118",
                  "object": "vehicle",
                  "kind": "custom",
                  "name": "Mega trailer 13.6 m",
                  "type": "trailer",
                  "length": 1360,
                  "width": 248,
                  "height": 300,
                  "max_weight": 24000,
                  "floor_load_capacity": null,
                  "axle_positions": [],
                  "axle_max_loads": [],
                  "cog_range_x": null,
                  "cog_range_y": null,
                  "aux_deck": false,
                  "aux_deck_height": null,
                  "aux_deck_max_weight": null,
                  "tractor_weight": null,
                  "empty_trailer_weight": null,
                  "front_axle_to_middle_axle": null,
                  "front_axle_to_tractor_cog": null,
                  "front_axle_to_kingpin": null,
                  "kingpin_to_rear_axle": null,
                  "trailer_cog_to_rear_axle": null,
                  "trailer_start_to_kingpin": null,
                  "max_middle_axle_weight": null,
                  "max_rear_axle_weight": null,
                  "blocked_areas": [],
                  "created_by": {
                    "id": "usr_7",
                    "name": "Elif Kaya"
                  },
                  "updated_by": {
                    "id": "usr_7",
                    "name": "Elif Kaya"
                  },
                  "created_at": "2026-10-02T08:41:17Z"
                },
                "schema": {
                  "$ref": "#/components/schemas/SavedVehicle"
                }
              }
            },
            "description": "The vehicle.",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Limit of the tightest rate window.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix time (seconds) when that window resets.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`unauthorized`: Missing, malformed or unknown API key.\n\n`key_revoked`: The key was revoked.\n\n`key_expired`: The key passed its expiry date.",
            "headers": {
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "x-error-codes": [
              "unauthorized",
              "key_revoked",
              "key_expired"
            ]
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`ip_not_allowed`: The calling IP is not on the key's allowlist.\n\n`subscription_inactive`: The organization has no active subscription that includes the API.\n\n`account_inactive`: The organization is suspended, or has no owner whose account is active.\n\n`scope_missing`: The key lacks a scope this endpoint needs.",
            "headers": {
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "x-error-codes": [
              "ip_not_allowed",
              "subscription_inactive",
              "account_inactive",
              "scope_missing"
            ]
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`vehicle_not_found`: No vehicle with this id among the presets or your organization's vehicles.",
            "headers": {
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "x-error-codes": [
              "vehicle_not_found"
            ]
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`rate_limited`: Too many requests in the current minute, hour or day (per key or per organization), or more than 60 failed authentications per minute from your IP address.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "x-error-codes": [
              "rate_limited"
            ]
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`internal_error`: Something failed on our side.",
            "headers": {
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "x-error-codes": [
              "internal_error"
            ]
          },
          "503": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`api_disabled`: The API is temporarily disabled (maintenance) or switched off for the organization.",
            "headers": {
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "x-error-codes": [
              "api_disabled"
            ]
          }
        },
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "summary": "Get a vehicle",
        "tags": [
          "Vehicles"
        ],
        "x-example-request": {
          "path": {
            "id": "veh_118"
          }
        },
        "x-scope": "resources:read",
        "x-scopes": [
          "resources:read"
        ]
      },
      "patch": {
        "description": "Changes one of your vehicles. Presets are read-only. Free: no credits are charged.",
        "externalDocs": {
          "url": "https://runner.cargoduo.com/api/public/api-docs/pages/update-vehicle.md"
        },
        "operationId": "updateVehicle",
        "parameters": [
          {
            "description": "A preset id or one of your vehicles (veh_…).",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "max_weight": 25000
              },
              "schema": {
                "$ref": "#/components/schemas/VehicleUpdate"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "example": {
                  "id": "veh_118",
                  "object": "vehicle",
                  "kind": "custom",
                  "name": "Mega trailer 13.6 m",
                  "type": "trailer",
                  "length": 1360,
                  "width": 248,
                  "height": 300,
                  "max_weight": 25000,
                  "floor_load_capacity": null,
                  "axle_positions": [],
                  "axle_max_loads": [],
                  "cog_range_x": null,
                  "cog_range_y": null,
                  "aux_deck": false,
                  "aux_deck_height": null,
                  "aux_deck_max_weight": null,
                  "tractor_weight": null,
                  "empty_trailer_weight": null,
                  "front_axle_to_middle_axle": null,
                  "front_axle_to_tractor_cog": null,
                  "front_axle_to_kingpin": null,
                  "kingpin_to_rear_axle": null,
                  "trailer_cog_to_rear_axle": null,
                  "trailer_start_to_kingpin": null,
                  "max_middle_axle_weight": null,
                  "max_rear_axle_weight": null,
                  "blocked_areas": [],
                  "created_by": {
                    "id": "usr_7",
                    "name": "Elif Kaya"
                  },
                  "updated_by": {
                    "id": "usr_7",
                    "name": "Elif Kaya"
                  },
                  "created_at": "2026-10-02T08:41:17Z"
                },
                "schema": {
                  "$ref": "#/components/schemas/SavedVehicle"
                }
              }
            },
            "description": "The vehicle after the change.",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Limit of the tightest rate window.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix time (seconds) when that window resets.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`invalid_json`: The body is not valid JSON or a field has the wrong type.",
            "headers": {
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "x-error-codes": [
              "invalid_json"
            ]
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`unauthorized`: Missing, malformed or unknown API key.\n\n`key_revoked`: The key was revoked.\n\n`key_expired`: The key passed its expiry date.",
            "headers": {
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "x-error-codes": [
              "unauthorized",
              "key_revoked",
              "key_expired"
            ]
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`preset_read_only`: Presets cannot be changed or deleted.\n\n`ip_not_allowed`: The calling IP is not on the key's allowlist.\n\n`subscription_inactive`: The organization has no active subscription that includes the API.\n\n`account_inactive`: The organization is suspended, or has no owner whose account is active.\n\n`scope_missing`: The key lacks a scope this endpoint needs.",
            "headers": {
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "x-error-codes": [
              "preset_read_only",
              "ip_not_allowed",
              "subscription_inactive",
              "account_inactive",
              "scope_missing"
            ]
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`vehicle_not_found`: No vehicle with this id among the presets or your organization's vehicles.",
            "headers": {
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "x-error-codes": [
              "vehicle_not_found"
            ]
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`validation_failed`: The request is well-formed JSON but describes an invalid job. details[] lists every problem.",
            "headers": {
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "x-error-codes": [
              "validation_failed"
            ]
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`rate_limited`: Too many requests in the current minute, hour or day (per key or per organization), or more than 60 failed authentications per minute from your IP address.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "x-error-codes": [
              "rate_limited"
            ]
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`internal_error`: Something failed on our side.",
            "headers": {
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "x-error-codes": [
              "internal_error"
            ]
          },
          "503": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "`api_disabled`: The API is temporarily disabled (maintenance) or switched off for the organization.",
            "headers": {
              "X-Request-Id": {
                "description": "Unique id of this request (req_…).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "x-error-codes": [
              "api_disabled"
            ]
          }
        },
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "summary": "Update a vehicle",
        "tags": [
          "Vehicles"
        ],
        "x-example-request": {
          "path": {
            "id": "veh_118"
          }
        },
        "x-scope": "resources:write",
        "x-scopes": [
          "resources:write"
        ]
      }
    }
  },
  "security": [
    {
      "bearerAuth": []
    }
  ],
  "servers": [
    {
      "url": "https://runner.cargoduo.com"
    }
  ],
  "tags": [
    {
      "description": "Create and price packing jobs.",
      "name": "Pack"
    },
    {
      "description": "Follow, read and cancel jobs.",
      "name": "Jobs"
    },
    {
      "description": "Load plans shared with the app; pack them in place.",
      "name": "Projects"
    },
    {
      "description": "Presets and your organization's vehicles.",
      "name": "Vehicles"
    },
    {
      "description": "Saved items (cargo templates).",
      "name": "Templates"
    },
    {
      "description": "Limits, balance and usage.",
      "name": "Account"
    },
    {
      "description": "Public documentation files.",
      "name": "Docs"
    }
  ],
  "x-error-codes": [
    {
      "code": "invalid_json",
      "handling": "Fix the request body.",
      "meaning": "The body is not valid JSON or a field has the wrong type.",
      "retryable": false,
      "status": 400
    },
    {
      "code": "unauthorized",
      "handling": "Send Authorization: Bearer cd_live_…; check the key was copied completely.",
      "meaning": "Missing, malformed or unknown API key.",
      "retryable": false,
      "status": 401
    },
    {
      "code": "key_revoked",
      "handling": "Create a new key in the developer console.",
      "meaning": "The key was revoked.",
      "retryable": false,
      "status": 401
    },
    {
      "code": "key_expired",
      "handling": "Create a new key in the developer console.",
      "meaning": "The key passed its expiry date.",
      "retryable": false,
      "status": 401
    },
    {
      "code": "insufficient_credits",
      "handling": "Buy a credit pack or wait for the monthly credits; nothing was charged.",
      "meaning": "Available credits do not cover the smallest possible run of this job.",
      "retryable": false,
      "status": 402
    },
    {
      "code": "ip_not_allowed",
      "handling": "Call from an allowed IP or edit the allowlist.",
      "meaning": "The calling IP is not on the key's allowlist.",
      "retryable": false,
      "status": 403
    },
    {
      "code": "subscription_inactive",
      "handling": "Renew the subscription.",
      "meaning": "The organization has no active subscription that includes the API.",
      "retryable": false,
      "status": 403
    },
    {
      "code": "account_inactive",
      "handling": "Contact support.",
      "meaning": "The organization is suspended, or has no owner whose account is active.",
      "retryable": false,
      "status": 403
    },
    {
      "code": "scope_missing",
      "handling": "Use a key with the scope (pack:write, jobs:read, account:read, resources:read, resources:write).",
      "meaning": "The key lacks a scope this endpoint needs.",
      "retryable": false,
      "status": 403
    },
    {
      "code": "preset_read_only",
      "handling": "Create your own vehicle with POST /v1/vehicles.",
      "meaning": "Presets cannot be changed or deleted.",
      "retryable": false,
      "status": 403
    },
    {
      "code": "plan_limit_reached",
      "handling": "Delete projects you no longer need, or move to a larger plan.",
      "meaning": "The organization's plan allows no more projects or cargo items.",
      "retryable": false,
      "status": 403
    },
    {
      "code": "not_found",
      "handling": "Check the method and path against the endpoint list.",
      "meaning": "No /v1 endpoint has this method and path.",
      "retryable": false,
      "status": 404
    },
    {
      "code": "job_not_found",
      "handling": "Check the id.",
      "meaning": "No job with this id in your organization.",
      "retryable": false,
      "status": 404
    },
    {
      "code": "vehicle_not_found",
      "handling": "Check the id against GET /v1/vehicles.",
      "meaning": "No vehicle with this id among the presets or your organization's vehicles.",
      "retryable": false,
      "status": 404
    },
    {
      "code": "template_not_found",
      "handling": "Check the id against GET /v1/templates.",
      "meaning": "No template with this id in your organization.",
      "retryable": false,
      "status": 404
    },
    {
      "code": "project_not_found",
      "handling": "Check the id against GET /v1/projects.",
      "meaning": "No project with this id in your organization.",
      "retryable": false,
      "status": 404
    },
    {
      "code": "job_not_finished",
      "handling": "Poll GET /v1/jobs/{id} until `status` is `succeeded`.",
      "meaning": "The job is still queued or running.",
      "retryable": true,
      "status": 409
    },
    {
      "code": "project_busy",
      "handling": "Wait for that run to end, then retry.",
      "meaning": "The project is being packed right now (in the app or by another job).",
      "retryable": true,
      "status": 409
    },
    {
      "code": "job_failed",
      "handling": "Read `job.error`; failures on our side are not charged (time_limit_exceeded is charged like a canceled job) — resubmit if the cause was temporary.",
      "meaning": "The job failed; it has no result.",
      "retryable": false,
      "status": 409
    },
    {
      "code": "job_canceled",
      "handling": "Resubmit if needed.",
      "meaning": "The job was canceled; it has no result.",
      "retryable": false,
      "status": 409
    },
    {
      "code": "job_already_finished",
      "handling": "Nothing to do.",
      "meaning": "The job already ended and cannot be canceled.",
      "retryable": false,
      "status": 409
    },
    {
      "code": "idempotency_key_invalid",
      "handling": "Use a shorter key (a UUID works).",
      "meaning": "The Idempotency-Key header is longer than 128 characters.",
      "retryable": false,
      "status": 400
    },
    {
      "code": "result_expired",
      "handling": "Resubmit the job if you need the plan again.",
      "meaning": "The result passed the retention window and was deleted.",
      "retryable": false,
      "status": 410
    },
    {
      "code": "payload_too_large",
      "handling": "Send fewer or simpler items.",
      "meaning": "The request body exceeds 10 MB.",
      "retryable": false,
      "status": 413
    },
    {
      "code": "validation_failed",
      "handling": "Fix each details[].path; validation failures are free.",
      "meaning": "The request is well-formed JSON but describes an invalid job. details[] lists every problem.",
      "retryable": false,
      "status": 422
    },
    {
      "code": "rate_limited",
      "handling": "Wait Retry-After seconds, then retry with backoff.",
      "meaning": "Too many requests in the current minute, hour or day (per key or per organization), or more than 60 failed authentications per minute from your IP address.",
      "retryable": true,
      "status": 429
    },
    {
      "code": "too_many_jobs",
      "handling": "Wait for running jobs to finish, then retry.",
      "meaning": "The organization already has the maximum number of queued + running jobs.",
      "retryable": true,
      "status": 429
    },
    {
      "code": "internal_error",
      "handling": "Retry with backoff; quote request_id if it persists.",
      "meaning": "Something failed on our side.",
      "retryable": true,
      "status": 500
    },
    {
      "code": "api_disabled",
      "handling": "Retry later.",
      "meaning": "The API is temporarily disabled (maintenance) or switched off for the organization.",
      "retryable": true,
      "status": 503
    }
  ],
  "x-features": [
    {
      "default": false,
      "description": "Axle positions and limits, tractor and trailer geometry, centre-of-gravity ranges and per-axle loads in the result. Without access these fields are accepted and ignored.",
      "fields": [
        "vehicles[].axle_positions",
        "vehicles[].axle_max_loads",
        "vehicles[].cog_range_x",
        "vehicles[].cog_range_y",
        "vehicles[].tractor_weight",
        "vehicles[].empty_trailer_weight",
        "vehicles[].front_axle_to_middle_axle",
        "vehicles[].front_axle_to_tractor_cog",
        "vehicles[].front_axle_to_kingpin",
        "vehicles[].kingpin_to_rear_axle",
        "vehicles[].trailer_cog_to_rear_axle",
        "vehicles[].trailer_start_to_kingpin",
        "vehicles[].max_middle_axle_weight",
        "vehicles[].max_rear_axle_weight",
        "options.enforce_axle",
        "result.vehicles[].axle_loads"
      ],
      "key": "axle_loads",
      "title": "Axle loads"
    },
    {
      "default": true,
      "description": "Double decks, floor load capacity and blocked floor areas.",
      "fields": [
        "vehicles[].floor_load_capacity",
        "vehicles[].aux_deck",
        "vehicles[].aux_deck_height",
        "vehicles[].aux_deck_max_weight",
        "vehicles[].blocked_areas"
      ],
      "key": "vehicle_details",
      "title": "Vehicle details"
    },
    {
      "default": true,
      "description": "Nesting, overweight loads, stack limits, locked rotations, identical-vehicle grouping and custom time limits.",
      "fields": [
        "items[].nesting_height",
        "options.allow_overweight",
        "options.max_stack_items",
        "options.max_stack_density_kg_m2",
        "options.lock_rotations",
        "options.group_identical_bins",
        "options.time_limit"
      ],
      "key": "load_rules",
      "title": "Load rules"
    }
  ],
  "x-job-error-codes": [
    {
      "code": "canceled",
      "handling": "",
      "meaning": "Canceled by DELETE /v1/jobs/{id}. Charged base + compute used.",
      "retryable": false
    },
    {
      "code": "time_limit_exceeded",
      "handling": "Raise options.time_limit or simplify the load.",
      "meaning": "The compute budget ran out before any vehicle was packed. Charged like a canceled job: per-job fee, large-load surcharge and the compute used, never the per-vehicle fee.",
      "retryable": true
    },
    {
      "code": "engine_failed",
      "handling": "Retry; contact support with the job id if it repeats.",
      "meaning": "The packing engine failed. Not charged.",
      "retryable": true
    },
    {
      "code": "queue_timeout",
      "handling": "Retry later.",
      "meaning": "The job waited too long for a compute slot. Not charged.",
      "retryable": true
    },
    {
      "code": "server_restarted",
      "handling": "Resubmit the job.",
      "meaning": "The service restarted while the job was queued or running. Not charged.",
      "retryable": true
    }
  ]
}