---
title: "Create a new plan"
method: POST
path: "/plans"
tags: ["Plans"]
---

# Create a new plan

`POST /plans`

## Request

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

## Request body

- object: The request body for creating a plan.
  - `title` string, required: The title of the plan.
  - `starts` object, required: 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 created 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 depot or driver could not be found.
- `409`: Depot not found
- `500`: An internal server error occurred
- `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)
