Set a trip's commercial state
POST/v1/trips/{tripId}/commercial-state
Moves the trip's commercial state (nueva, propuesta_enviada, aceptada, reserva_provisional, reservada, rechazada, cancelada), as the state menu does in the app. Any state may move to any other. ⚠️ This has side effects and no undo. Entering reserva_provisional or reservada creates payment plans for accepted quotes. Entering reservada opens the travelers' app access, which emails them. Asking for the state the trip is already in changes nothing.
Permissions: trips:write · Kind: write · Cost: 1 unit · MCP tool set_trip_commercial_state
Cannot be undone.
Path parameters
| Field | Type | Required | Description |
|---|---|---|---|
tripId |
uuid | yes |
Body
| Field | Type | Required | Description |
|---|---|---|---|
state |
"nueva" | "propuesta_enviada" | "aceptada" | "reserva_provisional" | "reservada" | "rechazada" | "cancelada" | yes |
Response 200
| Field | Type | Required | Description |
|---|---|---|---|
object |
"trip" | yes | |
id |
uuid | yes | |
code |
string | yes | |
title |
string | yes | |
startDate |
string | null | yes | |
endDate |
string | null | yes | |
publication |
"draft" | "published" | yes | |
commercialState |
"nueva" | "propuesta_enviada" | "aceptada" | "reserva_provisional" | "reservada" | "rechazada" | "cancelada" | yes | |
travelers |
integer | yes | |
ownerId |
uuid | null | yes | |
design |
object | null | yes | |
design.version |
1 | yes | |
design.originCity |
string | yes | |
design.stops |
object[] | yes | max 60 items |
design.stops[].id |
string | yes | |
design.stops[].city |
string | yes | |
design.stops[].nights |
integer | yes | 0–365 |
design.stops[].transferBefore |
object | null | yes | |
design.stops[].escala |
boolean | default false | |
design.stops[].place |
object | default {"placeId":"","lat":null,"lng":null,"formattedAddress":""} | |
design.returnCity |
string | null | yes | |
design.returnTransfer |
object | null | yes | |
design.returnTransfer.id |
string | yes | |
design.returnTransfer.departDate |
string | null | yes | |
design.returnTransfer.arriveDate |
string | null | yes | |
design.returnTransfer.days |
integer | 0–30, default 0 | |
design.returnTransfer.departTime |
string | default "" | |
design.returnTransfer.arriveTime |
string | default "" | |
design.returnTransfer.flight |
object | default {"flightNo":"","airline":"","fromAirport":"","toAirport":"","source":"","fetchedAt":"","scheduleValidFor":""} | |
design.originPlace |
object | default {"placeId":"","lat":null,"lng":null,"formattedAddress":""} | |
design.originPlace.placeId |
string | default "" | |
design.originPlace.lat |
number | null | default null | |
design.originPlace.lng |
number | null | default null | |
design.originPlace.formattedAddress |
string | default "" | |
design.returnPlace |
object | default {"placeId":"","lat":null,"lng":null,"formattedAddress":""} | |
design.returnPlace.placeId |
string | default "" | |
design.returnPlace.lat |
number | null | default null | |
design.returnPlace.lng |
number | null | default null | |
design.returnPlace.formattedAddress |
string | default "" | |
presentation |
object | yes | |
presentation.logoUrl |
uri | null | ||
presentation.brandColor |
string | null | ||
presentation.fontFamily |
"inter" | "montserrat" | "poppins" | "lora" | "playfair" | "source-sans" | null | ||
presentation.headerMedia |
object | null | ||
presentation.headerMedia.type |
"image" | "video" | yes | |
presentation.headerMedia.url |
uri | yes | |
profile |
object | yes | |
profile.pace |
"relajado" | "equilibrado" | "intenso" | null | default null | |
profile.profiles |
"primera_vez" | "repetidor" | "familia_ninos" | "pareja" | "grupo" | "senior" | "movilidad_reducida" | "cultural" | "gastronomico" | "naturaleza" | "fotografia" | "otaku" | "compras" | "presupuesto_ajustado" | "premium"[] | default [] | |
profile.mobility |
"normal" | "reducida" | default "normal" | |
profile.avoid |
string[] | default [] | |
profile.notes |
string | default "" | |
coverImageUrl |
string | null | yes | |
coverage |
object | null | yes | |
coverage.state |
"sin_cobros" | "pago_parcial" | "pagado" | yes | |
coverage.percent |
integer | yes | |
coverage.overpaid |
boolean | yes | |
metadata |
object | yes | |
appUrl |
string | null | yes | |
publicUrl |
string | null | yes | |
createdAt |
string | yes | |
updatedAt |
string | yes |
Errors
Errors are problem details. Besides the refusals described above, any call like this one can return:
invalid_request— Invalid requestunauthorized— Missing or invalid API keyinsufficient_scope— Missing permissionrate_limited— Rate limit reachednot_found— Not foundidempotency_key_reused— Idempotency-Key reusedrequest_in_progress— Request in progress