> ## 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.

# Cost modeling

> Represent cost in real currency with `cost`, piecewise-linear cost functions, and custom objectives via `customCost`.

<Tip>
  `cost`, `minimizeCosts`, and custom objectives are deliberately powerful, but only a minority of plans need them. Before reaching for this page, check whether a standard objective (`minimizeDistance`, `minimizeWorkingDuration`, `minimizeResources`, and so on) already expresses the trade-off you're after — see [How the optimization engine works](/concepts/how-the-optimization-engine-works#what-the-engine-optimizes).
</Tip>

## The `cost` object

A resource's `cost` object accumulates several independent contributions into a single currency figure that the `minimizeCosts` objective then optimizes: `using` (a flat cost per resource used), `workedHours`, `km`, `costsByStopTag`, `costsByCapacity`, `costPerCapacityPerTravelledKm`, and `costPerCapacityPerTravelledHour`.

These fields reformulate, in a real currency, the same underlying quantities that `minimizeDistance`, `minimizeWorkingDuration`, and `minimizeResources` already count in raw units (km, hours, vehicles). This isn't a strict one-to-one equivalence — it's a different objective, built on a monetary version of the same data, not a guaranteed substitute for the raw-unit objectives.

## Piecewise-linear cost functions

Every cost field preceding this section except `using` accepts a `CostFloorsAndCoeffs`-shaped object: a `constantCost` base, a `costCoeff` rate applied past `costFloor`, and an optional steeper `overcostCoeff` rate past a second, higher `overcostFloor` — the same shape as a salary with a base, a free allowance, and an overtime-style rate beyond it. [Modeling advanced constraints](/guides/advanced-constraints#tolerated-capacity-overflow) already has a worked `costsByCapacity` example using this object, to make capacity overflow economically unattractive rather than infeasible.

## Guaranteeing a minimum per-tour revenue via `costsByCapacity`

Create a capacity that only tracks completed deliveries — for example `deliveredUnits`, incremented solely on delivery stops rather than tied to any real load — then put a `costFloor`/`constantCost` on that capacity so a tour that ends below the threshold keeps paying a flat penalty:

```json theme={null}
{
  "resources": [
    {
      "id": "subcontractor-van-1",
      "capacities": { "weight": 800 },
      "cost": {
        "costsByCapacity": {
          "deliveredUnits": { "constantCost": 200, "costFloor": 50, "costCoeff": -4 }
        }
      }
    }
  ],
  "objectives": ["maximizeMandatoryStops", "minimizeCosts"]
}
```

The figures here (`200`, `50`, `-4`) are illustrative — confirm against the actual subcontractor rate before publishing a real payload. Use generic ids only (`subcontractor-van-1`), never a real client name, or a real contract amount.

## Rebuilding the default objective list with `customCost`

A `CustomObjective` (`type: "custom"`) lets you optimize a cost expression built from `costsByResourceTag` instead of a built-in `ObjectivesEnum` entry — for example scoping a custom fuel-cost objective to just the resources carrying a given tag:

```json theme={null}
{
  "objectives": [
    {
      "type": "custom",
      "name": "minimizeFuelCost",
      "direction": "minimize",
      "costsByResourceTag": {
        "subcontractorA": { "km": { "costCoeff": 0.18 } }
      }
    }
  ]
}
```

`name` must not collide with a built-in `ObjectivesEnum` value (the schema enforces this). `costsByResourceTag` maps a `Cost`-shaped object to a resource tag, so a custom objective can apply to a subset of the fleet rather than every resource.

## Modeling revenue or margin per stop

`costsByStopTag` with negative `constantCost` values represents a revenue (a negative cost) rather than a charge, combined with `minimizeCosts`:

```json theme={null}
{
  "id": "van-1",
  "cost": {
    "costsByStopTag": {
      "standard": { "constantCost": -30 },
      "premium": { "constantCost": -63 }
    }
  }
}
```

<Warning>
  If you'd rather reason entirely in positive revenue figures, use a `CustomObjective` with `direction: "maximize"` and positive `costsByStopTag` values instead of negating them under the built-in `minimizeCosts` — there is no built-in `maximizeCosts` objective in `ObjectivesEnum`, only `minimizeCosts`. The two approaches aren't interchangeable without also adjusting whatever thresholds you've set elsewhere.
</Warning>

Tag a stop with its own `stop.id` instead of a shared category tag when the rate is unique per stop rather than per category.

## See also

* [How the optimization engine works](/concepts/how-the-optimization-engine-works#what-the-engine-optimizes) — where `minimizeCosts` sits in the default objective order.
* [Modeling advanced constraints](/guides/advanced-constraints#tolerated-capacity-overflow) — the existing `costsByCapacity` worked example for tolerated overflow.
