---
title: "Create a budget"
method: POST
path: "/api/v2/budgets"
tags: ["Budgets (v2)"]
---

# Create a budget

`POST /api/v2/budgets`

## Request

- Base URL: `https://www.endlesstravelplans.com`
- URL: `https://www.endlesstravelplans.com/api/v2/budgets`
- Auth: HTTP bearer

Validates like the wizard's Next, then saves the inputs as a draft owned by the caller and joins or creates
the trip (`trip.needs_choice` with `candidates` when the free trip limit leaves a choice). 422
`validation_failed` carries the wizard's messages; 403 `quota_exceeded` when the caller is at the limit.

## Request body

- object
  - `tripExternalId` string, nullable: The trip to file the budget under.
  - `tripType` 'theme_park' | 'cruise' | 'all_inclusive' | 'city', nullable
  - `park` string, nullable: Must not be greater than 32 characters.
  - `sleeping` 'on' | 'off' | 'compare', nullable
  - `sleepingForced` boolean
  - `cruiseLine` string, nullable: Must not be greater than 32 characters.
  - `port` string, nullable: Must not be greater than 32 characters.
  - `cruiseNights` integer: Must be at least 1. Must not be greater than 30.
  - `cruiseRegion` string, nullable: Must not be greater than 32 characters.
  - `preNight` boolean
  - `coast` string, nullable: Must not be greater than 32 characters.
  - `destination` string, nullable: Must not be greater than 120 characters.
  - `destinationId` integer, nullable
  - `destLat` number, nullable: Must be between -90 and 90.
  - `destLon` number, nullable: Must be between -180 and 180.
  - `destCountry` string, nullable: Must not be greater than 100 characters.
  - `destTyped` boolean
  - `places` 'one' | 'several', nullable
  - `stops` object[]: Must not have more than 8 items.
    - `destination` string, nullable: Must not be greater than 120 characters.
    - `destination_id` integer, nullable
    - `latitude` number, nullable: Must be between -90 and 90.
    - `longitude` number, nullable: Must be between -180 and 180.
    - `country` string, nullable: Must not be greater than 100 characters.
    - `nights` integer: Must be at least 1. Must not be greater than 30.
    - `travel_mode` 'flight' | 'train' | 'drive' | 'bus', nullable
    - `typed` boolean
  - `departureDate` string, nullable: Must be a valid date in the format <code>Y-m-d</code>.
  - `returnDate` string, nullable: Must be a valid date in the format <code>Y-m-d</code>.
  - `homeCity` string, nullable: Must not be greater than 120 characters.
  - `homeLat` number, nullable: Must be between -90 and 90.
  - `homeLon` number, nullable: Must be between -180 and 180.
  - `homeCountryName` string, nullable: Must not be greater than 100 characters.
  - `homeTyped` boolean
  - `mode` 'fly' | 'drive' | 'train', nullable
  - `modeSwitched` string, nullable: Must not be greater than 16 characters.
  - `homeCountry` string, nullable: Must be 2 characters.
  - `currency` 'USD' | 'EUR' | 'GBP' | 'CAD', nullable
  - `adults` integer: Must be at least 0. Must not be greater than 40.
  - `seniors` integer: Must be at least 0. Must not be greater than 40.
  - `children` integer: Must be at least 0. Must not be greater than 40.
  - `childrenAges` integer[]: Must be at least 0. Must not be greater than 17.
  - `stayTier` string, nullable: Must not be greater than 24 characters.
  - `rooms` integer: Must be at least 1. Must not be greater than 20.
  - `roomsSet` boolean
  - `parkDays` integer: Must be at least 1. Must not be greater than 14.
  - `parkHopper` boolean
  - `skipLine` boolean
  - `diningPlan` boolean
  - `drinks` boolean
  - `wifi` boolean
  - `excursions` integer: Must be at least 0. Must not be greater than 6.
  - `excursion` boolean
  - `pace` string, nullable: Must not be greater than 16 characters.
  - `cabin` string, nullable: Must not be greater than 24 characters.
  - `railClass` 'standard' | 'first', nullable
  - `bags` integer: Must be at least 0. Must not be greater than 6.
  - `airportParking` boolean
  - `gettingAround` string, nullable: Must not be greater than 32 characters.
  - `insurance` boolean
  - `carSeat` boolean
  - `contingencyPct` integer: Must be at least 0. Must not be greater than 25.

## Response `201`

- object
  - `external_id` string
  - `status` string
  - `is_owner` boolean
  - `trip_type` string
  - `pricing` object
    - `status` string

## Other responses

- `401`: unauthenticated: No valid bearer token was sent.
- `403`: quota_exceeded: A free monthly tool allowance is spent; the body carries `limit`, `used` and `remaining`.
- `422`: validation_failed: The request body failed validation; field messages are in `errors`.
- `429`: rate_limited: A throttle or a per-account allowance refused the request; `retry_after` or `remaining` may be present.
- `500`: server_error: Unhandled failure; quote `request_id` to support.

---

[API](https://skmtc.dev/endlesstravelplans/apis/endless-travel-plans-api.md) · [All operations](https://skmtc.dev/endlesstravelplans/apis/endless-travel-plans-api/llms.txt) · [OpenAPI document](https://skmtc.dev/endlesstravelplans/apis/endless-travel-plans-api/revisions/ae82ed3e4a8f?raw)
