> ## Documentation Index
> Fetch the complete documentation index at: https://developers.kardinal.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Waste collection

> Alternative disposal outlets, material changeover time, incompatible loads, and heavy-vehicle routing on one municipal round.

A waste and recycling operation runs a mixed fleet of standard and specially certified trucks on collection rounds that end at one of several disposal or sorting sites, often carrying materials that can't be mixed on the same load and that trigger real routing restrictions (weight, height, tunnels, hazardous goods).

## What makes this vertical distinctive

* **Alternative disposal outlets** — a collection round can end at any of several disposal sites, and the solver picks whichever keeps the route tightest.
* **Material changeover time** — switching from one material to another that needs it (for example organic to glass) inserts a cleaning/setup pass.
* **Incompatible loads** — clashing materials (organic and hazardous, for instance) are automatically kept off the same truck.
* **Heavy-vehicle routing (HGV profiles)** — tolls avoided, dimensions and hazmat-safe roads respected for the trucks that need it.

## Combined example

```json theme={null}
{
  "resources": [
    {
      "id": "truck-hazmat-1",
      "vehicleProfile": {
        "type": "truck",
        "grossWeight": 19000,
        "avoidTollRoad": true,
        "avoidTunnel": true,
        "tunnelCategory": "C",
        "shippedHazardousGoods": ["harmfulToWater"]
      },
      "capacities": { "weight": 9000, "volume": 20, "containers": 40 },
      "skills": ["hazmat-certified", "hoist-equipped"]
    },
    { "id": "truck-standard-1", "vehicleProfile": { "type": "truck" } }
  ],
  "orders": [
    {
      "id": "order-hazmat-site",
      "stops": [
        {
          "type": "single",
          "id": "stop-hazmat-site",
          "position": { "lon": 2.435, "lat": 48.84 },
          "kind": "delivery",
          "operationDuration": "PT15M",
          "tags": ["material:hazardous"]
        }
      ],
      "requiredSkills": ["hazmat-certified", "hoist-equipped"]
    },
    {
      "id": "order-organic",
      "stops": [
        {
          "type": "single",
          "id": "stop-organic",
          "position": { "lon": 2.465, "lat": 48.814 },
          "kind": "delivery",
          "operationDuration": "PT8M",
          "tags": ["material:organic"]
        }
      ]
    },
    {
      "id": "order-glass",
      "stops": [
        {
          "type": "single",
          "id": "stop-glass",
          "position": { "lon": 2.443, "lat": 48.818 },
          "kind": "delivery",
          "operationDuration": "PT8M",
          "tags": ["material:glass"]
        }
      ]
    },
    {
      "id": "order-collection-round",
      "stops": [
        {
          "type": "single",
          "id": "stop-collection-round",
          "position": { "lon": 2.46, "lat": 48.854 },
          "kind": "pickup",
          "operationDuration": "PT25M",
          "capacities": { "volume": 18 }
        },
        {
          "id": "stop-disposal-alternatives",
          "type": "alternatives",
          "alternatives": [
            { "type": "single", "id": "stop-disposal-site-a", "position": { "lon": 2.447, "lat": 48.806 }, "kind": "delivery", "operationDuration": "PT10M", "capacities": { "volume": 18 } },
            { "type": "single", "id": "stop-disposal-site-b", "position": { "lon": 2.47, "lat": 48.842 }, "kind": "delivery", "operationDuration": "PT10M", "capacities": { "volume": 18 } },
            { "type": "single", "id": "stop-disposal-site-c", "position": { "lon": 2.435, "lat": 48.84 }, "kind": "delivery", "operationDuration": "PT10M", "capacities": { "volume": 18 } }
          ]
        }
      ]
    }
  ],
  "additionalConstraints": [
    {
      "type": "incompatibleStopTags",
      "stopTags": ["material:organic", "material:hazardous"],
      "name": "no-organic-with-hazardous"
    }
  ],
  "setupDurations": [
    { "fromStopTag": "material:organic", "toStopTag": "material:glass", "setupDuration": "PT12M" }
  ]
}
```

### Alternative disposal outlets

`order-collection-round`'s second stop is an `AlternativesStop` (`stop-disposal-alternatives`) offering three candidate disposal sites; the engine picks whichever fits the rest of the route best, rather than the plan being tied to one fixed endpoint. This is the same `AlternativesStop` stop type used in [Optional steps that gate a mandatory stop](/guides/advanced-constraints#optional-steps-that-gate-a-mandatory-stop), applied here to a choice between equally valid endpoints rather than to gating a downstream stop.

### Material changeover time

`setupDurations` adds a fixed duration (here 12 minutes) whenever a resource's next stop carries `material:glass` right after one tagged `material:organic` — a cleaning pass triggered by the sequence of tags actually visited, not scheduled up front. See [Plan-level fields](/reference/data-model#plan-level-fields).

### Incompatible loads

`additionalConstraints[].type: "incompatibleStopTags"` forbids a single resource from ever carrying both `material:organic` and `material:hazardous` stops on the same tour — a hard rule, checked across the whole tour rather than stop by stop. See [Constraints catalog](/reference/data-model#constraints-catalog).

### Heavy-vehicle routing

`truck-hazmat-1.vehicleProfile` carries `grossWeight`, `avoidTollRoad`, `avoidTunnel`/`tunnelCategory`, and `shippedHazardousGoods` — the engine routes this truck only over roads that accept its dimensions, weight, and cargo, on top of the `hazmat-certified` skill required by the hazardous site. See [Vehicle profiles](/reference/data-model#vehicle-profiles).

## Full payload

<Accordion title="Full payload — ready to submit as POST /plans">
  The preceding example isolates the four mechanisms this vertical needs; this expands it to the scale of a real working day — a full fleet schedule (`workingTimeWindow`, `departure`, `arrival`), the complete `objectives` list, and enough stops to look like an actual round rather than a minimal illustration. Submit it as-is via [`POST /plans`](/api-reference/plan/create-a-plan) — the service assigns the plan's `id`, so don't include one of your own.

  ```json theme={null}
  {
    "tz": "Europe/Paris",
    "resources": [
      {
        "id": "truck-1",
        "vehicleProfile": {
          "type": "truck",
          "grossWeight": 19000,
          "height": 380,
          "width": 255,
          "length": 1050,
          "avoidTollRoad": true,
          "avoidTunnel": true,
          "tunnelCategory": "C",
          "shippedHazardousGoods": ["harmfulToWater"]
        },
        "workingTimeWindow": { "begin": "2026-08-03T07:00:00Z", "end": "2026-08-03T17:00:00Z" },
        "departure": { "lon": 2.455, "lat": 48.832 },
        "arrival": { "lon": 2.455, "lat": 48.832 },
        "capacities": { "weight": 9000, "volume": 20, "containers": 40 },
        "skills": ["hazmat-certified", "hoist-equipped"],
        "tags": ["noise:low-emission"]
      },
      {
        "id": "truck-2",
        "vehicleProfile": { "type": "truck" },
        "workingTimeWindow": { "begin": "2026-08-03T07:00:00Z", "end": "2026-08-03T17:00:00Z" },
        "departure": { "lon": 2.455, "lat": 48.832 },
        "arrival": { "lon": 2.455, "lat": 48.832 },
        "capacities": { "weight": 7000, "volume": 16, "containers": 32 },
        "tags": ["equipment:standard"]
      }
    ],
    "orders": [
      {
        "id": "order-standard",
        "stops": [{ "type": "single", "id": "stop-standard", "position": { "lon": 2.47, "lat": 48.842 }, "kind": "delivery", "operationDuration": "PT8M", "capacities": { "weight": 1500, "volume": 3, "containers": 7 } }]
      },
      {
        "id": "order-hazmat-site",
        "stops": [{ "type": "single", "id": "stop-hazmat-site", "position": { "lon": 2.435, "lat": 48.84 }, "kind": "delivery", "operationDuration": "PT15M", "capacities": { "weight": 300, "volume": 1, "containers": 2 }, "tags": ["material:hazardous"] }],
        "requiredSkills": ["hazmat-certified", "hoist-equipped"]
      },
      {
        "id": "order-organic",
        "stops": [{ "type": "single", "id": "stop-organic", "position": { "lon": 2.465, "lat": 48.814 }, "kind": "delivery", "operationDuration": "PT8M", "capacities": { "weight": 1200, "volume": 5, "containers": 4 }, "tags": ["material:organic"] }]
      },
      {
        "id": "order-glass",
        "stops": [{ "type": "single", "id": "stop-glass", "position": { "lon": 2.443, "lat": 48.818 }, "kind": "delivery", "operationDuration": "PT8M", "capacities": { "weight": 1000, "volume": 1.2, "containers": 3 }, "tags": ["material:glass"] }]
      },
      {
        "id": "order-direct-transfer",
        "stops": [
          { "type": "single", "id": "stop-pickup-site", "position": { "lon": 2.48, "lat": 48.827 }, "kind": "pickup", "operationDuration": "PT20M", "capacities": { "volume": 20 } },
          { "type": "single", "id": "stop-disposal-site", "position": { "lon": 2.425, "lat": 48.847 }, "kind": "delivery", "operationDuration": "PT15M", "capacities": { "volume": 20 } }
        ],
        "successiveStops": true,
        "maxStopSpan": "PT45M"
      },
      {
        "id": "order-collection-round",
        "stops": [
          { "type": "single", "id": "stop-collection-round", "position": { "lon": 2.46, "lat": 48.854 }, "kind": "pickup", "operationDuration": "PT25M", "capacities": { "volume": 18 } },
          {
            "id": "stop-disposal-alternatives",
            "type": "alternatives",
            "alternatives": [
              { "type": "single", "id": "stop-disposal-site-a", "position": { "lon": 2.447, "lat": 48.806 }, "kind": "delivery", "operationDuration": "PT10M", "capacities": { "volume": 18 } },
              { "type": "single", "id": "stop-disposal-site-b", "position": { "lon": 2.47, "lat": 48.842 }, "kind": "delivery", "operationDuration": "PT10M", "capacities": { "volume": 18 } },
              { "type": "single", "id": "stop-disposal-site-c", "position": { "lon": 2.435, "lat": 48.84 }, "kind": "delivery", "operationDuration": "PT10M", "capacities": { "volume": 18 } }
            ]
          }
        ]
      },
      {
        "id": "order-collection-slot",
        "stops": [
          {
            "type": "single",
            "id": "stop-collection-slot",
            "position": { "lon": 2.465, "lat": 48.814 },
            "kind": "pickup",
            "operationDuration": "PT20M",
            "capacities": { "weight": 900, "volume": 3.5, "containers": 6 },
            "authorizedTimeWindows": [
              { "begin": "2026-08-03T06:00:00Z", "end": "2026-08-03T08:00:00Z", "resourceTags": ["noise:low-emission"] },
              { "begin": "2026-08-03T09:00:00Z", "end": "2026-08-03T17:00:00Z" }
            ]
          }
        ]
      },
      {
        "id": "order-unloading-slot",
        "stops": [
          { "type": "single", "id": "stop-unloading-slot", "position": { "lon": 2.443, "lat": 48.818 }, "kind": "delivery", "operationDuration": "PT20M", "capacities": { "weight": 1100, "volume": 4, "containers": 5 }, "authorizedTimeWindows": [{ "begin": "2026-08-03T08:30:00Z", "end": "2026-08-03T09:30:00Z" }] }
        ]
      },
      {
        "id": "order-collection-0",
        "stops": [{ "type": "single", "id": "stop-collection-0", "position": { "lon": 2.47, "lat": 48.842 }, "kind": "delivery", "operationDuration": "PT8M", "capacities": { "weight": 1500, "volume": 3, "containers": 7 }, "tags": ["equipment:collection-point"] }]
      },
      {
        "id": "order-collection-1",
        "stops": [{ "type": "single", "id": "stop-collection-1", "position": { "lon": 2.435, "lat": 48.84 }, "kind": "delivery", "operationDuration": "PT8M", "capacities": { "weight": 1500, "volume": 3, "containers": 7 }, "tags": ["equipment:collection-point"] }]
      },
      {
        "id": "order-collection-2",
        "stops": [{ "type": "single", "id": "stop-collection-2", "position": { "lon": 2.465, "lat": 48.814 }, "kind": "delivery", "operationDuration": "PT8M", "capacities": { "weight": 1500, "volume": 3, "containers": 7 }, "tags": ["equipment:collection-point"] }]
      },
      {
        "id": "order-collection-3",
        "stops": [{ "type": "single", "id": "stop-collection-3", "position": { "lon": 2.443, "lat": 48.818 }, "kind": "delivery", "operationDuration": "PT8M", "capacities": { "weight": 1500, "volume": 3, "containers": 7 }, "tags": ["equipment:collection-point"] }]
      }
    ],
    "objectives": ["maximizeMandatoryStops", "minimizeResources", "minimizeWorkingDuration", "minimizeDistance"],
    "additionalConstraints": [
      { "type": "incompatibleStopTags", "stopTags": ["material:organic", "material:hazardous"], "name": "no-organic-with-hazardous" }
    ],
    "additionalOperationDurations": [
      { "resourceTag": "equipment:standard", "stopTag": "equipment:collection-point", "additionalOperationDuration": "PT5M" }
    ],
    "setupDurations": [
      { "fromStopTag": "material:organic", "toStopTag": "material:glass", "setupDuration": "PT12M" }
    ]
  }
  ```
</Accordion>

## See also

* [Modeling advanced constraints](/guides/advanced-constraints#optional-steps-that-gate-a-mandatory-stop) — the `AlternativesStop` mechanism, worked through a gating example.
* [Data model](/reference/data-model#vehicle-profiles) — the full set of `vehicleProfile` fields, including routing restrictions.
* [Data model](/reference/data-model#constraints-catalog) — the full `additionalConstraints` and `globalConstraints` catalog.

Ready to model an operation like this one? [Send your first API call](/getting-started/first-api-call) with your own data, or contact [customer.success@kardinal.ai](mailto:customer.success@kardinal.ai) to walk through your specific constraints.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.