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

# Route Optimization

This guide walks through how to run a route optimization using Nash's REST API. You will learn how to submit an optimization request, poll for completion, and dispatch the resulting routes.

## What Is Route Optimization?

Nash's route optimization engine takes a set of orders and groups them into efficient, constraint-aware routes for your fleet. It solves the Vehicle Routing Problem (VRP) by considering:

* **Capacity constraints** (stop count, item count, weight, volume)
* **Time windows** (hard pickup and dropoff windows per order)
* **Driver shifts and breaks** (shift start/end, mandatory meal breaks)
* **Vehicle profiles** (car, truck, bicycle with different speed/access/capacity)
* **Real-time traffic** (live traffic data for accurate travel time estimates)
* **Cost modeling** (fixed cost, distance tiers, time cost, per-stop cost)

### When to Use It

Use route optimization when you have **multiple orders** to deliver and want to minimize cost, distance, or time across your fleet. Common scenarios include:

* Daily or shift-based delivery planning
* Batching orders from a store location into driver routes
* Optimizing catering, grocery, or pharmacy deliveries with time windows

## Prerequisites

Before running an optimization, make sure you have:

1. **API key and Organization ID** -- see [Generating API Key and Org ID](/reference/generating-api-key-and-org-id)
2. **At least two orders** created in Nash -- the optimizer requires a minimum of two orders
3. **A contract with vehicle optimization parameters** -- your provider contract must include vehicle parameters (vehicle count, max orders per route, driving limits, cost model). Contact Nash support if you need help configuring this.
4. **Appropriate permissions** -- your API key must have `WRITE_JOB` permission to create optimization activities and `READ_ORDER` permission to query results

## End-to-End Flow

The optimization workflow follows three steps:

1. **Submit** -- Call the optimization endpoint with your orders and parameters
2. **Poll** -- Query the returned activity ID until status is `SUCCESS`
3. **Dispatch** -- Dispatch the optimized routes to your fleet

## Step 1: Submit an Optimization Request

Use `POST /v1/activities/optimization` to submit orders for optimization. There are two ways to specify which orders to optimize:

* **Explicit order IDs** -- pass a list of `orderIds` directly
* **Filters** -- use `tags`, `pickupStoreLocationIds`, `status`, or date ranges to select orders dynamically

Both approaches can be combined (results are merged).

### Submit with Explicit Order IDs

```shell submit optimization with order IDs theme={null}
curl --request POST \
  --url https://api.sandbox.usenash.com/v1/activities/optimization \
  --header 'Authorization: Bearer $TOKEN' \
  --header 'Nash-Org-Id: $ORG_ID' \
  --header 'Content-Type: application/json' \
  --data '{
    "orderIds": ["ord_abc123", "ord_def456", "ord_ghi789"],
    "optimizationParameters": {
        "scenarios": [
            {
                "name": "",
                "value": [
                    {
                        "contractId": "your_contract_id",
                        "providerName": "YourProviderName",
                        "useAllVehicles": false,
                        "vehicleCount": 5
                    }
                ]
            }
        ]
    },
    "async": true
}'
```

### Submit with Tag Filters

```shell submit optimization with tag filters theme={null}
curl --request POST \
  --url https://api.sandbox.usenash.com/v1/activities/optimization \
  --header 'Authorization: Bearer $TOKEN' \
  --header 'Nash-Org-Id: $ORG_ID' \
  --header 'Content-Type: application/json' \
  --data '{
    "tags": ["morning-batch"],
    "optimizationParameters": {
        "scenarios": [
            {
                "name": "",
                "value": [
                    {
                        "contractId": "your_contract_id",
                        "providerName": "YourProviderName",
                        "useAllVehicles": false,
                        "vehicleCount": 10
                    }
                ]
            }
        ]
    },
    "async": true
}'
```

### Example Response

```json submit optimization response theme={null}
{
    "id": "act_abc123def456",
    "createdAt": "2026-02-25T10:00:00Z",
    "action": "act_optimize_orders",
    "status": "QUEUED",
    "externalOptimizationId": null,
    "inputData": {
        "order_ids": ["ord_abc123", "ord_def456", "ord_ghi789"]
    },
    "result": null
}
```

<Note>
  When `async` is `true` (the default), the activity is created with status `QUEUED` and optimization runs in the background. When `async` is `false`, the request blocks until optimization completes and returns the final status directly.
</Note>

### Request Parameters

| Parameter                 | Type      | Required | Description                                                                   |
| ------------------------- | --------- | -------- | ----------------------------------------------------------------------------- |
| `optimizationParameters`  | Object    | Yes      | Optimization configuration (see below)                                        |
| `orderIds`                | String\[] | No       | Explicit list of order IDs to optimize                                        |
| `tags`                    | String\[] | No       | Filter orders by tags                                                         |
| `pickupStoreLocationIds`  | String\[] | No       | Filter orders by pickup store location                                        |
| `dropoffStoreLocationIds` | String\[] | No       | Filter orders by dropoff store location                                       |
| `status`                  | String\[] | No       | Filter orders by status                                                       |
| `startDate`               | DateTime  | No       | Filter by pickup start date                                                   |
| `endDate`                 | DateTime  | No       | Filter by pickup end date                                                     |
| `storeLocationId`         | String    | No       | Run store-location-based optimization (mutually exclusive with order filters) |
| `async`                   | Boolean   | No       | Run asynchronously (default: `true`)                                          |
| `sessionId`               | String    | No       | Optional session identifier for grouping activities                           |
| `optimizationStrategyIds` | String\[] | No       | Filter by optimization strategy IDs                                           |

### Optimization Parameters Object

The `optimizationParameters` object configures how the optimizer builds routes:

```json optimization parameters structure theme={null}
{
    "scenarios": [
        {
            "name": "",
            "value": [
                {
                    "contractId": "your_contract_id",
                    "providerName": "YourProviderName",
                    "useAllVehicles": false,
                    "vehicleCount": 5
                }
            ]
        }
    ],
    "softCapabilities": [],
    "searchLevel": null,
    "clusteringLevel": null,
    "softClusterLabel": false
}
```

| Field                                | Type      | Description                                                                                                            |
| ------------------------------------ | --------- | ---------------------------------------------------------------------------------------------------------------------- |
| `scenarios`                          | Array     | Fleet scenarios to optimize across. Each scenario has a `name` and a `value` array of vehicle/contract configurations. |
| `scenarios[].value[].contractId`     | String    | The contract ID defining vehicle parameters and cost model                                                             |
| `scenarios[].value[].providerName`   | String    | The provider name for this vehicle group                                                                               |
| `scenarios[].value[].vehicleCount`   | Integer   | Number of vehicles available for this scenario                                                                         |
| `scenarios[].value[].useAllVehicles` | Boolean   | If `true`, forces all vehicles to be used even if fewer would suffice                                                  |
| `softCapabilities`                   | String\[] | Optional soft constraints (e.g., vehicle capabilities that are preferred but not required)                             |
| `searchLevel`                        | Integer   | Search depth (0-3). Higher values produce better solutions but take longer. `null` uses the default.                   |
| `clusteringLevel`                    | Integer   | Controls geographic clustering of orders before optimization. `null` uses the default.                                 |
| `softClusterLabel`                   | Boolean   | When `true`, cluster labels are soft constraints rather than hard boundaries                                           |

## Step 2: Poll for Optimization Status

After submitting an optimization request, poll the activity status until it reaches a terminal state.

```shell poll activity status theme={null}
curl --request GET \
  --url https://api.sandbox.usenash.com/v1/activities/act_abc123def456 \
  --header 'Authorization: Bearer $TOKEN' \
  --header 'Nash-Org-Id: $ORG_ID'
```

### Activity Status Values

| Status        | Description                                                                        |
| ------------- | ---------------------------------------------------------------------------------- |
| `SCHEDULED`   | Activity is scheduled for future execution                                         |
| `QUEUED`      | Activity is queued and waiting to be processed                                     |
| `IN_PROGRESS` | Optimization is currently running                                                  |
| `SUCCESS`     | Optimization completed successfully -- results are available in the `result` field |
| `FAILED`      | Optimization failed -- check the `result` field for error details                  |
| `CANCELLED`   | Activity was cancelled                                                             |
| `SKIPPED`     | Activity was skipped (e.g., no eligible orders found)                              |

### Polling Strategy

We recommend polling every **5 seconds** with a maximum timeout of **5 minutes**. Most optimizations complete within 30 seconds, but larger order sets or higher search levels may take longer.

Poll `GET /v1/activities/{id}` repeatedly until the `status` field is `SUCCESS`, `FAILED`, `CANCELLED`, or `SKIPPED`.

### Example Success Response

When the activity status is `SUCCESS`, the response contains the `externalOptimizationId` you will need for dispatch:

```json poll success response theme={null}
{
    "id": "act_abc123def456",
    "createdAt": "2026-02-25T10:00:00Z",
    "action": "act_optimize_orders",
    "status": "SUCCESS",
    "externalOptimizationId": "opt_ext_789",
    "inputData": {
        "order_ids": ["ord_abc123", "ord_def456", "ord_ghi789"]
    },
    "result": [
        {
            "optimized_route": {
                "routes": ["..."],
                "unassigned": []
            }
        }
    ]
}
```

## Step 3: Dispatch Optimized Routes

Once optimization completes, you can dispatch the routes. There are two dispatch paths:

### Option A: Dispatch Optimized Orders Directly

Use `POST /v1/activities/{id}/dispatch` to dispatch the optimized orders in a single step. This creates routes, jobs, and (if `autoDispatch` is `true`) dispatches them to providers.

```shell dispatch optimized orders theme={null}
curl --request POST \
  --url https://api.sandbox.usenash.com/v1/activities/act_abc123def456/dispatch \
  --header 'Authorization: Bearer $TOKEN' \
  --header 'Nash-Org-Id: $ORG_ID' \
  --header 'Content-Type: application/json' \
  --data '{
    "autoDispatch": true
}'
```

Both `orderIds` and `externalOptimizationId` are resolved automatically from the activity. You can optionally pass `orderIds` to dispatch only a subset of the optimized orders.

| Parameter      | Type      | Required | Description                                                                         |
| -------------- | --------- | -------- | ----------------------------------------------------------------------------------- |
| `orderIds`     | String\[] | No       | Order IDs to dispatch. If omitted, all orders from the optimization are dispatched. |
| `autoDispatch` | Boolean   | No       | Automatically dispatch to provider (default: `true`)                                |

### Option B: Save Routes First, Then Dispatch

For more control, you can save the optimization as routes, review them, and then dispatch individually.

**Save routes:**

Use `POST /v1/activities/{id}/save-routes` to create route objects from the optimization results. No request body is needed -- the activity ID in the URL is sufficient.

```shell save optimization routes theme={null}
curl --request POST \
  --url https://api.sandbox.usenash.com/v1/activities/act_abc123def456/save-routes \
  --header 'Authorization: Bearer $TOKEN' \
  --header 'Nash-Org-Id: $ORG_ID'
```

This returns the created route objects with their IDs, stops, and order assignments. You can also view these routes in the [Nash Portal](https://portal.usenash.com) before dispatching.

**Dispatch routes:**

Use `POST /v1/routes/dispatch` to dispatch one or more saved routes.

```shell dispatch routes theme={null}
curl --request POST \
  --url https://api.sandbox.usenash.com/v1/routes/dispatch \
  --header 'Authorization: Bearer $TOKEN' \
  --header 'Nash-Org-Id: $ORG_ID' \
  --header 'Content-Type: application/json' \
  --data '{
    "routeIds": ["rte_route_id_1", "rte_route_id_2"],
    "autoDispatch": true
}'
```

| Parameter      | Type      | Required | Description                                          |
| -------------- | --------- | -------- | ---------------------------------------------------- |
| `routeIds`     | String\[] | Yes      | The route IDs to dispatch                            |
| `autoDispatch` | Boolean   | No       | Automatically dispatch to provider (default: `true`) |

## Common Pitfalls and Troubleshooting

### Not Enough Orders

The optimizer requires **at least two orders**. If you pass fewer, the request returns an error. Make sure your filters match enough orders before submitting.

### Missing Vehicle Optimization Parameters

If your contract doesn't have `vehicle_optimization_parameters` configured, optimization will fail. These parameters define vehicle capacity, driving limits, and cost model. Contact Nash support to configure them on your contract.

### Async Timing Issues

When using `async: true` (the default), the request returns immediately with status `QUEUED`. You **must** poll the activity status before attempting to dispatch. Dispatching before optimization completes will fail.

### Mismatched Optimization Mode

The endpoint has two mutually exclusive modes:

* **Order-based**: Use `orderIds`, `tags`, and other order filter fields (no `storeLocationId`)
* **Store-location-based**: Use `storeLocationId` (no order filter fields)

Mixing fields from both modes will result in a validation error.

### Empty Result / No Routes

If the optimizer cannot fit orders into routes given the constraints (time windows, capacity, vehicle count), the result may contain unassigned orders. Consider:

* Increasing `vehicleCount`
* Relaxing time window constraints on your orders
* Checking that pickup and dropoff addresses are valid and geocoded

### Optimization Strategy IDs

If you use Optimization Strategies (pre-configured optimization profiles), pass their IDs via `optimizationStrategyIds`. This applies the strategy's contract, schedule, and constraint configuration automatically.

## Related Resources

* [Orchestration Overview](/reference/orchestration) -- full overview of Nash's delivery orchestration capabilities
* [Create or Update Route](/api-reference/route/create-or-update-route) -- manually create or update routes
* [Get Route](/api-reference/route/get-route) -- retrieve route details
* [Dispatch Strategies](/api-reference/dispatch-strategies/dispatch-strategy) -- configure automatic provider selection
* [Authentication](/reference/authentication) -- API key setup and headers
