---
title: "Update an existing plan"
method: PATCH
path: "/plans/{planId}"
tags: ["Plans"]
---

# Update an existing plan

`PATCH /plans/{planId}`

## Request

- Base URL: `https://api.spoke.com/public/v1`
- URL: `https://api.spoke.com/public/v1/plans/{planId}`
- Auth: HTTP basic
- TypeScript: <https://skmtc.dev/spoke/apis/spoke-api/docs/plans/:planId/patch.ts> (a function with typed inputs; its response is checked against the schema)

Update an existing plan. If the plan `writable` property is false, prefer using the [Live Plans API](#tag/Live-Plans).

## Path parameters

- `planId` string, required

## Request body

- object: The request body for updating a plan. All the values present in the request will update the plan value, if you wish to update only certain fields, only set them and do not set the others. Any fields not set will not be updated. **Important:** Notice that the `drivers` Array will be completely replaced. If a single driver is provided in the request, the plan will have all other previous drivers discarded.
  - `title` string: The title of the plan.
  - `starts` object: The date the plan starts. Does not accept dates that are too far in the future or past.
    - `day` integer, required: The day of the date.
    - `month` integer, required: The month of the date.
    - `year` integer, required: The year of the date.
  - `drivers` string[]: The drivers IDs of the plan, in the format `drivers/<id>`, duplicates will be ignored
  - `depot` string, nullable: The depot id, in the format `depots/<id>`. If not provided, the team's Main Depot will be used.
  - `routeOverrides` object, nullable: Overrides for the plan route behavior.
    - `startAddress` object, nullable: At least one of the fields is required. If the latitude and longitude fields are set they will override any of the others.
      - `addressName` string, nullable: The name of the address. This will not be used for geocoding, and is only for the final address display purposes.
      - `addressLineOne` string, nullable: The first line of the address.
      - `addressLineTwo` string, nullable: The second line of the address.
      - `city` string, nullable: The city of the address.
      - `state` string, nullable: The state of the address.
      - `zip` string, nullable: The zip code of the address.
      - `country` string, nullable: The country of the address.
      - `latitude` number, nullable: The latitude of the address in decimal degrees.
      - `longitude` number, nullable: The longitude of the address in decimal degrees.
    - `endAddress` object, nullable: At least one of the fields is required. If the latitude and longitude fields are set they will override any of the others.
      - `addressName` string, nullable: The name of the address. This will not be used for geocoding, and is only for the final address display purposes.
      - `addressLineOne` string, nullable: The first line of the address.
      - `addressLineTwo` string, nullable: The second line of the address.
      - `city` string, nullable: The city of the address.
      - `state` string, nullable: The state of the address.
      - `zip` string, nullable: The zip code of the address.
      - `country` string, nullable: The country of the address.
      - `latitude` number, nullable: The latitude of the address in decimal degrees.
      - `longitude` number, nullable: The longitude of the address in decimal degrees.
    - `startTime` object, nullable: Time of day in hours and minutes. Use a 24 hour clock.
      - `hour` integer, required: Hour of the day
      - `minute` integer, required: Minute of the hour
    - `endTime` object, nullable: Time of day in hours and minutes. Use a 24 hour clock.
      - `hour` integer, required: Hour of the day
      - `minute` integer, required: Minute of the hour
    - `maxStops` integer, nullable: The maximum number of stops that can be allocated per route. Note that this setting will be ignored when vehicle capacity or pickups are being used.
    - `drivingSpeed` 'slower' | 'average' | 'faster', nullable: How fast drivers drive compared to the Team's average
    - `deliverySpeed` 'slower' | 'average' | 'faster', nullable: How fast drivers deliver compared to the Team's average
    - `vehicleType` 'bike' | 'scooter' | 'car' | 'small_truck' | 'truck' | 'electric_cargo_bike', nullable: The type of vehicle used for routes in this plan
    - `optimizationSettings` object, nullable: Configures the optimization settings for routes.
      - `objective` 'distribute_services', nullable: The primary optimization objective.
      - `subObjective` 'equalize_workload' | 'equalize_time' | 'maximize_efficiency', nullable: The secondary optimization objective.

## Response `200`

The updated plan

- PlanSchema: A plan.
  - `id` string, required
  - `title` string, required: The title of the plan.
  - `starts` DateSchema, required: A date.
    - `day` integer, required: The day of the date.
    - `month` integer, required: The month of the date.
    - `year` integer, required: The year of the date.
  - `depot` string, required
  - `distributed` boolean, required: Whether the plan has been distributed.
  - `writable` boolean, required: Whether the plan is writable using the normal Plan APIs. If this is false, you will need to use the [Live Plan APIs](/api/v1#tag/Live-Plans) to edit the plan. Any plan created before 2023-04-01 is not writable.
  - `optimization` 'creating' | 'editing' | 'preview' | 'optimized' | 'optimizing', nullable, required: The optimization state of the plan.
  - `drivers` DriverIdSchema[], required: The driver IDs of the plan, in the format drivers/<id>.
  - `routes` RouteIdSchema[], required: The route IDs of the plan, in the format routes/<id>.
  - `routeOverrides` object, nullable, required: Settings for this plan to override default route configurations.
    - `startTime` object, nullable, required: Time of day in hours and minutes. Uses a 24 hour clock.
      - `hour` integer, required: Hour of the day
      - `minute` integer, required: Minute of the hour
    - `endTime` object, nullable, required: Time of day in hours and minutes. Uses a 24 hour clock.
      - `hour` integer, required: Hour of the day
      - `minute` integer, required: Minute of the hour
    - `startAddress` object, nullable, required: The address of the stop.
      - `address` string, required: The address of the stop.
      - `addressLineOne` string, required: The first line of the address.
      - `addressLineTwo` string, required: The second line of the address.
      - `latitude` number, nullable, required: The latitude of the address in decimal degrees.
      - `longitude` number, nullable, required: The longitude of the address in decimal degrees.
      - `placeId` string, nullable, required: The identifier of the place corresponding to this stop on Google Places
      - `placeTypes` string[], required: Array of strings that is provided by the Google AutoCompleteAPI
    - `endAddress` object, nullable, required: The address of the stop.
      - `address` string, required: The address of the stop.
      - `addressLineOne` string, required: The first line of the address.
      - `addressLineTwo` string, required: The second line of the address.
      - `latitude` number, nullable, required: The latitude of the address in decimal degrees.
      - `longitude` number, nullable, required: The longitude of the address in decimal degrees.
      - `placeId` string, nullable, required: The identifier of the place corresponding to this stop on Google Places
      - `placeTypes` string[], required: Array of strings that is provided by the Google AutoCompleteAPI
    - `maxStops` integer, nullable, required: Maximum number of Stops per route.
    - `drivingSpeed` 'slower' | 'average' | 'faster', nullable, required: The relative driving speed compared to others.
    - `deliverySpeed` 'slower' | 'average' | 'faster', nullable, required: The relative delivery speed compared to others.
    - `vehicleType` 'bike' | 'scooter' | 'car' | 'small_truck' | 'truck' | 'electric_cargo_bike', nullable, required: The vehicle type used for deliveries.
    - `optimizationSettings` object, required: Optimization settings for the plan.
      - `objective` 'minimize_drivers' | 'distribute_services', required: The primary optimization objective.
      - `subObjective` 'equalize_workload' | 'equalize_time' | 'maximize_efficiency', nullable: The secondary optimization objective.

## Other responses

- `400`: The request or a route override is invalid, or a driver is not active.
- `401`: Unauthorized
- `403`: Plan is no longer accessible due to data access restrictions. Upgrade to a plan that supports a longer delivery history period to access it.
- `404`: The plan, depot, or driver could not be found.
- `409`: The plan is not writable.
- `412`: Drivers and plans must have the same depot configured
- `default`: The default error model

---

[API](https://skmtc.dev/spoke/apis/spoke-api.md) - [All operations](https://skmtc.dev/spoke/apis/spoke-api/llms.txt) - [OpenAPI document](https://skmtc.dev/spoke/apis/spoke-api/revisions/a09d9194ae1c?raw)
