{"openapi":"3.1.0","info":{"title":"bymundi API","version":"2026-09-26","description":"Trips, itineraries and catalog for travel agencies. Authenticate with a personal API key from Integrations → API & MCP: `Authorization: Bearer bym_live_…`. Errors are RFC 9457 problem details; writes accept `Idempotency-Key`."},"servers":[{"url":"https://api.bymundi.com/v1"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","description":"A personal API key (`bym_live_…`)."}},"parameters":{"IdempotencyKey":{"name":"Idempotency-Key","in":"header","required":false,"schema":{"type":"string","maxLength":255},"description":"Makes a write safe to retry: the first response is replayed for 24 h."},"DryRun":{"name":"dryRun","in":"query","required":false,"schema":{"type":"boolean"},"description":"Plan the change and return its effects without persisting anything."}},"schemas":{"Problem":{"type":"object","required":["type","title","status","detail","code","requestId"],"properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"code":{"type":"string"},"requestId":{"type":"string"},"errors":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"message":{"type":"string"}}}}}}}},"paths":{"/me":{"get":{"operationId":"me.get","summary":"Who am I","description":"Returns the key's owner, the agency, the key's permissions and the rate limits. Call it first to check that a key works and what it may do.\n\n**Permissions:** any valid key.","tags":["Account"],"x-scopes":[],"x-undo":"none","parameters":[],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"object":{"type":"string","const":"me"},"user":{"type":"object","properties":{"id":{"type":"string"},"displayName":{"type":["string","null"]},"email":{"type":["string","null"]}},"required":["id","displayName","email"],"additionalProperties":false},"agency":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":["string","null"]}},"required":["id","name"],"additionalProperties":false},"key":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"prefix":{"type":"string"},"scopes":{"type":"array","items":{"type":"string"}},"expiresAt":{"type":["string","null"]}},"required":["id","name","prefix","scopes","expiresAt"],"additionalProperties":false},"limits":{"type":"object","properties":{"perKeyPerMinute":{"type":"integer"},"perAgencyPerMinute":{"type":"integer"}},"required":["perKeyPerMinute","perAgencyPerMinute"],"additionalProperties":false}},"required":["object","user","agency","key","limits"],"additionalProperties":false}}}},"default":{"description":"Error (RFC 9457)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/trips":{"get":{"operationId":"trips.list","summary":"List trips","description":"Lists the agency's live trips (archived ones are at GET /trips/archived), most recently changed first. Filter by `q` (text in the title), `publication`, `commercialState`, `ownerId`, `updatedSince` and up to 5 `metadata[key]=value` pairs, which must all match. For a polling trigger (n8n, Zapier), pass the last `updatedAt` you saw as `updatedSince` with `sort=updatedAt`, and follow `nextCursor` until it is null.\n\n**Permissions:** `trips:read`.","tags":["Trips"],"x-scopes":["trips:read"],"x-undo":"none","parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":100,"default":25}},{"name":"cursor","in":"query","required":false,"schema":{"type":"string","minLength":1,"maxLength":500}},{"name":"sort","in":"query","required":false,"schema":{"type":"string","enum":["updatedAt","-updatedAt","createdAt","-createdAt"],"default":"-updatedAt"}},{"name":"updatedSince","in":"query","required":false,"schema":{"type":"string","format":"date-time"}},{"name":"q","in":"query","required":false,"schema":{"type":"string","minLength":1,"maxLength":200}},{"name":"publication","in":"query","required":false,"schema":{"type":"string","enum":["draft","published"]}},{"name":"commercialState","in":"query","required":false,"schema":{"type":"string","enum":["nueva","propuesta_enviada","aceptada","reserva_provisional","reservada","rechazada","cancelada"]}},{"name":"ownerId","in":"query","required":false,"schema":{"type":"string","format":"uuid"}},{"name":"metadata","in":"query","required":false,"schema":{"type":"object","additionalProperties":{"type":"string","maxLength":500},"propertyNames":{"pattern":"^[A-Za-z0-9_.-]{1,40}$"}},"style":"deepObject","explode":true}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"object":{"type":"string","const":"list"},"data":{"type":"array","items":{"type":"object","properties":{"object":{"type":"string","const":"trip"},"id":{"type":"string","format":"uuid"},"code":{"type":"string"},"title":{"type":"string"},"startDate":{"type":["string","null"]},"endDate":{"type":["string","null"]},"publication":{"type":"string","enum":["draft","published"]},"commercialState":{"type":"string","enum":["nueva","propuesta_enviada","aceptada","reserva_provisional","reservada","rechazada","cancelada"]},"travelers":{"type":"integer"},"ownerId":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}]},"design":{"anyOf":[{"type":"object","properties":{"version":{"type":"number","const":1},"originCity":{"type":"string"},"stops":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"city":{"type":"string"},"nights":{"type":"integer","minimum":0,"maximum":365},"transferBefore":{"anyOf":[{"type":"object","properties":{"id":{"type":"string"},"departDate":{"type":["string","null"]},"arriveDate":{"type":["string","null"]},"days":{"type":"integer","minimum":0,"maximum":30,"default":0},"departTime":{"type":"string","default":""},"arriveTime":{"type":"string","default":""},"flight":{"type":"object","properties":{"flightNo":{"type":"string","default":""},"airline":{"type":"string","default":""},"fromAirport":{"type":"string","default":""},"toAirport":{"type":"string","default":""},"source":{"type":"string","default":""},"fetchedAt":{"type":"string","default":""},"scheduleValidFor":{"type":"string","default":""}},"additionalProperties":false,"default":{"flightNo":"","airline":"","fromAirport":"","toAirport":"","source":"","fetchedAt":"","scheduleValidFor":""}}},"required":["id","departDate","arriveDate"],"additionalProperties":false},{"type":"null"}]},"escala":{"type":"boolean","default":false},"place":{"type":"object","properties":{"placeId":{"type":"string","default":""},"lat":{"type":["number","null"],"default":null},"lng":{"type":["number","null"],"default":null},"formattedAddress":{"type":"string","default":""}},"additionalProperties":false,"default":{"placeId":"","lat":null,"lng":null,"formattedAddress":""}}},"required":["id","city","nights","transferBefore"],"additionalProperties":false},"maxItems":60},"returnCity":{"type":["string","null"]},"returnTransfer":{"anyOf":[{"type":"object","properties":{"id":{"type":"string"},"departDate":{"type":["string","null"]},"arriveDate":{"type":["string","null"]},"days":{"type":"integer","minimum":0,"maximum":30,"default":0},"departTime":{"type":"string","default":""},"arriveTime":{"type":"string","default":""},"flight":{"type":"object","properties":{"flightNo":{"type":"string","default":""},"airline":{"type":"string","default":""},"fromAirport":{"type":"string","default":""},"toAirport":{"type":"string","default":""},"source":{"type":"string","default":""},"fetchedAt":{"type":"string","default":""},"scheduleValidFor":{"type":"string","default":""}},"additionalProperties":false,"default":{"flightNo":"","airline":"","fromAirport":"","toAirport":"","source":"","fetchedAt":"","scheduleValidFor":""}}},"required":["id","departDate","arriveDate"],"additionalProperties":false},{"type":"null"}]},"originPlace":{"type":"object","properties":{"placeId":{"type":"string","default":""},"lat":{"type":["number","null"],"default":null},"lng":{"type":["number","null"],"default":null},"formattedAddress":{"type":"string","default":""}},"additionalProperties":false,"default":{"placeId":"","lat":null,"lng":null,"formattedAddress":""}},"returnPlace":{"type":"object","properties":{"placeId":{"type":"string","default":""},"lat":{"type":["number","null"],"default":null},"lng":{"type":["number","null"],"default":null},"formattedAddress":{"type":"string","default":""}},"additionalProperties":false,"default":{"placeId":"","lat":null,"lng":null,"formattedAddress":""}}},"required":["version","originCity","stops","returnCity","returnTransfer"],"additionalProperties":false},{"type":"null"}]},"presentation":{"type":"object","properties":{"logoUrl":{"anyOf":[{"type":"string","format":"uri"},{"type":"null"}]},"brandColor":{"anyOf":[{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},{"type":"null"}]},"fontFamily":{"anyOf":[{"type":"string","enum":["inter","montserrat","poppins","lora","playfair","source-sans"]},{"type":"null"}]},"headerMedia":{"anyOf":[{"type":"object","properties":{"type":{"type":"string","enum":["image","video"]},"url":{"type":"string","format":"uri"}},"required":["type","url"],"additionalProperties":false},{"type":"null"}]}},"additionalProperties":false},"profile":{"type":"object","properties":{"pace":{"anyOf":[{"type":"string","enum":["relajado","equilibrado","intenso"]},{"type":"null"}],"default":null},"profiles":{"type":"array","items":{"type":"string","enum":["primera_vez","repetidor","familia_ninos","pareja","grupo","senior","movilidad_reducida","cultural","gastronomico","naturaleza","fotografia","otaku","compras","presupuesto_ajustado","premium"]},"default":[]},"mobility":{"type":"string","enum":["normal","reducida"],"default":"normal"},"avoid":{"type":"array","items":{"type":"string"},"default":[]},"notes":{"type":"string","default":""}},"additionalProperties":false},"coverImageUrl":{"type":["string","null"]},"coverage":{"anyOf":[{"type":"object","properties":{"state":{"type":"string","enum":["sin_cobros","pago_parcial","pagado"]},"percent":{"type":"integer"},"overpaid":{"type":"boolean"}},"required":["state","percent","overpaid"],"additionalProperties":false},{"type":"null"}]},"metadata":{"type":"object","additionalProperties":{"type":"string","maxLength":500},"propertyNames":{"pattern":"^[A-Za-z0-9_.-]{1,40}$"}},"appUrl":{"type":["string","null"]},"publicUrl":{"type":["string","null"]},"createdAt":{"type":"string"},"updatedAt":{"type":"string"}},"required":["object","id","code","title","startDate","endDate","publication","commercialState","travelers","ownerId","design","presentation","profile","coverImageUrl","coverage","metadata","appUrl","publicUrl","createdAt","updatedAt"],"additionalProperties":false}},"nextCursor":{"type":["string","null"]}},"required":["object","data","nextCursor"],"additionalProperties":false}}}},"default":{"description":"Error (RFC 9457)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"post":{"operationId":"trips.create","summary":"Create a trip","description":"Creates a trip owned by the key's owner: blank, from a trip template (`templateId`, which brings the template's design and blocks), or from a `design` (a route: origin, stops with nights, transfers), which builds one itinerary day per trip day and derives `endDate`. A design needs `startDate`. Optional `travelers`, `ownerId`, `presentation`, `profile` and `metadata` are set in the same change. With `?dryRun=true` nothing is written and a `trip_create_preview` comes back.\n\n**Permissions:** `trips:write`.\n\n**Undo:** the response carries `Bymundi-Change-Id`; `POST /changes/{changeId}/revert` undoes it.","tags":["Trips"],"x-scopes":["trips:write"],"x-undo":"change","parameters":[{"$ref":"#/components/parameters/DryRun"},{"$ref":"#/components/parameters/IdempotencyKey"}],"responses":{"201":{"description":"Success","content":{"application/json":{"schema":{"anyOf":[{"type":"object","properties":{"object":{"type":"string","const":"trip"},"id":{"type":"string","format":"uuid"},"code":{"type":"string"},"title":{"type":"string"},"startDate":{"type":["string","null"]},"endDate":{"type":["string","null"]},"publication":{"type":"string","enum":["draft","published"]},"commercialState":{"type":"string","enum":["nueva","propuesta_enviada","aceptada","reserva_provisional","reservada","rechazada","cancelada"]},"travelers":{"type":"integer"},"ownerId":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}]},"design":{"anyOf":[{"type":"object","properties":{"version":{"type":"number","const":1},"originCity":{"type":"string"},"stops":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"city":{"type":"string"},"nights":{"type":"integer","minimum":0,"maximum":365},"transferBefore":{"anyOf":[{"type":"object","properties":{"id":{"type":"string"},"departDate":{"type":["string","null"]},"arriveDate":{"type":["string","null"]},"days":{"type":"integer","minimum":0,"maximum":30,"default":0},"departTime":{"type":"string","default":""},"arriveTime":{"type":"string","default":""},"flight":{"type":"object","properties":{"flightNo":{"type":"string","default":""},"airline":{"type":"string","default":""},"fromAirport":{"type":"string","default":""},"toAirport":{"type":"string","default":""},"source":{"type":"string","default":""},"fetchedAt":{"type":"string","default":""},"scheduleValidFor":{"type":"string","default":""}},"additionalProperties":false,"default":{"flightNo":"","airline":"","fromAirport":"","toAirport":"","source":"","fetchedAt":"","scheduleValidFor":""}}},"required":["id","departDate","arriveDate"],"additionalProperties":false},{"type":"null"}]},"escala":{"type":"boolean","default":false},"place":{"type":"object","properties":{"placeId":{"type":"string","default":""},"lat":{"type":["number","null"],"default":null},"lng":{"type":["number","null"],"default":null},"formattedAddress":{"type":"string","default":""}},"additionalProperties":false,"default":{"placeId":"","lat":null,"lng":null,"formattedAddress":""}}},"required":["id","city","nights","transferBefore"],"additionalProperties":false},"maxItems":60},"returnCity":{"type":["string","null"]},"returnTransfer":{"anyOf":[{"type":"object","properties":{"id":{"type":"string"},"departDate":{"type":["string","null"]},"arriveDate":{"type":["string","null"]},"days":{"type":"integer","minimum":0,"maximum":30,"default":0},"departTime":{"type":"string","default":""},"arriveTime":{"type":"string","default":""},"flight":{"type":"object","properties":{"flightNo":{"type":"string","default":""},"airline":{"type":"string","default":""},"fromAirport":{"type":"string","default":""},"toAirport":{"type":"string","default":""},"source":{"type":"string","default":""},"fetchedAt":{"type":"string","default":""},"scheduleValidFor":{"type":"string","default":""}},"additionalProperties":false,"default":{"flightNo":"","airline":"","fromAirport":"","toAirport":"","source":"","fetchedAt":"","scheduleValidFor":""}}},"required":["id","departDate","arriveDate"],"additionalProperties":false},{"type":"null"}]},"originPlace":{"type":"object","properties":{"placeId":{"type":"string","default":""},"lat":{"type":["number","null"],"default":null},"lng":{"type":["number","null"],"default":null},"formattedAddress":{"type":"string","default":""}},"additionalProperties":false,"default":{"placeId":"","lat":null,"lng":null,"formattedAddress":""}},"returnPlace":{"type":"object","properties":{"placeId":{"type":"string","default":""},"lat":{"type":["number","null"],"default":null},"lng":{"type":["number","null"],"default":null},"formattedAddress":{"type":"string","default":""}},"additionalProperties":false,"default":{"placeId":"","lat":null,"lng":null,"formattedAddress":""}}},"required":["version","originCity","stops","returnCity","returnTransfer"],"additionalProperties":false},{"type":"null"}]},"presentation":{"type":"object","properties":{"logoUrl":{"anyOf":[{"type":"string","format":"uri"},{"type":"null"}]},"brandColor":{"anyOf":[{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},{"type":"null"}]},"fontFamily":{"anyOf":[{"type":"string","enum":["inter","montserrat","poppins","lora","playfair","source-sans"]},{"type":"null"}]},"headerMedia":{"anyOf":[{"type":"object","properties":{"type":{"type":"string","enum":["image","video"]},"url":{"type":"string","format":"uri"}},"required":["type","url"],"additionalProperties":false},{"type":"null"}]}},"additionalProperties":false},"profile":{"type":"object","properties":{"pace":{"anyOf":[{"type":"string","enum":["relajado","equilibrado","intenso"]},{"type":"null"}],"default":null},"profiles":{"type":"array","items":{"type":"string","enum":["primera_vez","repetidor","familia_ninos","pareja","grupo","senior","movilidad_reducida","cultural","gastronomico","naturaleza","fotografia","otaku","compras","presupuesto_ajustado","premium"]},"default":[]},"mobility":{"type":"string","enum":["normal","reducida"],"default":"normal"},"avoid":{"type":"array","items":{"type":"string"},"default":[]},"notes":{"type":"string","default":""}},"additionalProperties":false},"coverImageUrl":{"type":["string","null"]},"coverage":{"anyOf":[{"type":"object","properties":{"state":{"type":"string","enum":["sin_cobros","pago_parcial","pagado"]},"percent":{"type":"integer"},"overpaid":{"type":"boolean"}},"required":["state","percent","overpaid"],"additionalProperties":false},{"type":"null"}]},"metadata":{"type":"object","additionalProperties":{"type":"string","maxLength":500},"propertyNames":{"pattern":"^[A-Za-z0-9_.-]{1,40}$"}},"appUrl":{"type":["string","null"]},"publicUrl":{"type":["string","null"]},"createdAt":{"type":"string"},"updatedAt":{"type":"string"}},"required":["object","id","code","title","startDate","endDate","publication","commercialState","travelers","ownerId","design","presentation","profile","coverImageUrl","coverage","metadata","appUrl","publicUrl","createdAt","updatedAt"],"additionalProperties":false},{"type":"object","properties":{"object":{"type":"string","const":"trip_create_preview"},"title":{"type":"string"},"startDate":{"type":["string","null"]},"endDate":{"type":["string","null"]},"blocksAdded":{"type":"integer"},"days":{"type":"array","items":{"type":"object","properties":{"date":{"type":"string"},"title":{"type":"string"}},"required":["date","title"],"additionalProperties":false}}},"required":["object","title","startDate","endDate","blocksAdded","days"],"additionalProperties":false}]}}}},"default":{"description":"Error (RFC 9457)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"title":{"type":"string","minLength":1},"startDate":{"anyOf":[{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$"},{"type":"null"}]},"endDate":{"anyOf":[{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$"},{"type":"null"}]},"templateId":{"type":"string","format":"uuid"},"design":{"type":"object","properties":{"version":{"type":"number","const":1},"originCity":{"type":"string"},"stops":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"city":{"type":"string"},"nights":{"type":"integer","minimum":0,"maximum":365},"transferBefore":{"anyOf":[{"type":"object","properties":{"id":{"type":"string"},"departDate":{"type":["string","null"]},"arriveDate":{"type":["string","null"]},"days":{"type":"integer","minimum":0,"maximum":30,"default":0},"departTime":{"type":"string","default":""},"arriveTime":{"type":"string","default":""},"flight":{"type":"object","properties":{"flightNo":{"type":"string","default":""},"airline":{"type":"string","default":""},"fromAirport":{"type":"string","default":""},"toAirport":{"type":"string","default":""},"source":{"type":"string","default":""},"fetchedAt":{"type":"string","default":""},"scheduleValidFor":{"type":"string","default":""}},"additionalProperties":false,"default":{"flightNo":"","airline":"","fromAirport":"","toAirport":"","source":"","fetchedAt":"","scheduleValidFor":""}}},"required":["id","departDate","arriveDate"],"additionalProperties":false},{"type":"null"}]},"escala":{"type":"boolean","default":false},"place":{"type":"object","properties":{"placeId":{"type":"string","default":""},"lat":{"type":["number","null"],"default":null},"lng":{"type":["number","null"],"default":null},"formattedAddress":{"type":"string","default":""}},"additionalProperties":false,"default":{"placeId":"","lat":null,"lng":null,"formattedAddress":""}}},"required":["id","city","nights","transferBefore"],"additionalProperties":false},"maxItems":60},"returnCity":{"type":["string","null"]},"returnTransfer":{"anyOf":[{"type":"object","properties":{"id":{"type":"string"},"departDate":{"type":["string","null"]},"arriveDate":{"type":["string","null"]},"days":{"type":"integer","minimum":0,"maximum":30,"default":0},"departTime":{"type":"string","default":""},"arriveTime":{"type":"string","default":""},"flight":{"type":"object","properties":{"flightNo":{"type":"string","default":""},"airline":{"type":"string","default":""},"fromAirport":{"type":"string","default":""},"toAirport":{"type":"string","default":""},"source":{"type":"string","default":""},"fetchedAt":{"type":"string","default":""},"scheduleValidFor":{"type":"string","default":""}},"additionalProperties":false,"default":{"flightNo":"","airline":"","fromAirport":"","toAirport":"","source":"","fetchedAt":"","scheduleValidFor":""}}},"required":["id","departDate","arriveDate"],"additionalProperties":false},{"type":"null"}]},"originPlace":{"type":"object","properties":{"placeId":{"type":"string","default":""},"lat":{"type":["number","null"],"default":null},"lng":{"type":["number","null"],"default":null},"formattedAddress":{"type":"string","default":""}},"additionalProperties":false,"default":{"placeId":"","lat":null,"lng":null,"formattedAddress":""}},"returnPlace":{"type":"object","properties":{"placeId":{"type":"string","default":""},"lat":{"type":["number","null"],"default":null},"lng":{"type":["number","null"],"default":null},"formattedAddress":{"type":"string","default":""}},"additionalProperties":false,"default":{"placeId":"","lat":null,"lng":null,"formattedAddress":""}}},"required":["version","originCity","stops","returnCity","returnTransfer"],"additionalProperties":false},"travelers":{"type":"integer","minimum":1,"maximum":40},"ownerId":{"type":"string","format":"uuid"},"presentation":{"type":"object","properties":{"logoUrl":{"anyOf":[{"type":"string","format":"uri"},{"type":"null"}]},"brandColor":{"anyOf":[{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},{"type":"null"}]},"fontFamily":{"anyOf":[{"type":"string","enum":["inter","montserrat","poppins","lora","playfair","source-sans"]},{"type":"null"}]},"headerMedia":{"anyOf":[{"type":"object","properties":{"type":{"type":"string","enum":["image","video"]},"url":{"type":"string","format":"uri"}},"required":["type","url"],"additionalProperties":false},{"type":"null"}]}},"additionalProperties":false},"profile":{"type":"object","properties":{"pace":{"anyOf":[{"type":"string","enum":["relajado","equilibrado","intenso"]},{"type":"null"}]},"profiles":{"type":"array","items":{"type":"string","enum":["primera_vez","repetidor","familia_ninos","pareja","grupo","senior","movilidad_reducida","cultural","gastronomico","naturaleza","fotografia","otaku","compras","presupuesto_ajustado","premium"]}},"mobility":{"type":"string","enum":["normal","reducida"]},"avoid":{"type":"array","items":{"type":"string"}},"notes":{"type":"string"}},"additionalProperties":false},"metadata":{"type":"object","additionalProperties":{"anyOf":[{"type":"string","maxLength":500},{"type":"null"}]},"propertyNames":{"pattern":"^[A-Za-z0-9_.-]{1,40}$"}}},"required":["title"],"additionalProperties":false}}}}}},"/trips/archived":{"get":{"operationId":"trips.listArchived","summary":"List archived trips","description":"Lists the agency's archived trips, most recently archived first, in one page (the app's own archive list is not paginated either). Restore one with POST /trips/{tripId}/restore.\n\n**Permissions:** `trips:read`.","tags":["Trips"],"x-scopes":["trips:read"],"x-undo":"none","parameters":[],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"object":{"type":"string","const":"list"},"data":{"type":"array","items":{"type":"object","properties":{"object":{"type":"string","const":"archived_trip"},"id":{"type":"string","format":"uuid"},"code":{"type":"string"},"title":{"type":"string"},"startDate":{"type":["string","null"]},"endDate":{"type":["string","null"]},"archivedAt":{"type":"string"},"archivedBy":{"type":["string","null"]}},"required":["object","id","code","title","startDate","endDate","archivedAt","archivedBy"],"additionalProperties":false}},"nextCursor":{"type":["string","null"]}},"required":["object","data","nextCursor"],"additionalProperties":false}}}},"default":{"description":"Error (RFC 9457)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/trips/{tripId}":{"get":{"operationId":"trips.get","summary":"Get a trip","description":"Returns one trip with every field the app shows: dates, headcount, owner, design (the route), presentation overrides, the planner profile, commercial state, payment coverage and your metadata. Another agency's trip, and an archived one, is a 404.\n\n**Permissions:** `trips:read`.","tags":["Trips"],"x-scopes":["trips:read"],"x-undo":"none","parameters":[{"name":"tripId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"object":{"type":"string","const":"trip"},"id":{"type":"string","format":"uuid"},"code":{"type":"string"},"title":{"type":"string"},"startDate":{"type":["string","null"]},"endDate":{"type":["string","null"]},"publication":{"type":"string","enum":["draft","published"]},"commercialState":{"type":"string","enum":["nueva","propuesta_enviada","aceptada","reserva_provisional","reservada","rechazada","cancelada"]},"travelers":{"type":"integer"},"ownerId":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}]},"design":{"anyOf":[{"type":"object","properties":{"version":{"type":"number","const":1},"originCity":{"type":"string"},"stops":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"city":{"type":"string"},"nights":{"type":"integer","minimum":0,"maximum":365},"transferBefore":{"anyOf":[{"type":"object","properties":{"id":{"type":"string"},"departDate":{"type":["string","null"]},"arriveDate":{"type":["string","null"]},"days":{"type":"integer","minimum":0,"maximum":30,"default":0},"departTime":{"type":"string","default":""},"arriveTime":{"type":"string","default":""},"flight":{"type":"object","properties":{"flightNo":{"type":"string","default":""},"airline":{"type":"string","default":""},"fromAirport":{"type":"string","default":""},"toAirport":{"type":"string","default":""},"source":{"type":"string","default":""},"fetchedAt":{"type":"string","default":""},"scheduleValidFor":{"type":"string","default":""}},"additionalProperties":false,"default":{"flightNo":"","airline":"","fromAirport":"","toAirport":"","source":"","fetchedAt":"","scheduleValidFor":""}}},"required":["id","departDate","arriveDate"],"additionalProperties":false},{"type":"null"}]},"escala":{"type":"boolean","default":false},"place":{"type":"object","properties":{"placeId":{"type":"string","default":""},"lat":{"type":["number","null"],"default":null},"lng":{"type":["number","null"],"default":null},"formattedAddress":{"type":"string","default":""}},"additionalProperties":false,"default":{"placeId":"","lat":null,"lng":null,"formattedAddress":""}}},"required":["id","city","nights","transferBefore"],"additionalProperties":false},"maxItems":60},"returnCity":{"type":["string","null"]},"returnTransfer":{"anyOf":[{"type":"object","properties":{"id":{"type":"string"},"departDate":{"type":["string","null"]},"arriveDate":{"type":["string","null"]},"days":{"type":"integer","minimum":0,"maximum":30,"default":0},"departTime":{"type":"string","default":""},"arriveTime":{"type":"string","default":""},"flight":{"type":"object","properties":{"flightNo":{"type":"string","default":""},"airline":{"type":"string","default":""},"fromAirport":{"type":"string","default":""},"toAirport":{"type":"string","default":""},"source":{"type":"string","default":""},"fetchedAt":{"type":"string","default":""},"scheduleValidFor":{"type":"string","default":""}},"additionalProperties":false,"default":{"flightNo":"","airline":"","fromAirport":"","toAirport":"","source":"","fetchedAt":"","scheduleValidFor":""}}},"required":["id","departDate","arriveDate"],"additionalProperties":false},{"type":"null"}]},"originPlace":{"type":"object","properties":{"placeId":{"type":"string","default":""},"lat":{"type":["number","null"],"default":null},"lng":{"type":["number","null"],"default":null},"formattedAddress":{"type":"string","default":""}},"additionalProperties":false,"default":{"placeId":"","lat":null,"lng":null,"formattedAddress":""}},"returnPlace":{"type":"object","properties":{"placeId":{"type":"string","default":""},"lat":{"type":["number","null"],"default":null},"lng":{"type":["number","null"],"default":null},"formattedAddress":{"type":"string","default":""}},"additionalProperties":false,"default":{"placeId":"","lat":null,"lng":null,"formattedAddress":""}}},"required":["version","originCity","stops","returnCity","returnTransfer"],"additionalProperties":false},{"type":"null"}]},"presentation":{"type":"object","properties":{"logoUrl":{"anyOf":[{"type":"string","format":"uri"},{"type":"null"}]},"brandColor":{"anyOf":[{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},{"type":"null"}]},"fontFamily":{"anyOf":[{"type":"string","enum":["inter","montserrat","poppins","lora","playfair","source-sans"]},{"type":"null"}]},"headerMedia":{"anyOf":[{"type":"object","properties":{"type":{"type":"string","enum":["image","video"]},"url":{"type":"string","format":"uri"}},"required":["type","url"],"additionalProperties":false},{"type":"null"}]}},"additionalProperties":false},"profile":{"type":"object","properties":{"pace":{"anyOf":[{"type":"string","enum":["relajado","equilibrado","intenso"]},{"type":"null"}],"default":null},"profiles":{"type":"array","items":{"type":"string","enum":["primera_vez","repetidor","familia_ninos","pareja","grupo","senior","movilidad_reducida","cultural","gastronomico","naturaleza","fotografia","otaku","compras","presupuesto_ajustado","premium"]},"default":[]},"mobility":{"type":"string","enum":["normal","reducida"],"default":"normal"},"avoid":{"type":"array","items":{"type":"string"},"default":[]},"notes":{"type":"string","default":""}},"additionalProperties":false},"coverImageUrl":{"type":["string","null"]},"coverage":{"anyOf":[{"type":"object","properties":{"state":{"type":"string","enum":["sin_cobros","pago_parcial","pagado"]},"percent":{"type":"integer"},"overpaid":{"type":"boolean"}},"required":["state","percent","overpaid"],"additionalProperties":false},{"type":"null"}]},"metadata":{"type":"object","additionalProperties":{"type":"string","maxLength":500},"propertyNames":{"pattern":"^[A-Za-z0-9_.-]{1,40}$"}},"appUrl":{"type":["string","null"]},"publicUrl":{"type":["string","null"]},"createdAt":{"type":"string"},"updatedAt":{"type":"string"}},"required":["object","id","code","title","startDate","endDate","publication","commercialState","travelers","ownerId","design","presentation","profile","coverImageUrl","coverage","metadata","appUrl","publicUrl","createdAt","updatedAt"],"additionalProperties":false}}}},"default":{"description":"Error (RFC 9457)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"patch":{"operationId":"trips.update","summary":"Update a trip","description":"Changes any field an agent can edit in the app: title, startDate, endDate, travelers (1–40; refused while a quote is accepted), ownerId (an active staff member), design, presentation, profile, and metadata. An absent field is unchanged and `null` clears it. `presentation` and `profile` are replaced as a whole. `metadata` merges key by key, and `\"key\": null` deletes that key. Changing the dates re-dates the itinerary, as the app does. Changing `design` does not rebuild the itinerary's days: call POST /trips/{tripId}/itinerary/sync. With `?dryRun=true`, returns a `trip_change_preview` listing each field's from/to.\n\n**Permissions:** `trips:write`.\n\n**Undo:** the response carries `Bymundi-Change-Id`; `POST /changes/{changeId}/revert` undoes it.","tags":["Trips"],"x-scopes":["trips:write"],"x-undo":"change","parameters":[{"name":"tripId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"$ref":"#/components/parameters/DryRun"},{"$ref":"#/components/parameters/IdempotencyKey"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"anyOf":[{"type":"object","properties":{"object":{"type":"string","const":"trip"},"id":{"type":"string","format":"uuid"},"code":{"type":"string"},"title":{"type":"string"},"startDate":{"type":["string","null"]},"endDate":{"type":["string","null"]},"publication":{"type":"string","enum":["draft","published"]},"commercialState":{"type":"string","enum":["nueva","propuesta_enviada","aceptada","reserva_provisional","reservada","rechazada","cancelada"]},"travelers":{"type":"integer"},"ownerId":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}]},"design":{"anyOf":[{"type":"object","properties":{"version":{"type":"number","const":1},"originCity":{"type":"string"},"stops":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"city":{"type":"string"},"nights":{"type":"integer","minimum":0,"maximum":365},"transferBefore":{"anyOf":[{"type":"object","properties":{"id":{"type":"string"},"departDate":{"type":["string","null"]},"arriveDate":{"type":["string","null"]},"days":{"type":"integer","minimum":0,"maximum":30,"default":0},"departTime":{"type":"string","default":""},"arriveTime":{"type":"string","default":""},"flight":{"type":"object","properties":{"flightNo":{"type":"string","default":""},"airline":{"type":"string","default":""},"fromAirport":{"type":"string","default":""},"toAirport":{"type":"string","default":""},"source":{"type":"string","default":""},"fetchedAt":{"type":"string","default":""},"scheduleValidFor":{"type":"string","default":""}},"additionalProperties":false,"default":{"flightNo":"","airline":"","fromAirport":"","toAirport":"","source":"","fetchedAt":"","scheduleValidFor":""}}},"required":["id","departDate","arriveDate"],"additionalProperties":false},{"type":"null"}]},"escala":{"type":"boolean","default":false},"place":{"type":"object","properties":{"placeId":{"type":"string","default":""},"lat":{"type":["number","null"],"default":null},"lng":{"type":["number","null"],"default":null},"formattedAddress":{"type":"string","default":""}},"additionalProperties":false,"default":{"placeId":"","lat":null,"lng":null,"formattedAddress":""}}},"required":["id","city","nights","transferBefore"],"additionalProperties":false},"maxItems":60},"returnCity":{"type":["string","null"]},"returnTransfer":{"anyOf":[{"type":"object","properties":{"id":{"type":"string"},"departDate":{"type":["string","null"]},"arriveDate":{"type":["string","null"]},"days":{"type":"integer","minimum":0,"maximum":30,"default":0},"departTime":{"type":"string","default":""},"arriveTime":{"type":"string","default":""},"flight":{"type":"object","properties":{"flightNo":{"type":"string","default":""},"airline":{"type":"string","default":""},"fromAirport":{"type":"string","default":""},"toAirport":{"type":"string","default":""},"source":{"type":"string","default":""},"fetchedAt":{"type":"string","default":""},"scheduleValidFor":{"type":"string","default":""}},"additionalProperties":false,"default":{"flightNo":"","airline":"","fromAirport":"","toAirport":"","source":"","fetchedAt":"","scheduleValidFor":""}}},"required":["id","departDate","arriveDate"],"additionalProperties":false},{"type":"null"}]},"originPlace":{"type":"object","properties":{"placeId":{"type":"string","default":""},"lat":{"type":["number","null"],"default":null},"lng":{"type":["number","null"],"default":null},"formattedAddress":{"type":"string","default":""}},"additionalProperties":false,"default":{"placeId":"","lat":null,"lng":null,"formattedAddress":""}},"returnPlace":{"type":"object","properties":{"placeId":{"type":"string","default":""},"lat":{"type":["number","null"],"default":null},"lng":{"type":["number","null"],"default":null},"formattedAddress":{"type":"string","default":""}},"additionalProperties":false,"default":{"placeId":"","lat":null,"lng":null,"formattedAddress":""}}},"required":["version","originCity","stops","returnCity","returnTransfer"],"additionalProperties":false},{"type":"null"}]},"presentation":{"type":"object","properties":{"logoUrl":{"anyOf":[{"type":"string","format":"uri"},{"type":"null"}]},"brandColor":{"anyOf":[{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},{"type":"null"}]},"fontFamily":{"anyOf":[{"type":"string","enum":["inter","montserrat","poppins","lora","playfair","source-sans"]},{"type":"null"}]},"headerMedia":{"anyOf":[{"type":"object","properties":{"type":{"type":"string","enum":["image","video"]},"url":{"type":"string","format":"uri"}},"required":["type","url"],"additionalProperties":false},{"type":"null"}]}},"additionalProperties":false},"profile":{"type":"object","properties":{"pace":{"anyOf":[{"type":"string","enum":["relajado","equilibrado","intenso"]},{"type":"null"}],"default":null},"profiles":{"type":"array","items":{"type":"string","enum":["primera_vez","repetidor","familia_ninos","pareja","grupo","senior","movilidad_reducida","cultural","gastronomico","naturaleza","fotografia","otaku","compras","presupuesto_ajustado","premium"]},"default":[]},"mobility":{"type":"string","enum":["normal","reducida"],"default":"normal"},"avoid":{"type":"array","items":{"type":"string"},"default":[]},"notes":{"type":"string","default":""}},"additionalProperties":false},"coverImageUrl":{"type":["string","null"]},"coverage":{"anyOf":[{"type":"object","properties":{"state":{"type":"string","enum":["sin_cobros","pago_parcial","pagado"]},"percent":{"type":"integer"},"overpaid":{"type":"boolean"}},"required":["state","percent","overpaid"],"additionalProperties":false},{"type":"null"}]},"metadata":{"type":"object","additionalProperties":{"type":"string","maxLength":500},"propertyNames":{"pattern":"^[A-Za-z0-9_.-]{1,40}$"}},"appUrl":{"type":["string","null"]},"publicUrl":{"type":["string","null"]},"createdAt":{"type":"string"},"updatedAt":{"type":"string"}},"required":["object","id","code","title","startDate","endDate","publication","commercialState","travelers","ownerId","design","presentation","profile","coverImageUrl","coverage","metadata","appUrl","publicUrl","createdAt","updatedAt"],"additionalProperties":false},{"type":"object","properties":{"object":{"type":"string","const":"trip_change_preview"},"tripId":{"type":"string","format":"uuid"},"changes":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"from":{},"to":{}},"required":["field"],"additionalProperties":false}}},"required":["object","tripId","changes"],"additionalProperties":false}]}}}},"default":{"description":"Error (RFC 9457)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"title":{"type":"string","minLength":1},"startDate":{"anyOf":[{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$"},{"type":"null"}]},"endDate":{"anyOf":[{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$"},{"type":"null"}]},"travelers":{"type":"integer","minimum":1,"maximum":40},"ownerId":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}]},"design":{"anyOf":[{"type":"object","properties":{"version":{"type":"number","const":1},"originCity":{"type":"string"},"stops":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"city":{"type":"string"},"nights":{"type":"integer","minimum":0,"maximum":365},"transferBefore":{"anyOf":[{"type":"object","properties":{"id":{"type":"string"},"departDate":{"type":["string","null"]},"arriveDate":{"type":["string","null"]},"days":{"type":"integer","minimum":0,"maximum":30,"default":0},"departTime":{"type":"string","default":""},"arriveTime":{"type":"string","default":""},"flight":{"type":"object","properties":{"flightNo":{"type":"string","default":""},"airline":{"type":"string","default":""},"fromAirport":{"type":"string","default":""},"toAirport":{"type":"string","default":""},"source":{"type":"string","default":""},"fetchedAt":{"type":"string","default":""},"scheduleValidFor":{"type":"string","default":""}},"additionalProperties":false,"default":{"flightNo":"","airline":"","fromAirport":"","toAirport":"","source":"","fetchedAt":"","scheduleValidFor":""}}},"required":["id","departDate","arriveDate"],"additionalProperties":false},{"type":"null"}]},"escala":{"type":"boolean","default":false},"place":{"type":"object","properties":{"placeId":{"type":"string","default":""},"lat":{"type":["number","null"],"default":null},"lng":{"type":["number","null"],"default":null},"formattedAddress":{"type":"string","default":""}},"additionalProperties":false,"default":{"placeId":"","lat":null,"lng":null,"formattedAddress":""}}},"required":["id","city","nights","transferBefore"],"additionalProperties":false},"maxItems":60},"returnCity":{"type":["string","null"]},"returnTransfer":{"anyOf":[{"type":"object","properties":{"id":{"type":"string"},"departDate":{"type":["string","null"]},"arriveDate":{"type":["string","null"]},"days":{"type":"integer","minimum":0,"maximum":30,"default":0},"departTime":{"type":"string","default":""},"arriveTime":{"type":"string","default":""},"flight":{"type":"object","properties":{"flightNo":{"type":"string","default":""},"airline":{"type":"string","default":""},"fromAirport":{"type":"string","default":""},"toAirport":{"type":"string","default":""},"source":{"type":"string","default":""},"fetchedAt":{"type":"string","default":""},"scheduleValidFor":{"type":"string","default":""}},"additionalProperties":false,"default":{"flightNo":"","airline":"","fromAirport":"","toAirport":"","source":"","fetchedAt":"","scheduleValidFor":""}}},"required":["id","departDate","arriveDate"],"additionalProperties":false},{"type":"null"}]},"originPlace":{"type":"object","properties":{"placeId":{"type":"string","default":""},"lat":{"type":["number","null"],"default":null},"lng":{"type":["number","null"],"default":null},"formattedAddress":{"type":"string","default":""}},"additionalProperties":false,"default":{"placeId":"","lat":null,"lng":null,"formattedAddress":""}},"returnPlace":{"type":"object","properties":{"placeId":{"type":"string","default":""},"lat":{"type":["number","null"],"default":null},"lng":{"type":["number","null"],"default":null},"formattedAddress":{"type":"string","default":""}},"additionalProperties":false,"default":{"placeId":"","lat":null,"lng":null,"formattedAddress":""}}},"required":["version","originCity","stops","returnCity","returnTransfer"],"additionalProperties":false},{"type":"null"}]},"presentation":{"anyOf":[{"type":"object","properties":{"logoUrl":{"anyOf":[{"type":"string","format":"uri"},{"type":"null"}]},"brandColor":{"anyOf":[{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},{"type":"null"}]},"fontFamily":{"anyOf":[{"type":"string","enum":["inter","montserrat","poppins","lora","playfair","source-sans"]},{"type":"null"}]},"headerMedia":{"anyOf":[{"type":"object","properties":{"type":{"type":"string","enum":["image","video"]},"url":{"type":"string","format":"uri"}},"required":["type","url"],"additionalProperties":false},{"type":"null"}]}},"additionalProperties":false},{"type":"null"}]},"profile":{"anyOf":[{"type":"object","properties":{"pace":{"anyOf":[{"type":"string","enum":["relajado","equilibrado","intenso"]},{"type":"null"}]},"profiles":{"type":"array","items":{"type":"string","enum":["primera_vez","repetidor","familia_ninos","pareja","grupo","senior","movilidad_reducida","cultural","gastronomico","naturaleza","fotografia","otaku","compras","presupuesto_ajustado","premium"]}},"mobility":{"type":"string","enum":["normal","reducida"]},"avoid":{"type":"array","items":{"type":"string"}},"notes":{"type":"string"}},"additionalProperties":false},{"type":"null"}]},"metadata":{"type":"object","additionalProperties":{"anyOf":[{"type":"string","maxLength":500},{"type":"null"}]},"propertyNames":{"pattern":"^[A-Za-z0-9_.-]{1,40}$"}}},"required":[],"additionalProperties":false}}}}},"delete":{"operationId":"trips.archive","summary":"Archive a trip","description":"Archives (soft-deletes) a trip, as Archive does in the app, subject to your trip-deletion permission (none / own trips / the agency's). The trip leaves every list and read. Undo with POST /changes/{changeId}/revert, or restore it with POST /trips/{tripId}/restore.\n\n**Permissions:** `trips:write`.\n\n**Undo:** the response carries `Bymundi-Change-Id`; `POST /changes/{changeId}/revert` undoes it.","tags":["Trips"],"x-scopes":["trips:write"],"x-undo":"change","parameters":[{"name":"tripId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"$ref":"#/components/parameters/IdempotencyKey"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"object":{"type":"string","const":"archived_trip"},"id":{"type":"string","format":"uuid"},"code":{"type":"string"},"title":{"type":"string"},"startDate":{"type":["string","null"]},"endDate":{"type":["string","null"]},"archivedAt":{"type":"string"},"archivedBy":{"type":["string","null"]}},"required":["object","id","code","title","startDate","endDate","archivedAt","archivedBy"],"additionalProperties":false}}}},"default":{"description":"Error (RFC 9457)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/trips/{tripId}/restore":{"post":{"operationId":"trips.restore","summary":"Restore an archived trip","description":"Brings an archived trip back, as Restore does in the app, subject to your trip-deletion permission. A trip that is not archived is a 409; one your permission does not cover is a 403.\n\n**Permissions:** `trips:write`.\n\n**Undo:** call `trips.archive`.","tags":["Trips"],"x-scopes":["trips:write"],"x-undo":{"restore":"trips.archive"},"parameters":[{"name":"tripId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"$ref":"#/components/parameters/IdempotencyKey"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"object":{"type":"string","const":"trip"},"id":{"type":"string","format":"uuid"},"code":{"type":"string"},"title":{"type":"string"},"startDate":{"type":["string","null"]},"endDate":{"type":["string","null"]},"publication":{"type":"string","enum":["draft","published"]},"commercialState":{"type":"string","enum":["nueva","propuesta_enviada","aceptada","reserva_provisional","reservada","rechazada","cancelada"]},"travelers":{"type":"integer"},"ownerId":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}]},"design":{"anyOf":[{"type":"object","properties":{"version":{"type":"number","const":1},"originCity":{"type":"string"},"stops":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"city":{"type":"string"},"nights":{"type":"integer","minimum":0,"maximum":365},"transferBefore":{"anyOf":[{"type":"object","properties":{"id":{"type":"string"},"departDate":{"type":["string","null"]},"arriveDate":{"type":["string","null"]},"days":{"type":"integer","minimum":0,"maximum":30,"default":0},"departTime":{"type":"string","default":""},"arriveTime":{"type":"string","default":""},"flight":{"type":"object","properties":{"flightNo":{"type":"string","default":""},"airline":{"type":"string","default":""},"fromAirport":{"type":"string","default":""},"toAirport":{"type":"string","default":""},"source":{"type":"string","default":""},"fetchedAt":{"type":"string","default":""},"scheduleValidFor":{"type":"string","default":""}},"additionalProperties":false,"default":{"flightNo":"","airline":"","fromAirport":"","toAirport":"","source":"","fetchedAt":"","scheduleValidFor":""}}},"required":["id","departDate","arriveDate"],"additionalProperties":false},{"type":"null"}]},"escala":{"type":"boolean","default":false},"place":{"type":"object","properties":{"placeId":{"type":"string","default":""},"lat":{"type":["number","null"],"default":null},"lng":{"type":["number","null"],"default":null},"formattedAddress":{"type":"string","default":""}},"additionalProperties":false,"default":{"placeId":"","lat":null,"lng":null,"formattedAddress":""}}},"required":["id","city","nights","transferBefore"],"additionalProperties":false},"maxItems":60},"returnCity":{"type":["string","null"]},"returnTransfer":{"anyOf":[{"type":"object","properties":{"id":{"type":"string"},"departDate":{"type":["string","null"]},"arriveDate":{"type":["string","null"]},"days":{"type":"integer","minimum":0,"maximum":30,"default":0},"departTime":{"type":"string","default":""},"arriveTime":{"type":"string","default":""},"flight":{"type":"object","properties":{"flightNo":{"type":"string","default":""},"airline":{"type":"string","default":""},"fromAirport":{"type":"string","default":""},"toAirport":{"type":"string","default":""},"source":{"type":"string","default":""},"fetchedAt":{"type":"string","default":""},"scheduleValidFor":{"type":"string","default":""}},"additionalProperties":false,"default":{"flightNo":"","airline":"","fromAirport":"","toAirport":"","source":"","fetchedAt":"","scheduleValidFor":""}}},"required":["id","departDate","arriveDate"],"additionalProperties":false},{"type":"null"}]},"originPlace":{"type":"object","properties":{"placeId":{"type":"string","default":""},"lat":{"type":["number","null"],"default":null},"lng":{"type":["number","null"],"default":null},"formattedAddress":{"type":"string","default":""}},"additionalProperties":false,"default":{"placeId":"","lat":null,"lng":null,"formattedAddress":""}},"returnPlace":{"type":"object","properties":{"placeId":{"type":"string","default":""},"lat":{"type":["number","null"],"default":null},"lng":{"type":["number","null"],"default":null},"formattedAddress":{"type":"string","default":""}},"additionalProperties":false,"default":{"placeId":"","lat":null,"lng":null,"formattedAddress":""}}},"required":["version","originCity","stops","returnCity","returnTransfer"],"additionalProperties":false},{"type":"null"}]},"presentation":{"type":"object","properties":{"logoUrl":{"anyOf":[{"type":"string","format":"uri"},{"type":"null"}]},"brandColor":{"anyOf":[{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},{"type":"null"}]},"fontFamily":{"anyOf":[{"type":"string","enum":["inter","montserrat","poppins","lora","playfair","source-sans"]},{"type":"null"}]},"headerMedia":{"anyOf":[{"type":"object","properties":{"type":{"type":"string","enum":["image","video"]},"url":{"type":"string","format":"uri"}},"required":["type","url"],"additionalProperties":false},{"type":"null"}]}},"additionalProperties":false},"profile":{"type":"object","properties":{"pace":{"anyOf":[{"type":"string","enum":["relajado","equilibrado","intenso"]},{"type":"null"}],"default":null},"profiles":{"type":"array","items":{"type":"string","enum":["primera_vez","repetidor","familia_ninos","pareja","grupo","senior","movilidad_reducida","cultural","gastronomico","naturaleza","fotografia","otaku","compras","presupuesto_ajustado","premium"]},"default":[]},"mobility":{"type":"string","enum":["normal","reducida"],"default":"normal"},"avoid":{"type":"array","items":{"type":"string"},"default":[]},"notes":{"type":"string","default":""}},"additionalProperties":false},"coverImageUrl":{"type":["string","null"]},"coverage":{"anyOf":[{"type":"object","properties":{"state":{"type":"string","enum":["sin_cobros","pago_parcial","pagado"]},"percent":{"type":"integer"},"overpaid":{"type":"boolean"}},"required":["state","percent","overpaid"],"additionalProperties":false},{"type":"null"}]},"metadata":{"type":"object","additionalProperties":{"type":"string","maxLength":500},"propertyNames":{"pattern":"^[A-Za-z0-9_.-]{1,40}$"}},"appUrl":{"type":["string","null"]},"publicUrl":{"type":["string","null"]},"createdAt":{"type":"string"},"updatedAt":{"type":"string"}},"required":["object","id","code","title","startDate","endDate","publication","commercialState","travelers","ownerId","design","presentation","profile","coverImageUrl","coverage","metadata","appUrl","publicUrl","createdAt","updatedAt"],"additionalProperties":false}}}},"default":{"description":"Error (RFC 9457)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{},"required":[],"additionalProperties":false}}}}}},"/trips/{tripId}/duplicate":{"post":{"operationId":"trips.duplicate","summary":"Duplicate a trip","description":"Copies a trip as `Copia de …`, in draft, as the app's Duplicate does. The copy keeps the design, dates, headcount, cover and itinerary blocks. It does not copy travellers, quotes, documents, chat or presentation. Only a trip with a design (route) can be duplicated. Undo by archiving the copy.\n\n**Permissions:** `trips:write`.\n\n**Undo:** call `trips.archive`.","tags":["Trips"],"x-scopes":["trips:write"],"x-undo":{"restore":"trips.archive"},"parameters":[{"name":"tripId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"$ref":"#/components/parameters/IdempotencyKey"}],"responses":{"201":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"object":{"type":"string","const":"trip"},"id":{"type":"string","format":"uuid"},"code":{"type":"string"},"title":{"type":"string"},"startDate":{"type":["string","null"]},"endDate":{"type":["string","null"]},"publication":{"type":"string","enum":["draft","published"]},"commercialState":{"type":"string","enum":["nueva","propuesta_enviada","aceptada","reserva_provisional","reservada","rechazada","cancelada"]},"travelers":{"type":"integer"},"ownerId":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}]},"design":{"anyOf":[{"type":"object","properties":{"version":{"type":"number","const":1},"originCity":{"type":"string"},"stops":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"city":{"type":"string"},"nights":{"type":"integer","minimum":0,"maximum":365},"transferBefore":{"anyOf":[{"type":"object","properties":{"id":{"type":"string"},"departDate":{"type":["string","null"]},"arriveDate":{"type":["string","null"]},"days":{"type":"integer","minimum":0,"maximum":30,"default":0},"departTime":{"type":"string","default":""},"arriveTime":{"type":"string","default":""},"flight":{"type":"object","properties":{"flightNo":{"type":"string","default":""},"airline":{"type":"string","default":""},"fromAirport":{"type":"string","default":""},"toAirport":{"type":"string","default":""},"source":{"type":"string","default":""},"fetchedAt":{"type":"string","default":""},"scheduleValidFor":{"type":"string","default":""}},"additionalProperties":false,"default":{"flightNo":"","airline":"","fromAirport":"","toAirport":"","source":"","fetchedAt":"","scheduleValidFor":""}}},"required":["id","departDate","arriveDate"],"additionalProperties":false},{"type":"null"}]},"escala":{"type":"boolean","default":false},"place":{"type":"object","properties":{"placeId":{"type":"string","default":""},"lat":{"type":["number","null"],"default":null},"lng":{"type":["number","null"],"default":null},"formattedAddress":{"type":"string","default":""}},"additionalProperties":false,"default":{"placeId":"","lat":null,"lng":null,"formattedAddress":""}}},"required":["id","city","nights","transferBefore"],"additionalProperties":false},"maxItems":60},"returnCity":{"type":["string","null"]},"returnTransfer":{"anyOf":[{"type":"object","properties":{"id":{"type":"string"},"departDate":{"type":["string","null"]},"arriveDate":{"type":["string","null"]},"days":{"type":"integer","minimum":0,"maximum":30,"default":0},"departTime":{"type":"string","default":""},"arriveTime":{"type":"string","default":""},"flight":{"type":"object","properties":{"flightNo":{"type":"string","default":""},"airline":{"type":"string","default":""},"fromAirport":{"type":"string","default":""},"toAirport":{"type":"string","default":""},"source":{"type":"string","default":""},"fetchedAt":{"type":"string","default":""},"scheduleValidFor":{"type":"string","default":""}},"additionalProperties":false,"default":{"flightNo":"","airline":"","fromAirport":"","toAirport":"","source":"","fetchedAt":"","scheduleValidFor":""}}},"required":["id","departDate","arriveDate"],"additionalProperties":false},{"type":"null"}]},"originPlace":{"type":"object","properties":{"placeId":{"type":"string","default":""},"lat":{"type":["number","null"],"default":null},"lng":{"type":["number","null"],"default":null},"formattedAddress":{"type":"string","default":""}},"additionalProperties":false,"default":{"placeId":"","lat":null,"lng":null,"formattedAddress":""}},"returnPlace":{"type":"object","properties":{"placeId":{"type":"string","default":""},"lat":{"type":["number","null"],"default":null},"lng":{"type":["number","null"],"default":null},"formattedAddress":{"type":"string","default":""}},"additionalProperties":false,"default":{"placeId":"","lat":null,"lng":null,"formattedAddress":""}}},"required":["version","originCity","stops","returnCity","returnTransfer"],"additionalProperties":false},{"type":"null"}]},"presentation":{"type":"object","properties":{"logoUrl":{"anyOf":[{"type":"string","format":"uri"},{"type":"null"}]},"brandColor":{"anyOf":[{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},{"type":"null"}]},"fontFamily":{"anyOf":[{"type":"string","enum":["inter","montserrat","poppins","lora","playfair","source-sans"]},{"type":"null"}]},"headerMedia":{"anyOf":[{"type":"object","properties":{"type":{"type":"string","enum":["image","video"]},"url":{"type":"string","format":"uri"}},"required":["type","url"],"additionalProperties":false},{"type":"null"}]}},"additionalProperties":false},"profile":{"type":"object","properties":{"pace":{"anyOf":[{"type":"string","enum":["relajado","equilibrado","intenso"]},{"type":"null"}],"default":null},"profiles":{"type":"array","items":{"type":"string","enum":["primera_vez","repetidor","familia_ninos","pareja","grupo","senior","movilidad_reducida","cultural","gastronomico","naturaleza","fotografia","otaku","compras","presupuesto_ajustado","premium"]},"default":[]},"mobility":{"type":"string","enum":["normal","reducida"],"default":"normal"},"avoid":{"type":"array","items":{"type":"string"},"default":[]},"notes":{"type":"string","default":""}},"additionalProperties":false},"coverImageUrl":{"type":["string","null"]},"coverage":{"anyOf":[{"type":"object","properties":{"state":{"type":"string","enum":["sin_cobros","pago_parcial","pagado"]},"percent":{"type":"integer"},"overpaid":{"type":"boolean"}},"required":["state","percent","overpaid"],"additionalProperties":false},{"type":"null"}]},"metadata":{"type":"object","additionalProperties":{"type":"string","maxLength":500},"propertyNames":{"pattern":"^[A-Za-z0-9_.-]{1,40}$"}},"appUrl":{"type":["string","null"]},"publicUrl":{"type":["string","null"]},"createdAt":{"type":"string"},"updatedAt":{"type":"string"}},"required":["object","id","code","title","startDate","endDate","publication","commercialState","travelers","ownerId","design","presentation","profile","coverImageUrl","coverage","metadata","appUrl","publicUrl","createdAt","updatedAt"],"additionalProperties":false}}}},"default":{"description":"Error (RFC 9457)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{},"required":[],"additionalProperties":false}}}}}},"/trips/{tripId}/publish":{"post":{"operationId":"trips.publish","summary":"Publish a trip","description":"Publishes the trip so its public link (`publicUrl`) and the traveler's app show it. First, blocks sitting loose at the itinerary's root are moved into a section, as the app does. `adoptedBlocks` says how many moved; if it is above 0, re-read the itinerary. Undo with POST /trips/{tripId}/unpublish.\n\n**Permissions:** `trips:write`.\n\n**Undo:** call `trips.unpublish`.","tags":["Trips"],"x-scopes":["trips:write"],"x-undo":{"restore":"trips.unpublish"},"parameters":[{"name":"tripId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"$ref":"#/components/parameters/IdempotencyKey"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"object":{"type":"string","const":"trip"},"id":{"type":"string","format":"uuid"},"code":{"type":"string"},"title":{"type":"string"},"startDate":{"type":["string","null"]},"endDate":{"type":["string","null"]},"publication":{"type":"string","enum":["draft","published"]},"commercialState":{"type":"string","enum":["nueva","propuesta_enviada","aceptada","reserva_provisional","reservada","rechazada","cancelada"]},"travelers":{"type":"integer"},"ownerId":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}]},"design":{"anyOf":[{"type":"object","properties":{"version":{"type":"number","const":1},"originCity":{"type":"string"},"stops":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"city":{"type":"string"},"nights":{"type":"integer","minimum":0,"maximum":365},"transferBefore":{"anyOf":[{"type":"object","properties":{"id":{"type":"string"},"departDate":{"type":["string","null"]},"arriveDate":{"type":["string","null"]},"days":{"type":"integer","minimum":0,"maximum":30,"default":0},"departTime":{"type":"string","default":""},"arriveTime":{"type":"string","default":""},"flight":{"type":"object","properties":{"flightNo":{"type":"string","default":""},"airline":{"type":"string","default":""},"fromAirport":{"type":"string","default":""},"toAirport":{"type":"string","default":""},"source":{"type":"string","default":""},"fetchedAt":{"type":"string","default":""},"scheduleValidFor":{"type":"string","default":""}},"additionalProperties":false,"default":{"flightNo":"","airline":"","fromAirport":"","toAirport":"","source":"","fetchedAt":"","scheduleValidFor":""}}},"required":["id","departDate","arriveDate"],"additionalProperties":false},{"type":"null"}]},"escala":{"type":"boolean","default":false},"place":{"type":"object","properties":{"placeId":{"type":"string","default":""},"lat":{"type":["number","null"],"default":null},"lng":{"type":["number","null"],"default":null},"formattedAddress":{"type":"string","default":""}},"additionalProperties":false,"default":{"placeId":"","lat":null,"lng":null,"formattedAddress":""}}},"required":["id","city","nights","transferBefore"],"additionalProperties":false},"maxItems":60},"returnCity":{"type":["string","null"]},"returnTransfer":{"anyOf":[{"type":"object","properties":{"id":{"type":"string"},"departDate":{"type":["string","null"]},"arriveDate":{"type":["string","null"]},"days":{"type":"integer","minimum":0,"maximum":30,"default":0},"departTime":{"type":"string","default":""},"arriveTime":{"type":"string","default":""},"flight":{"type":"object","properties":{"flightNo":{"type":"string","default":""},"airline":{"type":"string","default":""},"fromAirport":{"type":"string","default":""},"toAirport":{"type":"string","default":""},"source":{"type":"string","default":""},"fetchedAt":{"type":"string","default":""},"scheduleValidFor":{"type":"string","default":""}},"additionalProperties":false,"default":{"flightNo":"","airline":"","fromAirport":"","toAirport":"","source":"","fetchedAt":"","scheduleValidFor":""}}},"required":["id","departDate","arriveDate"],"additionalProperties":false},{"type":"null"}]},"originPlace":{"type":"object","properties":{"placeId":{"type":"string","default":""},"lat":{"type":["number","null"],"default":null},"lng":{"type":["number","null"],"default":null},"formattedAddress":{"type":"string","default":""}},"additionalProperties":false,"default":{"placeId":"","lat":null,"lng":null,"formattedAddress":""}},"returnPlace":{"type":"object","properties":{"placeId":{"type":"string","default":""},"lat":{"type":["number","null"],"default":null},"lng":{"type":["number","null"],"default":null},"formattedAddress":{"type":"string","default":""}},"additionalProperties":false,"default":{"placeId":"","lat":null,"lng":null,"formattedAddress":""}}},"required":["version","originCity","stops","returnCity","returnTransfer"],"additionalProperties":false},{"type":"null"}]},"presentation":{"type":"object","properties":{"logoUrl":{"anyOf":[{"type":"string","format":"uri"},{"type":"null"}]},"brandColor":{"anyOf":[{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},{"type":"null"}]},"fontFamily":{"anyOf":[{"type":"string","enum":["inter","montserrat","poppins","lora","playfair","source-sans"]},{"type":"null"}]},"headerMedia":{"anyOf":[{"type":"object","properties":{"type":{"type":"string","enum":["image","video"]},"url":{"type":"string","format":"uri"}},"required":["type","url"],"additionalProperties":false},{"type":"null"}]}},"additionalProperties":false},"profile":{"type":"object","properties":{"pace":{"anyOf":[{"type":"string","enum":["relajado","equilibrado","intenso"]},{"type":"null"}],"default":null},"profiles":{"type":"array","items":{"type":"string","enum":["primera_vez","repetidor","familia_ninos","pareja","grupo","senior","movilidad_reducida","cultural","gastronomico","naturaleza","fotografia","otaku","compras","presupuesto_ajustado","premium"]},"default":[]},"mobility":{"type":"string","enum":["normal","reducida"],"default":"normal"},"avoid":{"type":"array","items":{"type":"string"},"default":[]},"notes":{"type":"string","default":""}},"additionalProperties":false},"coverImageUrl":{"type":["string","null"]},"coverage":{"anyOf":[{"type":"object","properties":{"state":{"type":"string","enum":["sin_cobros","pago_parcial","pagado"]},"percent":{"type":"integer"},"overpaid":{"type":"boolean"}},"required":["state","percent","overpaid"],"additionalProperties":false},{"type":"null"}]},"metadata":{"type":"object","additionalProperties":{"type":"string","maxLength":500},"propertyNames":{"pattern":"^[A-Za-z0-9_.-]{1,40}$"}},"appUrl":{"type":["string","null"]},"publicUrl":{"type":["string","null"]},"createdAt":{"type":"string"},"updatedAt":{"type":"string"},"adoptedBlocks":{"type":"integer"}},"required":["object","id","code","title","startDate","endDate","publication","commercialState","travelers","ownerId","design","presentation","profile","coverImageUrl","coverage","metadata","appUrl","publicUrl","createdAt","updatedAt","adoptedBlocks"],"additionalProperties":false}}}},"default":{"description":"Error (RFC 9457)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{},"required":[],"additionalProperties":false}}}}}},"/trips/{tripId}/unpublish":{"post":{"operationId":"trips.unpublish","summary":"Unpublish a trip","description":"Returns the trip to draft: its public link and the traveler's app stop showing it. Undo with POST /trips/{tripId}/publish.\n\n**Permissions:** `trips:write`.\n\n**Undo:** call `trips.publish`.","tags":["Trips"],"x-scopes":["trips:write"],"x-undo":{"restore":"trips.publish"},"parameters":[{"name":"tripId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"$ref":"#/components/parameters/IdempotencyKey"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"object":{"type":"string","const":"trip"},"id":{"type":"string","format":"uuid"},"code":{"type":"string"},"title":{"type":"string"},"startDate":{"type":["string","null"]},"endDate":{"type":["string","null"]},"publication":{"type":"string","enum":["draft","published"]},"commercialState":{"type":"string","enum":["nueva","propuesta_enviada","aceptada","reserva_provisional","reservada","rechazada","cancelada"]},"travelers":{"type":"integer"},"ownerId":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}]},"design":{"anyOf":[{"type":"object","properties":{"version":{"type":"number","const":1},"originCity":{"type":"string"},"stops":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"city":{"type":"string"},"nights":{"type":"integer","minimum":0,"maximum":365},"transferBefore":{"anyOf":[{"type":"object","properties":{"id":{"type":"string"},"departDate":{"type":["string","null"]},"arriveDate":{"type":["string","null"]},"days":{"type":"integer","minimum":0,"maximum":30,"default":0},"departTime":{"type":"string","default":""},"arriveTime":{"type":"string","default":""},"flight":{"type":"object","properties":{"flightNo":{"type":"string","default":""},"airline":{"type":"string","default":""},"fromAirport":{"type":"string","default":""},"toAirport":{"type":"string","default":""},"source":{"type":"string","default":""},"fetchedAt":{"type":"string","default":""},"scheduleValidFor":{"type":"string","default":""}},"additionalProperties":false,"default":{"flightNo":"","airline":"","fromAirport":"","toAirport":"","source":"","fetchedAt":"","scheduleValidFor":""}}},"required":["id","departDate","arriveDate"],"additionalProperties":false},{"type":"null"}]},"escala":{"type":"boolean","default":false},"place":{"type":"object","properties":{"placeId":{"type":"string","default":""},"lat":{"type":["number","null"],"default":null},"lng":{"type":["number","null"],"default":null},"formattedAddress":{"type":"string","default":""}},"additionalProperties":false,"default":{"placeId":"","lat":null,"lng":null,"formattedAddress":""}}},"required":["id","city","nights","transferBefore"],"additionalProperties":false},"maxItems":60},"returnCity":{"type":["string","null"]},"returnTransfer":{"anyOf":[{"type":"object","properties":{"id":{"type":"string"},"departDate":{"type":["string","null"]},"arriveDate":{"type":["string","null"]},"days":{"type":"integer","minimum":0,"maximum":30,"default":0},"departTime":{"type":"string","default":""},"arriveTime":{"type":"string","default":""},"flight":{"type":"object","properties":{"flightNo":{"type":"string","default":""},"airline":{"type":"string","default":""},"fromAirport":{"type":"string","default":""},"toAirport":{"type":"string","default":""},"source":{"type":"string","default":""},"fetchedAt":{"type":"string","default":""},"scheduleValidFor":{"type":"string","default":""}},"additionalProperties":false,"default":{"flightNo":"","airline":"","fromAirport":"","toAirport":"","source":"","fetchedAt":"","scheduleValidFor":""}}},"required":["id","departDate","arriveDate"],"additionalProperties":false},{"type":"null"}]},"originPlace":{"type":"object","properties":{"placeId":{"type":"string","default":""},"lat":{"type":["number","null"],"default":null},"lng":{"type":["number","null"],"default":null},"formattedAddress":{"type":"string","default":""}},"additionalProperties":false,"default":{"placeId":"","lat":null,"lng":null,"formattedAddress":""}},"returnPlace":{"type":"object","properties":{"placeId":{"type":"string","default":""},"lat":{"type":["number","null"],"default":null},"lng":{"type":["number","null"],"default":null},"formattedAddress":{"type":"string","default":""}},"additionalProperties":false,"default":{"placeId":"","lat":null,"lng":null,"formattedAddress":""}}},"required":["version","originCity","stops","returnCity","returnTransfer"],"additionalProperties":false},{"type":"null"}]},"presentation":{"type":"object","properties":{"logoUrl":{"anyOf":[{"type":"string","format":"uri"},{"type":"null"}]},"brandColor":{"anyOf":[{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},{"type":"null"}]},"fontFamily":{"anyOf":[{"type":"string","enum":["inter","montserrat","poppins","lora","playfair","source-sans"]},{"type":"null"}]},"headerMedia":{"anyOf":[{"type":"object","properties":{"type":{"type":"string","enum":["image","video"]},"url":{"type":"string","format":"uri"}},"required":["type","url"],"additionalProperties":false},{"type":"null"}]}},"additionalProperties":false},"profile":{"type":"object","properties":{"pace":{"anyOf":[{"type":"string","enum":["relajado","equilibrado","intenso"]},{"type":"null"}],"default":null},"profiles":{"type":"array","items":{"type":"string","enum":["primera_vez","repetidor","familia_ninos","pareja","grupo","senior","movilidad_reducida","cultural","gastronomico","naturaleza","fotografia","otaku","compras","presupuesto_ajustado","premium"]},"default":[]},"mobility":{"type":"string","enum":["normal","reducida"],"default":"normal"},"avoid":{"type":"array","items":{"type":"string"},"default":[]},"notes":{"type":"string","default":""}},"additionalProperties":false},"coverImageUrl":{"type":["string","null"]},"coverage":{"anyOf":[{"type":"object","properties":{"state":{"type":"string","enum":["sin_cobros","pago_parcial","pagado"]},"percent":{"type":"integer"},"overpaid":{"type":"boolean"}},"required":["state","percent","overpaid"],"additionalProperties":false},{"type":"null"}]},"metadata":{"type":"object","additionalProperties":{"type":"string","maxLength":500},"propertyNames":{"pattern":"^[A-Za-z0-9_.-]{1,40}$"}},"appUrl":{"type":["string","null"]},"publicUrl":{"type":["string","null"]},"createdAt":{"type":"string"},"updatedAt":{"type":"string"}},"required":["object","id","code","title","startDate","endDate","publication","commercialState","travelers","ownerId","design","presentation","profile","coverImageUrl","coverage","metadata","appUrl","publicUrl","createdAt","updatedAt"],"additionalProperties":false}}}},"default":{"description":"Error (RFC 9457)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{},"required":[],"additionalProperties":false}}}}}},"/trips/{tripId}/commercial-state":{"post":{"operationId":"trips.setCommercialState","summary":"Set a trip's commercial state","description":"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.\n\n**Permissions:** `trips:write`.","tags":["Trips"],"x-scopes":["trips:write"],"x-undo":"none","parameters":[{"name":"tripId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"$ref":"#/components/parameters/IdempotencyKey"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"object":{"type":"string","const":"trip"},"id":{"type":"string","format":"uuid"},"code":{"type":"string"},"title":{"type":"string"},"startDate":{"type":["string","null"]},"endDate":{"type":["string","null"]},"publication":{"type":"string","enum":["draft","published"]},"commercialState":{"type":"string","enum":["nueva","propuesta_enviada","aceptada","reserva_provisional","reservada","rechazada","cancelada"]},"travelers":{"type":"integer"},"ownerId":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}]},"design":{"anyOf":[{"type":"object","properties":{"version":{"type":"number","const":1},"originCity":{"type":"string"},"stops":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"city":{"type":"string"},"nights":{"type":"integer","minimum":0,"maximum":365},"transferBefore":{"anyOf":[{"type":"object","properties":{"id":{"type":"string"},"departDate":{"type":["string","null"]},"arriveDate":{"type":["string","null"]},"days":{"type":"integer","minimum":0,"maximum":30,"default":0},"departTime":{"type":"string","default":""},"arriveTime":{"type":"string","default":""},"flight":{"type":"object","properties":{"flightNo":{"type":"string","default":""},"airline":{"type":"string","default":""},"fromAirport":{"type":"string","default":""},"toAirport":{"type":"string","default":""},"source":{"type":"string","default":""},"fetchedAt":{"type":"string","default":""},"scheduleValidFor":{"type":"string","default":""}},"additionalProperties":false,"default":{"flightNo":"","airline":"","fromAirport":"","toAirport":"","source":"","fetchedAt":"","scheduleValidFor":""}}},"required":["id","departDate","arriveDate"],"additionalProperties":false},{"type":"null"}]},"escala":{"type":"boolean","default":false},"place":{"type":"object","properties":{"placeId":{"type":"string","default":""},"lat":{"type":["number","null"],"default":null},"lng":{"type":["number","null"],"default":null},"formattedAddress":{"type":"string","default":""}},"additionalProperties":false,"default":{"placeId":"","lat":null,"lng":null,"formattedAddress":""}}},"required":["id","city","nights","transferBefore"],"additionalProperties":false},"maxItems":60},"returnCity":{"type":["string","null"]},"returnTransfer":{"anyOf":[{"type":"object","properties":{"id":{"type":"string"},"departDate":{"type":["string","null"]},"arriveDate":{"type":["string","null"]},"days":{"type":"integer","minimum":0,"maximum":30,"default":0},"departTime":{"type":"string","default":""},"arriveTime":{"type":"string","default":""},"flight":{"type":"object","properties":{"flightNo":{"type":"string","default":""},"airline":{"type":"string","default":""},"fromAirport":{"type":"string","default":""},"toAirport":{"type":"string","default":""},"source":{"type":"string","default":""},"fetchedAt":{"type":"string","default":""},"scheduleValidFor":{"type":"string","default":""}},"additionalProperties":false,"default":{"flightNo":"","airline":"","fromAirport":"","toAirport":"","source":"","fetchedAt":"","scheduleValidFor":""}}},"required":["id","departDate","arriveDate"],"additionalProperties":false},{"type":"null"}]},"originPlace":{"type":"object","properties":{"placeId":{"type":"string","default":""},"lat":{"type":["number","null"],"default":null},"lng":{"type":["number","null"],"default":null},"formattedAddress":{"type":"string","default":""}},"additionalProperties":false,"default":{"placeId":"","lat":null,"lng":null,"formattedAddress":""}},"returnPlace":{"type":"object","properties":{"placeId":{"type":"string","default":""},"lat":{"type":["number","null"],"default":null},"lng":{"type":["number","null"],"default":null},"formattedAddress":{"type":"string","default":""}},"additionalProperties":false,"default":{"placeId":"","lat":null,"lng":null,"formattedAddress":""}}},"required":["version","originCity","stops","returnCity","returnTransfer"],"additionalProperties":false},{"type":"null"}]},"presentation":{"type":"object","properties":{"logoUrl":{"anyOf":[{"type":"string","format":"uri"},{"type":"null"}]},"brandColor":{"anyOf":[{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},{"type":"null"}]},"fontFamily":{"anyOf":[{"type":"string","enum":["inter","montserrat","poppins","lora","playfair","source-sans"]},{"type":"null"}]},"headerMedia":{"anyOf":[{"type":"object","properties":{"type":{"type":"string","enum":["image","video"]},"url":{"type":"string","format":"uri"}},"required":["type","url"],"additionalProperties":false},{"type":"null"}]}},"additionalProperties":false},"profile":{"type":"object","properties":{"pace":{"anyOf":[{"type":"string","enum":["relajado","equilibrado","intenso"]},{"type":"null"}],"default":null},"profiles":{"type":"array","items":{"type":"string","enum":["primera_vez","repetidor","familia_ninos","pareja","grupo","senior","movilidad_reducida","cultural","gastronomico","naturaleza","fotografia","otaku","compras","presupuesto_ajustado","premium"]},"default":[]},"mobility":{"type":"string","enum":["normal","reducida"],"default":"normal"},"avoid":{"type":"array","items":{"type":"string"},"default":[]},"notes":{"type":"string","default":""}},"additionalProperties":false},"coverImageUrl":{"type":["string","null"]},"coverage":{"anyOf":[{"type":"object","properties":{"state":{"type":"string","enum":["sin_cobros","pago_parcial","pagado"]},"percent":{"type":"integer"},"overpaid":{"type":"boolean"}},"required":["state","percent","overpaid"],"additionalProperties":false},{"type":"null"}]},"metadata":{"type":"object","additionalProperties":{"type":"string","maxLength":500},"propertyNames":{"pattern":"^[A-Za-z0-9_.-]{1,40}$"}},"appUrl":{"type":["string","null"]},"publicUrl":{"type":["string","null"]},"createdAt":{"type":"string"},"updatedAt":{"type":"string"}},"required":["object","id","code","title","startDate","endDate","publication","commercialState","travelers","ownerId","design","presentation","profile","coverImageUrl","coverage","metadata","appUrl","publicUrl","createdAt","updatedAt"],"additionalProperties":false}}}},"default":{"description":"Error (RFC 9457)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"state":{"type":"string","enum":["nueva","propuesta_enviada","aceptada","reserva_provisional","reservada","rechazada","cancelada"]}},"required":["state"],"additionalProperties":false}}}}}},"/trips/{tripId}/itinerary":{"get":{"operationId":"itinerary.get","summary":"Get a trip's itinerary","description":"Returns the trip's itinerary as a flat list of blocks in rank order; `parentId` builds the tree (agenda → `dia` → activities, and so on). Block `type`s and `data` fields are the app's own (`dia`, `actividad`, `texto`, …). Each block carries its `version`: an update or delete sends it back as `expectedVersion`.\n\n**Permissions:** `trips:read`.","tags":["Itinerary"],"x-scopes":["trips:read"],"x-undo":"none","parameters":[{"name":"tripId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"object":{"type":"string","const":"itinerary"},"tripId":{"type":"string","format":"uuid"},"title":{"type":"string"},"publication":{"type":"string","enum":["draft","published"]},"hasDesignedRoute":{"type":"boolean"},"blocks":{"type":"array","items":{"type":"object","properties":{"object":{"type":"string","const":"block"},"id":{"type":"string","format":"uuid"},"type":{"type":"string","enum":["titulo","texto","imagen","agenda","dia","caja","desplegable","seccion","capitulo","derivado","actividad","alojamiento","vuelo","comida","transporte","tren","crucero","informacion","galeria","video","mapa","html","itinerario"]},"parentId":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}]},"rank":{"type":"string"},"data":{"type":"object","additionalProperties":{}},"layout":{"type":"object","properties":{"colSpan":{"type":"number","enum":[1,2,3],"default":3},"hidden":{"type":"boolean","description":"Hide this block (and its children) from the traveler."}},"additionalProperties":false},"version":{"type":"integer"},"source":{"anyOf":[{"type":"object","properties":{"kind":{"type":"string","minLength":1},"key":{"type":"string","minLength":1}},"required":["kind","key"],"additionalProperties":false},{"type":"null"}]}},"required":["object","id","type","parentId","rank","data","layout","version","source"],"additionalProperties":false}}},"required":["object","tripId","title","publication","hasDesignedRoute","blocks"],"additionalProperties":false}}}},"default":{"description":"Error (RFC 9457)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/trips/{tripId}/itinerary/blocks/{blockId}":{"get":{"operationId":"itinerary.getBlock","summary":"Get one block","description":"Returns one block of the trip's itinerary, with its full `data` and its current `version`.\n\n**Permissions:** `trips:read`.","tags":["Itinerary"],"x-scopes":["trips:read"],"x-undo":"none","parameters":[{"name":"tripId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"blockId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"object":{"type":"string","const":"block"},"id":{"type":"string","format":"uuid"},"type":{"type":"string","enum":["titulo","texto","imagen","agenda","dia","caja","desplegable","seccion","capitulo","derivado","actividad","alojamiento","vuelo","comida","transporte","tren","crucero","informacion","galeria","video","mapa","html","itinerario"]},"parentId":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}]},"rank":{"type":"string"},"data":{"type":"object","additionalProperties":{}},"layout":{"type":"object","properties":{"colSpan":{"type":"number","enum":[1,2,3],"default":3},"hidden":{"type":"boolean","description":"Hide this block (and its children) from the traveler."}},"additionalProperties":false},"version":{"type":"integer"},"source":{"anyOf":[{"type":"object","properties":{"kind":{"type":"string","minLength":1},"key":{"type":"string","minLength":1}},"required":["kind","key"],"additionalProperties":false},{"type":"null"}]}},"required":["object","id","type","parentId","rank","data","layout","version","source"],"additionalProperties":false}}}},"default":{"description":"Error (RFC 9457)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/trips/{tripId}/itinerary/ops":{"post":{"operationId":"itinerary.applyOps","summary":"Change the itinerary","description":"Applies a batch of block operations (`add`, `update`, `move`, `delete`) atomically, with the builder's own validation, and re-plans the route of every day it touches. Rules:\n- `update` and `delete` send the block's current `version` as `expectedVersion`; a stale one is a 409.\n- `update.data` is MERGED into the block's data, so send only the fields you change. An unknown field is a 422. A stop's times on a planned route belong to the route and are ignored.\n- A later op in the same batch refers to a block added earlier by its `clientId` (in `parentId` or `anchorId`). The server assigns ids and returns them in `created`.\n- `dia` structure ops are refused (422) on a trip whose days come from its design; change the design, then call /itinerary/sync.\n- Deleting more than 5 blocks, or more than 30 % of the itinerary, needs `confirm` set to the trip's exact title.\n- A batch in which nothing changes is refused (422), and so is deleting a retired block type, which could not be undone.\n\nWith `?dryRun=true`, returns the counts and the planner's notices without writing.\n\n**Permissions:** `trips:write`.\n\n**Undo:** the response carries `Bymundi-Change-Id`; `POST /changes/{changeId}/revert` undoes it.","tags":["Itinerary"],"x-scopes":["trips:write"],"x-undo":"change","parameters":[{"name":"tripId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"$ref":"#/components/parameters/DryRun"},{"$ref":"#/components/parameters/IdempotencyKey"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"anyOf":[{"type":"object","properties":{"object":{"type":"string","const":"itinerary_change"},"changeId":{"type":"string","format":"uuid"},"created":{"type":"array","items":{"type":"object","properties":{"clientId":{"type":["string","null"]},"id":{"type":"string","format":"uuid"}},"required":["clientId","id"],"additionalProperties":false}},"itinerary":{"type":"object","properties":{"object":{"type":"string","const":"itinerary"},"tripId":{"type":"string","format":"uuid"},"title":{"type":"string"},"publication":{"type":"string","enum":["draft","published"]},"hasDesignedRoute":{"type":"boolean"},"blocks":{"type":"array","items":{"type":"object","properties":{"object":{"type":"string","const":"block"},"id":{"type":"string","format":"uuid"},"type":{"type":"string","enum":["titulo","texto","imagen","agenda","dia","caja","desplegable","seccion","capitulo","derivado","actividad","alojamiento","vuelo","comida","transporte","tren","crucero","informacion","galeria","video","mapa","html","itinerario"]},"parentId":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}]},"rank":{"type":"string"},"data":{"type":"object","additionalProperties":{}},"layout":{"type":"object","properties":{"colSpan":{"type":"number","enum":[1,2,3],"default":3},"hidden":{"type":"boolean","description":"Hide this block (and its children) from the traveler."}},"additionalProperties":false},"version":{"type":"integer"},"source":{"anyOf":[{"type":"object","properties":{"kind":{"type":"string","minLength":1},"key":{"type":"string","minLength":1}},"required":["kind","key"],"additionalProperties":false},{"type":"null"}]}},"required":["object","id","type","parentId","rank","data","layout","version","source"],"additionalProperties":false}}},"required":["object","tripId","title","publication","hasDesignedRoute","blocks"],"additionalProperties":false}},"required":["object","changeId","created","itinerary"],"additionalProperties":false},{"type":"object","properties":{"object":{"type":"string","const":"itinerary_change_preview"},"added":{"type":"integer"},"updated":{"type":"integer"},"moved":{"type":"integer"},"removed":{"type":"integer"},"notices":{"type":"array","items":{"type":"string"}},"requiresConfirmation":{"type":"boolean"}},"required":["object","added","updated","moved","removed","notices","requiresConfirmation"],"additionalProperties":false}]}}}},"default":{"description":"Error (RFC 9457)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"ops":{"type":"array","items":{"anyOf":[{"type":"object","properties":{"op":{"type":"string","const":"add"},"type":{"type":"string","enum":["titulo","texto","imagen","agenda","dia","caja","desplegable","seccion","capitulo","derivado","actividad","alojamiento","vuelo","comida","transporte","tren","crucero","informacion","galeria","video","mapa","html","itinerario"]},"parentId":{"anyOf":[{"type":"string","minLength":1},{"type":"null"}],"default":null},"position":{"type":"string","enum":["start","end","after","before"],"default":"end"},"anchorId":{"type":"string","default":""},"data":{"type":"object","additionalProperties":{}},"layout":{"type":"object","properties":{"colSpan":{"type":"number","enum":[1,2,3]},"hidden":{"type":"boolean"}},"additionalProperties":false},"id":{"type":"string","format":"uuid"},"source":{"anyOf":[{"type":"object","properties":{"kind":{"type":"string","minLength":1},"key":{"type":"string","minLength":1}},"required":["kind","key"],"additionalProperties":false},{"type":"null"}]},"clientId":{"type":"string"}},"required":["op","type"],"additionalProperties":false},{"type":"object","properties":{"op":{"type":"string","const":"update"},"id":{"type":"string","minLength":1},"data":{"type":"object","additionalProperties":{}},"layout":{"type":"object","properties":{"colSpan":{"type":"number","enum":[1,2,3]},"hidden":{"type":"boolean"}},"additionalProperties":false},"source":{"anyOf":[{"type":"object","properties":{"kind":{"type":"string","minLength":1},"key":{"type":"string","minLength":1}},"required":["kind","key"],"additionalProperties":false},{"type":"null"}]},"expectedVersion":{"type":"integer","minimum":0}},"required":["op","id","expectedVersion"],"additionalProperties":false},{"type":"object","properties":{"op":{"type":"string","const":"move"},"id":{"type":"string","minLength":1},"parentId":{"anyOf":[{"type":"string","minLength":1},{"type":"null"}]},"position":{"type":"string","enum":["start","end","after","before"],"default":"end"},"anchorId":{"type":"string","default":""}},"required":["op","id","parentId"],"additionalProperties":false},{"type":"object","properties":{"op":{"type":"string","const":"delete"},"id":{"type":"string","minLength":1},"expectedVersion":{"type":"integer","minimum":0}},"required":["op","id","expectedVersion"],"additionalProperties":false}]},"minItems":1,"maxItems":200},"confirm":{"type":"string","maxLength":300}},"required":["ops"],"additionalProperties":false}}}}}},"/trips/{tripId}/itinerary/sync":{"post":{"operationId":"itinerary.sync","summary":"Sync the itinerary with the design","description":"Does what opening the Itinerario tab does in the app: rebuilds the days from the trip's design and latest quote (creating them the first time), then rewrites stop times planned by an older planner. Call it after changing a trip's `design`. `skipped` is true when the trip has no route. It records no change and has no undo; it is idempotent, and a second run changes nothing.\n\n**Permissions:** `trips:write`.","tags":["Itinerary"],"x-scopes":["trips:write"],"x-undo":"none","parameters":[{"name":"tripId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"$ref":"#/components/parameters/IdempotencyKey"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"object":{"type":"string","const":"itinerary_sync"},"skipped":{"type":"boolean"},"added":{"type":"integer"},"updated":{"type":"integer"},"removed":{"type":"integer"},"expelled":{"type":"integer"},"itinerary":{"type":"object","properties":{"object":{"type":"string","const":"itinerary"},"tripId":{"type":"string","format":"uuid"},"title":{"type":"string"},"publication":{"type":"string","enum":["draft","published"]},"hasDesignedRoute":{"type":"boolean"},"blocks":{"type":"array","items":{"type":"object","properties":{"object":{"type":"string","const":"block"},"id":{"type":"string","format":"uuid"},"type":{"type":"string","enum":["titulo","texto","imagen","agenda","dia","caja","desplegable","seccion","capitulo","derivado","actividad","alojamiento","vuelo","comida","transporte","tren","crucero","informacion","galeria","video","mapa","html","itinerario"]},"parentId":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}]},"rank":{"type":"string"},"data":{"type":"object","additionalProperties":{}},"layout":{"type":"object","properties":{"colSpan":{"type":"number","enum":[1,2,3],"default":3},"hidden":{"type":"boolean","description":"Hide this block (and its children) from the traveler."}},"additionalProperties":false},"version":{"type":"integer"},"source":{"anyOf":[{"type":"object","properties":{"kind":{"type":"string","minLength":1},"key":{"type":"string","minLength":1}},"required":["kind","key"],"additionalProperties":false},{"type":"null"}]}},"required":["object","id","type","parentId","rank","data","layout","version","source"],"additionalProperties":false}}},"required":["object","tripId","title","publication","hasDesignedRoute","blocks"],"additionalProperties":false}},"required":["object","skipped","added","updated","removed","expelled","itinerary"],"additionalProperties":false}}}},"default":{"description":"Error (RFC 9457)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{},"required":[],"additionalProperties":false}}}}}},"/catalog/entities":{"get":{"operationId":"catalog.entities.list","summary":"Search or browse the catalog","description":"The agency's catalog (products, destinations and places): destinations (`destino`), places (`punto`), accommodation (`alojamiento`), activities and services. Filters: `kind` and `tag`. Without `q`, browses the most recently changed entries first, paged by `nextCursor` — and takes `updatedSince`, `externalId`, `includeDeleted` and `deletedOnly`. For a polling trigger, pass the last `updatedAt` you saw as `updatedSince` with `includeDeleted=true`, and follow `nextCursor` until it is null. With `q`, returns one page of the best matches, ranked, with no cursor. Summaries only; GET /catalog/entities/{entityId} returns an entry in full.\n\n**Permissions:** `catalog:read`.","tags":["Catalog"],"x-scopes":["catalog:read"],"x-undo":"none","parameters":[{"name":"q","in":"query","required":false,"schema":{"type":"string","minLength":1,"maxLength":200}},{"name":"tag","in":"query","required":false,"schema":{"type":"string","minLength":1,"maxLength":60}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":100,"default":25}},{"name":"cursor","in":"query","required":false,"schema":{"type":"string","minLength":1,"maxLength":500}},{"name":"kind","in":"query","required":false,"schema":{"type":"string","enum":["destino","punto","alojamiento","actividad","servicio"]}},{"name":"updatedSince","in":"query","required":false,"schema":{"type":"string","format":"date-time","description":"Only entries changed at or after this instant — a polling trigger's watermark (deletes and restores count as changes)."}},{"name":"externalId","in":"query","required":false,"schema":{"type":"string","minLength":1,"maxLength":200,"description":"The entry with this external id."}},{"name":"includeDeleted","in":"query","required":false,"schema":{"anyOf":[{"type":"boolean"},{"type":"string","enum":["true","false"]}],"description":"Also return deleted entries (`deletedAt` set) — what a sync needs to see deletions."}},{"name":"deletedOnly","in":"query","required":false,"schema":{"anyOf":[{"type":"boolean"},{"type":"string","enum":["true","false"]}],"description":"Only deleted entries — what can be restored."}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"object":{"type":"string","const":"list"},"data":{"type":"array","items":{"type":"object","properties":{"object":{"type":"string","const":"catalog_entity_summary"},"id":{"type":"string","format":"uuid"},"kind":{"type":"string","enum":["destino","punto","alojamiento","actividad","servicio"]},"name":{"type":"string"},"placeId":{"type":"string"},"cityKey":{"type":"string"},"externalId":{"type":"string"},"tags":{"type":"array","items":{"type":"string"}},"partOf":{"type":["string","null"]},"category":{"type":"string"},"coverUrl":{"type":["string","null"]},"updatedAt":{"type":"string"},"deletedAt":{"type":["string","null"]}},"required":["object","id","kind","name","placeId","cityKey","externalId","tags","partOf","category","coverUrl","updatedAt","deletedAt"],"additionalProperties":false}},"nextCursor":{"type":["string","null"]}},"required":["object","data","nextCursor"],"additionalProperties":false}}}},"default":{"description":"Error (RFC 9457)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"post":{"operationId":"catalog.entities.create","summary":"Create a catalog entry","description":"Creates a catalog entry, as New in the Catalog: a `destino` (a country, city or zone), a place (`punto`), accommodation (`alojamiento`, which needs a Google `placeId`), an activity (`actividad`) or a service (`servicio`). Put it in the tree with `content.partOf` (the parent's id). An entry of the same kind for the same Google place, or with the same `externalId`, is a 409 naming the existing one (`existingId`) — update that one instead. Images are added after, with the entry's image upload. Undo with POST /changes/{changeId}/revert (a soft delete, while nobody has edited it).\n\n`content` fields by kind — use exactly these names; an unknown field is refused. `text` fields accept plain text (one paragraph per line). `partOf` is the parent entry's id: a `punto` hangs from a `destino`; nothing hangs from a `punto`.\nEvery kind also takes: category: string, features: string[], altNames: string[], estado: borrador|migrado|revisado|publicado|obsoleto, verifiedAt: string (pattern)|null, source: string, reviewNotes: string.\n- destino: partOf: uuid|null, intro: text, gettingAround: text, food: text, whenToGo: text, zoneNote: string\n- punto: partOf: uuid|null, description: text, tips: text, warnings: text, durationMin: number, hours: {state: unknown|always|scheduled, rules: string, display: string, note: string}, closedWeekdays: mon|tue|wed|thu|fri|sat|sun[], momentsOfDay: amanecer|manana|mediodia|tarde|atardecer|noche[], bestSeasons: primavera|sakura|verano|otono|koyo|invierno|iluminaciones|todo_el_ano[], intensity: baja|media|alta, indoor: boolean, accessibility: unknown|accessible|limited|not, profiles: primera_vez|repetidor|familia_ninos|pareja|grupo|senior|movilidad_reducida|cultural|gastronomico|naturaleza|fotografia|otaku|compras|presupuesto_ajustado|premium[], priority: 1|2|3, paidEntry: boolean, priceNote: string, bookingUrl: string, arrival: text, mapUrl: string, googleFeatureId: string\n- alojamiento: partOf: uuid|null, description: text, tips: text, warnings: text, includes: text, accessibility: unknown|accessible|limited|not, checkInWindow: {from: string (pattern), to: string (pattern)}, checkOutTime: string (pattern), mealTimes: {breakfast: string (pattern), dinner: string (pattern), note: string}\n- actividad: partOf: uuid|null, description: text, tips: text, warnings: text, durationMin: number|null, hours: {state: unknown|always|scheduled, rules: string, display: string, note: string}, closedWeekdays: mon|tue|wed|thu|fri|sat|sun[], momentsOfDay: amanecer|manana|mediodia|tarde|atardecer|noche[], bestSeasons: primavera|sakura|verano|otono|koyo|invierno|iluminaciones|todo_el_ano[], intensity: baja|media|alta, indoor: boolean, accessibility: unknown|accessible|limited|not, profiles: primera_vez|repetidor|familia_ninos|pareja|grupo|senior|movilidad_reducida|cultural|gastronomico|naturaleza|fotografia|otaku|compras|presupuesto_ajustado|premium[], includes: text, meetingPoint: string, requiresReservation: boolean, fixedTime: boolean, providers: {key: string, name: string, place: object, partOf: uuid|null, notes: string}[], beforeYouGo: text\n- servicio: partOf: uuid|null, description: text, tips: text, warnings: text, includes: text, provider: string\n\n**Permissions:** `catalog:write`.\n\n**Undo:** the response carries `Bymundi-Change-Id`; `POST /changes/{changeId}/revert` undoes it.","tags":["Catalog"],"x-scopes":["catalog:write"],"x-undo":"change","parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"responses":{"201":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"object":{"type":"string","const":"catalog_entity"},"id":{"type":"string","format":"uuid"},"kind":{"type":"string","enum":["destino","punto","alojamiento","actividad","servicio"]},"name":{"type":"string"},"placeId":{"type":"string"},"cityKey":{"type":"string"},"externalId":{"type":"string"},"place":{"type":"object","additionalProperties":{}},"images":{"type":"array","items":{"type":"object","additionalProperties":{}}},"tags":{"type":"array","items":{"type":"string"}},"origin":{"type":"string","enum":["human","ai","api","import"]},"content":{"type":"object","additionalProperties":{}},"updatedAt":{"type":"string"},"deletedAt":{"type":["string","null"]}},"required":["object","id","kind","name","placeId","cityKey","externalId","place","images","tags","origin","content","updatedAt","deletedAt"],"additionalProperties":false}}}},"default":{"description":"Error (RFC 9457)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"kind":{"type":"string","enum":["destino","punto","alojamiento","actividad","servicio"]},"name":{"type":"string","minLength":1,"maxLength":200},"placeId":{"type":"string","maxLength":300,"description":"The Google place id. Required for `alojamiento`."},"cityKey":{"type":"string","maxLength":200,"description":"A normalized city key; derived from the name when absent."},"place":{"type":"object","properties":{"lat":{"anyOf":[{"type":"number","minimum":-90,"maximum":90},{"type":"null"}]},"lng":{"anyOf":[{"type":"number","minimum":-180,"maximum":180},{"type":"null"}]},"formattedAddress":{"type":"string","maxLength":500}},"additionalProperties":false,"description":"Where it is. The Google place id goes in `placeId`, not here."},"content":{"type":"object","additionalProperties":{},"description":"The kind's own fields — see the list in the description."},"tags":{"type":"array","items":{"type":"string","minLength":1,"maxLength":60},"maxItems":12,"description":"Lowercased and de-duplicated; at most 12."},"externalId":{"type":"string","maxLength":200,"description":"Your system's id for this entry (e.g. a supplier's product code). Unique among the agency's live entries; \"\" clears it."}},"required":["kind","name"],"additionalProperties":false}}}}}},"/catalog/entities/{entityId}":{"get":{"operationId":"catalog.entities.get","summary":"Get a catalog entry","description":"Returns one catalog entry in full: its place, images, tags and its kind's own fields (`content`). An entry deleted in the app is still returned, with `deletedAt` set, because trips that use it still show it.\n\n**Permissions:** `catalog:read`.","tags":["Catalog"],"x-scopes":["catalog:read"],"x-undo":"none","parameters":[{"name":"entityId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"object":{"type":"string","const":"catalog_entity"},"id":{"type":"string","format":"uuid"},"kind":{"type":"string","enum":["destino","punto","alojamiento","actividad","servicio"]},"name":{"type":"string"},"placeId":{"type":"string"},"cityKey":{"type":"string"},"externalId":{"type":"string"},"place":{"type":"object","additionalProperties":{}},"images":{"type":"array","items":{"type":"object","additionalProperties":{}}},"tags":{"type":"array","items":{"type":"string"}},"origin":{"type":"string","enum":["human","ai","api","import"]},"content":{"type":"object","additionalProperties":{}},"updatedAt":{"type":"string"},"deletedAt":{"type":["string","null"]}},"required":["object","id","kind","name","placeId","cityKey","externalId","place","images","tags","origin","content","updatedAt","deletedAt"],"additionalProperties":false}}}},"default":{"description":"Error (RFC 9457)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"patch":{"operationId":"catalog.entities.update","summary":"Update a catalog entry","description":"Edits a catalog entry, as the Catalog's drawer does. Send only what changes: `content` MERGES into the entry's (an absent field stays; send the empty value — \"\", [] or null where allowed — to clear one). `images` REPLACES the list: send it to reorder, re-describe (`alt`) or remove photos, or to attach an image uploaded through this API (by `assetId`); it cannot add an external URL. Move the entry in the tree with `content.partOf`. The kind never changes. Pass the `updatedAt` you read, exactly as you read it, as `expectedUpdatedAt` to refuse a stale write with a 409. Undo with POST /changes/{changeId}/revert.\n\n`content` fields by kind — use exactly these names; an unknown field is refused. `text` fields accept plain text (one paragraph per line). `partOf` is the parent entry's id: a `punto` hangs from a `destino`; nothing hangs from a `punto`.\nEvery kind also takes: category: string, features: string[], altNames: string[], estado: borrador|migrado|revisado|publicado|obsoleto, verifiedAt: string (pattern)|null, source: string, reviewNotes: string.\n- destino: partOf: uuid|null, intro: text, gettingAround: text, food: text, whenToGo: text, zoneNote: string\n- punto: partOf: uuid|null, description: text, tips: text, warnings: text, durationMin: number, hours: {state: unknown|always|scheduled, rules: string, display: string, note: string}, closedWeekdays: mon|tue|wed|thu|fri|sat|sun[], momentsOfDay: amanecer|manana|mediodia|tarde|atardecer|noche[], bestSeasons: primavera|sakura|verano|otono|koyo|invierno|iluminaciones|todo_el_ano[], intensity: baja|media|alta, indoor: boolean, accessibility: unknown|accessible|limited|not, profiles: primera_vez|repetidor|familia_ninos|pareja|grupo|senior|movilidad_reducida|cultural|gastronomico|naturaleza|fotografia|otaku|compras|presupuesto_ajustado|premium[], priority: 1|2|3, paidEntry: boolean, priceNote: string, bookingUrl: string, arrival: text, mapUrl: string, googleFeatureId: string\n- alojamiento: partOf: uuid|null, description: text, tips: text, warnings: text, includes: text, accessibility: unknown|accessible|limited|not, checkInWindow: {from: string (pattern), to: string (pattern)}, checkOutTime: string (pattern), mealTimes: {breakfast: string (pattern), dinner: string (pattern), note: string}\n- actividad: partOf: uuid|null, description: text, tips: text, warnings: text, durationMin: number|null, hours: {state: unknown|always|scheduled, rules: string, display: string, note: string}, closedWeekdays: mon|tue|wed|thu|fri|sat|sun[], momentsOfDay: amanecer|manana|mediodia|tarde|atardecer|noche[], bestSeasons: primavera|sakura|verano|otono|koyo|invierno|iluminaciones|todo_el_ano[], intensity: baja|media|alta, indoor: boolean, accessibility: unknown|accessible|limited|not, profiles: primera_vez|repetidor|familia_ninos|pareja|grupo|senior|movilidad_reducida|cultural|gastronomico|naturaleza|fotografia|otaku|compras|presupuesto_ajustado|premium[], includes: text, meetingPoint: string, requiresReservation: boolean, fixedTime: boolean, providers: {key: string, name: string, place: object, partOf: uuid|null, notes: string}[], beforeYouGo: text\n- servicio: partOf: uuid|null, description: text, tips: text, warnings: text, includes: text, provider: string\n\n**Permissions:** `catalog:write`.\n\n**Undo:** the response carries `Bymundi-Change-Id`; `POST /changes/{changeId}/revert` undoes it.","tags":["Catalog"],"x-scopes":["catalog:write"],"x-undo":"change","parameters":[{"name":"entityId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"$ref":"#/components/parameters/IdempotencyKey"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"object":{"type":"string","const":"catalog_entity"},"id":{"type":"string","format":"uuid"},"kind":{"type":"string","enum":["destino","punto","alojamiento","actividad","servicio"]},"name":{"type":"string"},"placeId":{"type":"string"},"cityKey":{"type":"string"},"externalId":{"type":"string"},"place":{"type":"object","additionalProperties":{}},"images":{"type":"array","items":{"type":"object","additionalProperties":{}}},"tags":{"type":"array","items":{"type":"string"}},"origin":{"type":"string","enum":["human","ai","api","import"]},"content":{"type":"object","additionalProperties":{}},"updatedAt":{"type":"string"},"deletedAt":{"type":["string","null"]}},"required":["object","id","kind","name","placeId","cityKey","externalId","place","images","tags","origin","content","updatedAt","deletedAt"],"additionalProperties":false}}}},"default":{"description":"Error (RFC 9457)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":200},"placeId":{"type":"string","maxLength":300,"description":"The Google place id. Required for `alojamiento`."},"cityKey":{"type":"string","maxLength":200,"description":"A normalized city key; derived from the name when absent."},"place":{"type":"object","properties":{"lat":{"anyOf":[{"type":"number","minimum":-90,"maximum":90},{"type":"null"}]},"lng":{"anyOf":[{"type":"number","minimum":-180,"maximum":180},{"type":"null"}]},"formattedAddress":{"type":"string","maxLength":500}},"additionalProperties":false,"description":"Where it is. The Google place id goes in `placeId`, not here."},"content":{"type":"object","additionalProperties":{},"description":"The kind's own fields — see the list in the description."},"tags":{"type":"array","items":{"type":"string","minLength":1,"maxLength":60},"maxItems":12,"description":"Lowercased and de-duplicated; at most 12."},"externalId":{"type":"string","maxLength":200,"description":"Your system's id for this entry (e.g. a supplier's product code). Unique among the agency's live entries; \"\" clears it."},"images":{"type":"array","items":{"type":"object","properties":{"assetId":{"type":"string","format":"uuid","description":"An image of this entry, or one uploaded through this API."},"url":{"type":"string","maxLength":2000,"description":"An image of this entry, by the url it already has."},"alt":{"type":"string","maxLength":300,"description":"A description of the photo for screen readers."}},"additionalProperties":false},"maxItems":30,"description":"The entry's whole photo list, in order."},"expectedUpdatedAt":{"type":"string","format":"date-time","description":"The entry's `updatedAt` as you read it."}},"required":[],"additionalProperties":false}}}}},"delete":{"operationId":"catalog.entities.delete","summary":"Delete a catalog entry","description":"Deletes a catalog entry, as the Catalog's Delete: SOFT — it leaves the lists, and trips that already use it keep showing it. Deleting a `destino` or a place takes everything below it (its zones and places; products are never taken). When that is more than the entry itself, `confirm` (a query parameter) must be its exact name; `?dryRun=true` answers the counts first. Undo with POST /changes/{changeId}/revert, or POST /catalog/entities/{entityId}/restore.\n\n**Permissions:** `catalog:write`.\n\n**Undo:** the response carries `Bymundi-Change-Id`; `POST /changes/{changeId}/revert` undoes it.","tags":["Catalog"],"x-scopes":["catalog:write"],"x-undo":"change","parameters":[{"name":"entityId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"confirm","in":"query","required":false,"schema":{"type":"string","maxLength":200,"description":"The entry's exact name, when the delete takes more than the entry itself."}},{"$ref":"#/components/parameters/DryRun"},{"$ref":"#/components/parameters/IdempotencyKey"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"anyOf":[{"type":"object","properties":{"object":{"type":"string","const":"catalog_entity"},"id":{"type":"string","format":"uuid"},"deleted":{"type":"boolean","const":true},"deletedIds":{"type":"array","items":{"type":"string","format":"uuid"}}},"required":["object","id","deleted","deletedIds"],"additionalProperties":false},{"type":"object","properties":{"object":{"type":"string","const":"catalog_delete_preview"},"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"deletes":{"type":"object","properties":{"zonas":{"type":"integer"},"lugares":{"type":"integer"}},"required":["zonas","lugares"],"additionalProperties":false},"requiresConfirmation":{"type":"boolean","description":"true: repeat without dryRun and with `confirm` set to the entry's exact name."}},"required":["object","id","name","deletes","requiresConfirmation"],"additionalProperties":false}]}}}},"default":{"description":"Error (RFC 9457)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/library/entries":{"get":{"operationId":"library.entries.list","summary":"Search or browse the block library","description":"The agency's saved blocks (Catalog → Blocks): reusable itinerary pieces such as a day or a section. Filter by `tag`. Without `q`, browses the most recently changed first, paged by `nextCursor`; `updatedSince` keeps only rows changed since (a polling trigger's watermark). With `q`, returns one page of the best matches, ranked.\n\n**Permissions:** `catalog:read`.","tags":["Catalog"],"x-scopes":["catalog:read"],"x-undo":"none","parameters":[{"name":"q","in":"query","required":false,"schema":{"type":"string","minLength":1,"maxLength":200}},{"name":"tag","in":"query","required":false,"schema":{"type":"string","minLength":1,"maxLength":60}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":100,"default":25}},{"name":"cursor","in":"query","required":false,"schema":{"type":"string","minLength":1,"maxLength":500}},{"name":"updatedSince","in":"query","required":false,"schema":{"type":"string","format":"date-time"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"object":{"type":"string","const":"list"},"data":{"type":"array","items":{"type":"object","properties":{"object":{"type":"string","const":"library_entry_summary"},"id":{"type":"string","format":"uuid"},"title":{"type":"string"},"rootType":{"type":"string"},"tags":{"type":"array","items":{"type":"string"}},"updatedAt":{"type":"string"}},"required":["object","id","title","rootType","tags","updatedAt"],"additionalProperties":false}},"nextCursor":{"type":["string","null"]}},"required":["object","data","nextCursor"],"additionalProperties":false}}}},"default":{"description":"Error (RFC 9457)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"post":{"operationId":"library.entries.create","summary":"Save a block to the library","description":"Saves one block of a trip — and everything inside it — as a reusable library entry (Catalog → Blocks), as Save to library does. The trip is read as it is now. Needs `trips:read` as well. Undo with POST /changes/{changeId}/revert, while nobody has edited the entry since.\n\n**Permissions:** `catalog:write`, `trips:read`.\n\n**Undo:** the response carries `Bymundi-Change-Id`; `POST /changes/{changeId}/revert` undoes it.","tags":["Catalog"],"x-scopes":["catalog:write","trips:read"],"x-undo":"change","parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"responses":{"201":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"object":{"type":"string","const":"library_entry"},"id":{"type":"string","format":"uuid"},"title":{"type":"string"},"rootType":{"type":"string"},"tags":{"type":"array","items":{"type":"string"}},"updatedAt":{"type":"string"},"snapshot":{"type":"object","additionalProperties":{}}},"required":["object","id","title","rootType","tags","updatedAt","snapshot"],"additionalProperties":false}}}},"default":{"description":"Error (RFC 9457)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"tripId":{"type":"string","format":"uuid"},"blockId":{"type":"string","minLength":1,"maxLength":64,"description":"The block's id or its short ref from get_itinerary."},"title":{"type":"string","minLength":1,"maxLength":200},"tags":{"type":"array","items":{"type":"string","minLength":1,"maxLength":60},"maxItems":20,"description":"Replaces the tags; lowercased."}},"required":["tripId","blockId","title"],"additionalProperties":false}}}}}},"/library/entries/{entryId}":{"get":{"operationId":"library.entries.get","summary":"Get a library block","description":"Returns one saved block with its whole subtree (`snapshot`: type, data, layout, children, with no ids): the content that inserting it into a trip copies.\n\n**Permissions:** `catalog:read`.","tags":["Catalog"],"x-scopes":["catalog:read"],"x-undo":"none","parameters":[{"name":"entryId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"object":{"type":"string","const":"library_entry"},"id":{"type":"string","format":"uuid"},"title":{"type":"string"},"rootType":{"type":"string"},"tags":{"type":"array","items":{"type":"string"}},"updatedAt":{"type":"string"},"snapshot":{"type":"object","additionalProperties":{}}},"required":["object","id","title","rootType","tags","updatedAt","snapshot"],"additionalProperties":false}}}},"default":{"description":"Error (RFC 9457)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"patch":{"operationId":"library.entries.update","summary":"Update a library block","description":"Renames or re-tags a library entry, and/or REPLACES its content with a block of a trip (`fromTrip`: the same capture as saving; the block must be of the entry's type, else 422 `root_type_mismatch`; needs `trips:read`). A refresh is refused with 409 `being_edited` while the entry is open in the builder. Pass the `updatedAt` you read as `expectedUpdatedAt` to refuse a stale write with a 409. Undo with POST /changes/{changeId}/revert.\n\n**Permissions:** `catalog:write`.\n\n**Undo:** the response carries `Bymundi-Change-Id`; `POST /changes/{changeId}/revert` undoes it.","tags":["Catalog"],"x-scopes":["catalog:write"],"x-undo":"change","parameters":[{"name":"entryId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"$ref":"#/components/parameters/IdempotencyKey"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"object":{"type":"string","const":"library_entry"},"id":{"type":"string","format":"uuid"},"title":{"type":"string"},"rootType":{"type":"string"},"tags":{"type":"array","items":{"type":"string"}},"updatedAt":{"type":"string"},"snapshot":{"type":"object","additionalProperties":{}}},"required":["object","id","title","rootType","tags","updatedAt","snapshot"],"additionalProperties":false}}}},"default":{"description":"Error (RFC 9457)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"title":{"type":"string","minLength":1,"maxLength":200},"tags":{"type":"array","items":{"type":"string","minLength":1,"maxLength":60},"maxItems":20,"description":"Replaces the tags; lowercased."},"fromTrip":{"type":"object","properties":{"tripId":{"type":"string","format":"uuid"},"blockId":{"type":"string","minLength":1,"maxLength":64,"description":"The block's id or its short ref from get_itinerary."}},"required":["tripId","blockId"],"additionalProperties":false},"expectedUpdatedAt":{"type":"string","format":"date-time"}},"required":[],"additionalProperties":false}}}}},"delete":{"operationId":"library.entries.delete","summary":"Delete a library block","description":"Deletes a library entry, as Delete in Catalog → Blocks. Trips that already inserted it keep their copy. Refused with 409 `being_edited` while it is open in the builder. Undo with POST /changes/{changeId}/revert: it re-creates the same entry, same id.\n\n**Permissions:** `catalog:write`.\n\n**Undo:** the response carries `Bymundi-Change-Id`; `POST /changes/{changeId}/revert` undoes it.","tags":["Catalog"],"x-scopes":["catalog:write"],"x-undo":"change","parameters":[{"name":"entryId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"$ref":"#/components/parameters/IdempotencyKey"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"object":{"type":"string","const":"library_entry"},"id":{"type":"string","format":"uuid"},"deleted":{"type":"boolean","const":true}},"required":["object","id","deleted"],"additionalProperties":false}}}},"default":{"description":"Error (RFC 9457)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/trip-templates":{"get":{"operationId":"catalog.tripTemplates.list","summary":"Search or browse trip templates","description":"The agency's trip templates (Catalog → Trips). Each is a design plus the blocks a trip created from it starts with (POST /trips with `templateId`). Filter by `tag`. Without `q`, browses the most recently changed first, paged by `nextCursor`; `updatedSince` keeps only rows changed since (a polling trigger's watermark). With `q`, returns one page of the best matches, ranked.\n\n**Permissions:** `catalog:read`.","tags":["Catalog"],"x-scopes":["catalog:read"],"x-undo":"none","parameters":[{"name":"q","in":"query","required":false,"schema":{"type":"string","minLength":1,"maxLength":200}},{"name":"tag","in":"query","required":false,"schema":{"type":"string","minLength":1,"maxLength":60}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":100,"default":25}},{"name":"cursor","in":"query","required":false,"schema":{"type":"string","minLength":1,"maxLength":500}},{"name":"updatedSince","in":"query","required":false,"schema":{"type":"string","format":"date-time"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"object":{"type":"string","const":"list"},"data":{"type":"array","items":{"type":"object","properties":{"object":{"type":"string","const":"trip_template_summary"},"id":{"type":"string","format":"uuid"},"title":{"type":"string"},"description":{"type":"string"},"tags":{"type":"array","items":{"type":"string"}},"coverUrl":{"type":["string","null"]},"stopCount":{"type":"integer"},"updatedAt":{"type":"string"}},"required":["object","id","title","description","tags","coverUrl","stopCount","updatedAt"],"additionalProperties":false}},"nextCursor":{"type":["string","null"]}},"required":["object","data","nextCursor"],"additionalProperties":false}}}},"default":{"description":"Error (RFC 9457)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"post":{"operationId":"catalog.tripTemplates.create","summary":"Save a trip as a template","description":"Saves a trip as a trip template (Catalog → Trips), as Save trip as template does: its design, its blocks, its quotes as draft proposals, its headcount, presentation and start date. The trip must have a design (else 422 `trip_has_no_design`). The trip is read as it is now — its itinerary is not synced first. Needs `trips:read` as well. Undo with POST /changes/{changeId}/revert.\n\n**Permissions:** `catalog:write`, `trips:read`.\n\n**Undo:** the response carries `Bymundi-Change-Id`; `POST /changes/{changeId}/revert` undoes it.","tags":["Catalog"],"x-scopes":["catalog:write","trips:read"],"x-undo":"change","parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"responses":{"201":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"object":{"type":"string","const":"trip_template"},"id":{"type":"string","format":"uuid"},"title":{"type":"string"},"description":{"type":"string"},"tags":{"type":"array","items":{"type":"string"}},"coverUrl":{"type":["string","null"]},"stopCount":{"type":"integer"},"updatedAt":{"type":"string"},"design":{"type":"object","properties":{"version":{"type":"number","const":1},"originCity":{"type":"string"},"stops":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"city":{"type":"string"},"nights":{"type":"integer","minimum":0,"maximum":365},"transferBefore":{"anyOf":[{"type":"object","properties":{"id":{"type":"string"},"departDate":{"type":["string","null"]},"arriveDate":{"type":["string","null"]},"days":{"type":"integer","minimum":0,"maximum":30,"default":0},"departTime":{"type":"string","default":""},"arriveTime":{"type":"string","default":""},"flight":{"type":"object","properties":{"flightNo":{"type":"string","default":""},"airline":{"type":"string","default":""},"fromAirport":{"type":"string","default":""},"toAirport":{"type":"string","default":""},"source":{"type":"string","default":""},"fetchedAt":{"type":"string","default":""},"scheduleValidFor":{"type":"string","default":""}},"additionalProperties":false,"default":{"flightNo":"","airline":"","fromAirport":"","toAirport":"","source":"","fetchedAt":"","scheduleValidFor":""}}},"required":["id","departDate","arriveDate"],"additionalProperties":false},{"type":"null"}]},"escala":{"type":"boolean","default":false},"place":{"type":"object","properties":{"placeId":{"type":"string","default":""},"lat":{"type":["number","null"],"default":null},"lng":{"type":["number","null"],"default":null},"formattedAddress":{"type":"string","default":""}},"additionalProperties":false,"default":{"placeId":"","lat":null,"lng":null,"formattedAddress":""}}},"required":["id","city","nights","transferBefore"],"additionalProperties":false},"maxItems":60},"returnCity":{"type":["string","null"]},"returnTransfer":{"anyOf":[{"type":"object","properties":{"id":{"type":"string"},"departDate":{"type":["string","null"]},"arriveDate":{"type":["string","null"]},"days":{"type":"integer","minimum":0,"maximum":30,"default":0},"departTime":{"type":"string","default":""},"arriveTime":{"type":"string","default":""},"flight":{"type":"object","properties":{"flightNo":{"type":"string","default":""},"airline":{"type":"string","default":""},"fromAirport":{"type":"string","default":""},"toAirport":{"type":"string","default":""},"source":{"type":"string","default":""},"fetchedAt":{"type":"string","default":""},"scheduleValidFor":{"type":"string","default":""}},"additionalProperties":false,"default":{"flightNo":"","airline":"","fromAirport":"","toAirport":"","source":"","fetchedAt":"","scheduleValidFor":""}}},"required":["id","departDate","arriveDate"],"additionalProperties":false},{"type":"null"}]},"originPlace":{"type":"object","properties":{"placeId":{"type":"string","default":""},"lat":{"type":["number","null"],"default":null},"lng":{"type":["number","null"],"default":null},"formattedAddress":{"type":"string","default":""}},"additionalProperties":false,"default":{"placeId":"","lat":null,"lng":null,"formattedAddress":""}},"returnPlace":{"type":"object","properties":{"placeId":{"type":"string","default":""},"lat":{"type":["number","null"],"default":null},"lng":{"type":["number","null"],"default":null},"formattedAddress":{"type":"string","default":""}},"additionalProperties":false,"default":{"placeId":"","lat":null,"lng":null,"formattedAddress":""}}},"required":["version","originCity","stops","returnCity","returnTransfer"],"additionalProperties":false},"blocks":{"type":"array","items":{"type":"object","additionalProperties":{}}},"proposals":{"anyOf":[{"type":"array","items":{"type":"object","properties":{"name":{"type":"string"},"mode":{"type":"string","description":"`package` (one price, upgrade packages) or `per_item` (the customer picks lines)."},"marginPct":{"type":"number"},"lineCount":{"type":"integer"},"wasAccepted":{"type":"boolean","description":"Accepted in the trip the template was saved from."}},"required":["name","mode","marginPct","lineCount","wasAccepted"],"additionalProperties":false}},{"type":"null"}],"description":"The quotes a trip made from it starts with, as drafts; null on a template saved before proposals were kept."},"travelers":{"anyOf":[{"type":"integer"},{"type":"null"}],"description":"The headcount a trip made from it starts with."},"presentation":{"anyOf":[{"type":"object","additionalProperties":{}},{"type":"null"}],"description":"The branding a trip made from it starts with."},"baseStartDate":{"type":["string","null"],"description":"The start date of the trip it was saved from; a new trip's dates shift relative to it."}},"required":["object","id","title","description","tags","coverUrl","stopCount","updatedAt","design","blocks","proposals","travelers","presentation","baseStartDate"],"additionalProperties":false}}}},"default":{"description":"Error (RFC 9457)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"tripId":{"type":"string","format":"uuid"},"title":{"type":"string","minLength":1,"maxLength":200},"description":{"type":"string","maxLength":2000},"tags":{"type":"array","items":{"type":"string","minLength":1,"maxLength":60},"maxItems":20,"description":"Replaces the tags; lowercased."}},"required":["tripId","title"],"additionalProperties":false}}}}}},"/trip-templates/{templateId}":{"get":{"operationId":"catalog.tripTemplates.get","summary":"Get a trip template","description":"Returns one trip template in full: its design (the route) and its block forest. Create a trip from it with POST /trips and `templateId`.\n\n**Permissions:** `catalog:read`.","tags":["Catalog"],"x-scopes":["catalog:read"],"x-undo":"none","parameters":[{"name":"templateId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"object":{"type":"string","const":"trip_template"},"id":{"type":"string","format":"uuid"},"title":{"type":"string"},"description":{"type":"string"},"tags":{"type":"array","items":{"type":"string"}},"coverUrl":{"type":["string","null"]},"stopCount":{"type":"integer"},"updatedAt":{"type":"string"},"design":{"type":"object","properties":{"version":{"type":"number","const":1},"originCity":{"type":"string"},"stops":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"city":{"type":"string"},"nights":{"type":"integer","minimum":0,"maximum":365},"transferBefore":{"anyOf":[{"type":"object","properties":{"id":{"type":"string"},"departDate":{"type":["string","null"]},"arriveDate":{"type":["string","null"]},"days":{"type":"integer","minimum":0,"maximum":30,"default":0},"departTime":{"type":"string","default":""},"arriveTime":{"type":"string","default":""},"flight":{"type":"object","properties":{"flightNo":{"type":"string","default":""},"airline":{"type":"string","default":""},"fromAirport":{"type":"string","default":""},"toAirport":{"type":"string","default":""},"source":{"type":"string","default":""},"fetchedAt":{"type":"string","default":""},"scheduleValidFor":{"type":"string","default":""}},"additionalProperties":false,"default":{"flightNo":"","airline":"","fromAirport":"","toAirport":"","source":"","fetchedAt":"","scheduleValidFor":""}}},"required":["id","departDate","arriveDate"],"additionalProperties":false},{"type":"null"}]},"escala":{"type":"boolean","default":false},"place":{"type":"object","properties":{"placeId":{"type":"string","default":""},"lat":{"type":["number","null"],"default":null},"lng":{"type":["number","null"],"default":null},"formattedAddress":{"type":"string","default":""}},"additionalProperties":false,"default":{"placeId":"","lat":null,"lng":null,"formattedAddress":""}}},"required":["id","city","nights","transferBefore"],"additionalProperties":false},"maxItems":60},"returnCity":{"type":["string","null"]},"returnTransfer":{"anyOf":[{"type":"object","properties":{"id":{"type":"string"},"departDate":{"type":["string","null"]},"arriveDate":{"type":["string","null"]},"days":{"type":"integer","minimum":0,"maximum":30,"default":0},"departTime":{"type":"string","default":""},"arriveTime":{"type":"string","default":""},"flight":{"type":"object","properties":{"flightNo":{"type":"string","default":""},"airline":{"type":"string","default":""},"fromAirport":{"type":"string","default":""},"toAirport":{"type":"string","default":""},"source":{"type":"string","default":""},"fetchedAt":{"type":"string","default":""},"scheduleValidFor":{"type":"string","default":""}},"additionalProperties":false,"default":{"flightNo":"","airline":"","fromAirport":"","toAirport":"","source":"","fetchedAt":"","scheduleValidFor":""}}},"required":["id","departDate","arriveDate"],"additionalProperties":false},{"type":"null"}]},"originPlace":{"type":"object","properties":{"placeId":{"type":"string","default":""},"lat":{"type":["number","null"],"default":null},"lng":{"type":["number","null"],"default":null},"formattedAddress":{"type":"string","default":""}},"additionalProperties":false,"default":{"placeId":"","lat":null,"lng":null,"formattedAddress":""}},"returnPlace":{"type":"object","properties":{"placeId":{"type":"string","default":""},"lat":{"type":["number","null"],"default":null},"lng":{"type":["number","null"],"default":null},"formattedAddress":{"type":"string","default":""}},"additionalProperties":false,"default":{"placeId":"","lat":null,"lng":null,"formattedAddress":""}}},"required":["version","originCity","stops","returnCity","returnTransfer"],"additionalProperties":false},"blocks":{"type":"array","items":{"type":"object","additionalProperties":{}}},"proposals":{"anyOf":[{"type":"array","items":{"type":"object","properties":{"name":{"type":"string"},"mode":{"type":"string","description":"`package` (one price, upgrade packages) or `per_item` (the customer picks lines)."},"marginPct":{"type":"number"},"lineCount":{"type":"integer"},"wasAccepted":{"type":"boolean","description":"Accepted in the trip the template was saved from."}},"required":["name","mode","marginPct","lineCount","wasAccepted"],"additionalProperties":false}},{"type":"null"}],"description":"The quotes a trip made from it starts with, as drafts; null on a template saved before proposals were kept."},"travelers":{"anyOf":[{"type":"integer"},{"type":"null"}],"description":"The headcount a trip made from it starts with."},"presentation":{"anyOf":[{"type":"object","additionalProperties":{}},{"type":"null"}],"description":"The branding a trip made from it starts with."},"baseStartDate":{"type":["string","null"],"description":"The start date of the trip it was saved from; a new trip's dates shift relative to it."}},"required":["object","id","title","description","tags","coverUrl","stopCount","updatedAt","design","blocks","proposals","travelers","presentation","baseStartDate"],"additionalProperties":false}}}},"default":{"description":"Error (RFC 9457)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"patch":{"operationId":"catalog.tripTemplates.update","summary":"Update a trip template","description":"Edits a template's title, description or tags, and/or REPLACES its content with a trip's (`fromTripId`: the same capture as saving; needs `trips:read`) — the API's Save changes. A refresh is refused with 409 `being_edited` while the template is open in the builder. Pass the `updatedAt` you read as `expectedUpdatedAt` to refuse a stale write with a 409. Undo with POST /changes/{changeId}/revert.\n\n**Permissions:** `catalog:write`.\n\n**Undo:** the response carries `Bymundi-Change-Id`; `POST /changes/{changeId}/revert` undoes it.","tags":["Catalog"],"x-scopes":["catalog:write"],"x-undo":"change","parameters":[{"name":"templateId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"$ref":"#/components/parameters/IdempotencyKey"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"object":{"type":"string","const":"trip_template"},"id":{"type":"string","format":"uuid"},"title":{"type":"string"},"description":{"type":"string"},"tags":{"type":"array","items":{"type":"string"}},"coverUrl":{"type":["string","null"]},"stopCount":{"type":"integer"},"updatedAt":{"type":"string"},"design":{"type":"object","properties":{"version":{"type":"number","const":1},"originCity":{"type":"string"},"stops":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"city":{"type":"string"},"nights":{"type":"integer","minimum":0,"maximum":365},"transferBefore":{"anyOf":[{"type":"object","properties":{"id":{"type":"string"},"departDate":{"type":["string","null"]},"arriveDate":{"type":["string","null"]},"days":{"type":"integer","minimum":0,"maximum":30,"default":0},"departTime":{"type":"string","default":""},"arriveTime":{"type":"string","default":""},"flight":{"type":"object","properties":{"flightNo":{"type":"string","default":""},"airline":{"type":"string","default":""},"fromAirport":{"type":"string","default":""},"toAirport":{"type":"string","default":""},"source":{"type":"string","default":""},"fetchedAt":{"type":"string","default":""},"scheduleValidFor":{"type":"string","default":""}},"additionalProperties":false,"default":{"flightNo":"","airline":"","fromAirport":"","toAirport":"","source":"","fetchedAt":"","scheduleValidFor":""}}},"required":["id","departDate","arriveDate"],"additionalProperties":false},{"type":"null"}]},"escala":{"type":"boolean","default":false},"place":{"type":"object","properties":{"placeId":{"type":"string","default":""},"lat":{"type":["number","null"],"default":null},"lng":{"type":["number","null"],"default":null},"formattedAddress":{"type":"string","default":""}},"additionalProperties":false,"default":{"placeId":"","lat":null,"lng":null,"formattedAddress":""}}},"required":["id","city","nights","transferBefore"],"additionalProperties":false},"maxItems":60},"returnCity":{"type":["string","null"]},"returnTransfer":{"anyOf":[{"type":"object","properties":{"id":{"type":"string"},"departDate":{"type":["string","null"]},"arriveDate":{"type":["string","null"]},"days":{"type":"integer","minimum":0,"maximum":30,"default":0},"departTime":{"type":"string","default":""},"arriveTime":{"type":"string","default":""},"flight":{"type":"object","properties":{"flightNo":{"type":"string","default":""},"airline":{"type":"string","default":""},"fromAirport":{"type":"string","default":""},"toAirport":{"type":"string","default":""},"source":{"type":"string","default":""},"fetchedAt":{"type":"string","default":""},"scheduleValidFor":{"type":"string","default":""}},"additionalProperties":false,"default":{"flightNo":"","airline":"","fromAirport":"","toAirport":"","source":"","fetchedAt":"","scheduleValidFor":""}}},"required":["id","departDate","arriveDate"],"additionalProperties":false},{"type":"null"}]},"originPlace":{"type":"object","properties":{"placeId":{"type":"string","default":""},"lat":{"type":["number","null"],"default":null},"lng":{"type":["number","null"],"default":null},"formattedAddress":{"type":"string","default":""}},"additionalProperties":false,"default":{"placeId":"","lat":null,"lng":null,"formattedAddress":""}},"returnPlace":{"type":"object","properties":{"placeId":{"type":"string","default":""},"lat":{"type":["number","null"],"default":null},"lng":{"type":["number","null"],"default":null},"formattedAddress":{"type":"string","default":""}},"additionalProperties":false,"default":{"placeId":"","lat":null,"lng":null,"formattedAddress":""}}},"required":["version","originCity","stops","returnCity","returnTransfer"],"additionalProperties":false},"blocks":{"type":"array","items":{"type":"object","additionalProperties":{}}},"proposals":{"anyOf":[{"type":"array","items":{"type":"object","properties":{"name":{"type":"string"},"mode":{"type":"string","description":"`package` (one price, upgrade packages) or `per_item` (the customer picks lines)."},"marginPct":{"type":"number"},"lineCount":{"type":"integer"},"wasAccepted":{"type":"boolean","description":"Accepted in the trip the template was saved from."}},"required":["name","mode","marginPct","lineCount","wasAccepted"],"additionalProperties":false}},{"type":"null"}],"description":"The quotes a trip made from it starts with, as drafts; null on a template saved before proposals were kept."},"travelers":{"anyOf":[{"type":"integer"},{"type":"null"}],"description":"The headcount a trip made from it starts with."},"presentation":{"anyOf":[{"type":"object","additionalProperties":{}},{"type":"null"}],"description":"The branding a trip made from it starts with."},"baseStartDate":{"type":["string","null"],"description":"The start date of the trip it was saved from; a new trip's dates shift relative to it."}},"required":["object","id","title","description","tags","coverUrl","stopCount","updatedAt","design","blocks","proposals","travelers","presentation","baseStartDate"],"additionalProperties":false}}}},"default":{"description":"Error (RFC 9457)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"title":{"type":"string","minLength":1,"maxLength":200},"description":{"type":"string","maxLength":2000},"tags":{"type":"array","items":{"type":"string","minLength":1,"maxLength":60},"maxItems":20,"description":"Replaces the tags; lowercased."},"fromTripId":{"type":"string","format":"uuid","description":"Replace the template's content with this trip's (design, blocks, proposals, pax, presentation, start date)."},"expectedUpdatedAt":{"type":"string","format":"date-time"}},"required":[],"additionalProperties":false}}}}},"delete":{"operationId":"catalog.tripTemplates.delete","summary":"Delete a trip template","description":"Deletes a trip template, as Delete in Catalog → Trips. Trips already created from it are not affected. Refused with 409 `being_edited` while it is open in the builder (deleting it would delete that working copy with it). Undo with POST /changes/{changeId}/revert: it re-creates the same template, same id.\n\n**Permissions:** `catalog:write`.\n\n**Undo:** the response carries `Bymundi-Change-Id`; `POST /changes/{changeId}/revert` undoes it.","tags":["Catalog"],"x-scopes":["catalog:write"],"x-undo":"change","parameters":[{"name":"templateId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"$ref":"#/components/parameters/IdempotencyKey"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"object":{"type":"string","const":"trip_template"},"id":{"type":"string","format":"uuid"},"deleted":{"type":"boolean","const":true}},"required":["object","id","deleted"],"additionalProperties":false}}}},"default":{"description":"Error (RFC 9457)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/catalog/entities/{entityId}/restore":{"post":{"operationId":"catalog.entities.restore","summary":"Restore a deleted catalog entry","description":"Brings back a deleted catalog entry, as Show deleted → Restore does — and every deleted parent above it, so it reappears in the tree. Another live entry holding its Google place meanwhile is a 409 `place_taken`. Undo with POST /changes/{changeId}/revert (deletes them again).\n\n**Permissions:** `catalog:write`.\n\n**Undo:** the response carries `Bymundi-Change-Id`; `POST /changes/{changeId}/revert` undoes it.","tags":["Catalog"],"x-scopes":["catalog:write"],"x-undo":"change","parameters":[{"name":"entityId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"$ref":"#/components/parameters/IdempotencyKey"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"object":{"type":"string","const":"catalog_entity"},"id":{"type":"string","format":"uuid"},"kind":{"type":"string","enum":["destino","punto","alojamiento","actividad","servicio"]},"name":{"type":"string"},"placeId":{"type":"string"},"cityKey":{"type":"string"},"externalId":{"type":"string"},"place":{"type":"object","additionalProperties":{}},"images":{"type":"array","items":{"type":"object","additionalProperties":{}}},"tags":{"type":"array","items":{"type":"string"}},"origin":{"type":"string","enum":["human","ai","api","import"]},"content":{"type":"object","additionalProperties":{}},"updatedAt":{"type":"string"},"deletedAt":{"type":["string","null"]},"restoredIds":{"type":"array","items":{"type":"string","format":"uuid"}}},"required":["object","id","kind","name","placeId","cityKey","externalId","place","images","tags","origin","content","updatedAt","deletedAt","restoredIds"],"additionalProperties":false}}}},"default":{"description":"Error (RFC 9457)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{},"required":[],"additionalProperties":false}}}}}},"/catalog/features":{"get":{"operationId":"catalog.features.list","summary":"List the agency's rasgos","description":"The traits (`content.features`) this agency already uses on catalog entries of one kind — what the Catalog's Traits field suggests. Reuse them rather than inventing near-duplicates.\n\n**Permissions:** `catalog:read`.","tags":["Catalog"],"x-scopes":["catalog:read"],"x-undo":"none","parameters":[{"name":"kind","in":"query","required":true,"schema":{"type":"string","enum":["destino","punto","alojamiento","actividad","servicio"]}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"object":{"type":"string","const":"catalog_features"},"kind":{"type":"string","enum":["destino","punto","alojamiento","actividad","servicio"]},"features":{"type":"array","items":{"type":"string"},"description":"The rasgos this agency already uses on entries of this kind — reuse them rather than inventing near-duplicates."}},"required":["object","kind","features"],"additionalProperties":false}}}},"default":{"description":"Error (RFC 9457)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/catalog/entities/{entityId}/images":{"post":{"operationId":"catalog.images.startUpload","summary":"Start a catalog photo upload","description":"Reserves a photo for a catalog entry and returns a single-use upload URL (valid 2 hours). Then PUT the image's bytes to `upload.url` with exactly `upload.headers` — no Authorization header — and call POST /catalog/entities/{entityId}/images/{assetId}/complete to attach it. Up to 15 MB; PNG, JPEG, WebP, AVIF or GIF. bymundi stores its own re-encoded copy (WebP, at most 2000 px on the longest side, no EXIF).\n\n**Permissions:** `catalog:write`.","tags":["Catalog"],"x-scopes":["catalog:write"],"x-undo":"none","parameters":[{"name":"entityId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"$ref":"#/components/parameters/IdempotencyKey"}],"responses":{"201":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"object":{"type":"string","const":"catalog_image_upload"},"entityId":{"type":"string","format":"uuid"},"assetId":{"type":"string","format":"uuid"},"upload":{"type":"object","properties":{"method":{"type":"string","const":"PUT"},"url":{"type":"string","format":"uri","description":"Single-use: PUT the image's bytes here once."},"headers":{"type":"object","additionalProperties":{"type":"string"},"description":"Send exactly these headers with the PUT."},"expiresAt":{"type":"string"}},"required":["method","url","headers","expiresAt"],"additionalProperties":false}},"required":["object","entityId","assetId","upload"],"additionalProperties":false}}}},"default":{"description":"Error (RFC 9457)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"mimeType":{"type":"string","enum":["image/png","image/jpeg","image/webp","image/avif","image/gif"],"description":"The image's type — only these are accepted."},"byteSize":{"type":"integer","minimum":1,"maximum":15728640,"description":"The file's size in bytes (at most 15 MB)."}},"required":["mimeType","byteSize"],"additionalProperties":false}}}}}},"/catalog/entities/{entityId}/images/{assetId}/complete":{"post":{"operationId":"catalog.images.completeUpload","summary":"Complete a catalog photo upload","description":"Completes a photo upload after its bytes were PUT: bymundi re-encodes it and attaches it to the entry — last, or as the lead photo with `position: first`. Nothing uploaded yet is a 422 `upload_missing`; bytes that are not an image a 422 `not_an_image`; a second completion a 409 `already_complete`. Undo with POST /changes/{changeId}/revert: it takes the photo off the entry while nobody has changed its photos since.\n\n**Permissions:** `catalog:write`.\n\n**Undo:** the response carries `Bymundi-Change-Id`; `POST /changes/{changeId}/revert` undoes it.","tags":["Catalog"],"x-scopes":["catalog:write"],"x-undo":"change","parameters":[{"name":"entityId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"assetId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"$ref":"#/components/parameters/IdempotencyKey"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"object":{"type":"string","const":"catalog_entity"},"id":{"type":"string","format":"uuid"},"kind":{"type":"string","enum":["destino","punto","alojamiento","actividad","servicio"]},"name":{"type":"string"},"placeId":{"type":"string"},"cityKey":{"type":"string"},"externalId":{"type":"string"},"place":{"type":"object","additionalProperties":{}},"images":{"type":"array","items":{"type":"object","additionalProperties":{}}},"tags":{"type":"array","items":{"type":"string"}},"origin":{"type":"string","enum":["human","ai","api","import"]},"content":{"type":"object","additionalProperties":{}},"updatedAt":{"type":"string"},"deletedAt":{"type":["string","null"]}},"required":["object","id","kind","name","placeId","cityKey","externalId","place","images","tags","origin","content","updatedAt","deletedAt"],"additionalProperties":false}}}},"default":{"description":"Error (RFC 9457)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"alt":{"type":"string","maxLength":300,"description":"A description of the photo for screen readers (recommended)."},"position":{"type":"string","enum":["first","last"],"default":"last","description":"`first` makes it the entry's lead photo; `last` (the default) appends it."}},"required":[],"additionalProperties":false}}}}}},"/catalog/routes":{"get":{"operationId":"catalog.routes.list","summary":"List routes","description":"The agency's routes (Catalog → Routes), most recently changed first, paged by `nextCursor`. Filters: `q` (words in the title), `tipo`, `duracion`, `ritmo`, `structured`, `destinoId` (routes through that destination or zone), `throughPlaceId` (routes that stop at that place) and `updatedSince` (a polling trigger's watermark). Summaries only; GET /catalog/routes/{routeId} returns the stops.\n\n**Permissions:** `catalog:read`.","tags":["Catalog"],"x-scopes":["catalog:read"],"x-undo":"none","parameters":[{"name":"q","in":"query","required":false,"schema":{"type":"string","minLength":1,"maxLength":200}},{"name":"tipo","in":"query","required":false,"schema":{"type":"string","enum":["dia_entero","medio_dia","excursion","tematica","con_experiencias","llegada"]}},{"name":"duracion","in":"query","required":false,"schema":{"type":"string","enum":["medio_dia","dia_entero","dia_entero_largo"]}},{"name":"ritmo","in":"query","required":false,"schema":{"type":"string","enum":["relajado","equilibrado","intenso"]}},{"name":"structured","in":"query","required":false,"schema":{"anyOf":[{"type":"boolean"},{"type":"string","enum":["true","false"]}]}},{"name":"destinoId","in":"query","required":false,"schema":{"type":"string","format":"uuid"}},{"name":"throughPlaceId","in":"query","required":false,"schema":{"type":"string","format":"uuid"}},{"name":"updatedSince","in":"query","required":false,"schema":{"type":"string","format":"date-time"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":100,"default":25}},{"name":"cursor","in":"query","required":false,"schema":{"type":"string","minLength":1,"maxLength":500}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"object":{"type":"string","const":"list"},"data":{"type":"array","items":{"type":"object","properties":{"object":{"type":"string","const":"route_summary"},"id":{"type":"string","format":"uuid"},"title":{"type":"string"},"externalId":{"type":"string"},"tipo":{"anyOf":[{"type":"string","enum":["dia_entero","medio_dia","excursion","tematica","con_experiencias","llegada"]},{"type":"null"}]},"duracion":{"anyOf":[{"type":"string","enum":["medio_dia","dia_entero","dia_entero_largo"]},{"type":"null"}]},"structured":{"type":"boolean"},"destinos":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false}},"durationMin":{"anyOf":[{"type":"integer"},{"type":"null"}]},"updatedAt":{"type":"string"}},"required":["object","id","title","externalId","tipo","duracion","structured","destinos","durationMin","updatedAt"],"additionalProperties":false}},"nextCursor":{"type":["string","null"]}},"required":["object","data","nextCursor"],"additionalProperties":false}}}},"default":{"description":"Error (RFC 9457)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"post":{"operationId":"catalog.routes.create","summary":"Create a route","description":"Creates a route, as New route and its editor would. A route is a day's walk through catalog places: `stops` in order, each a catalog place (`punto`) or activity (`actividad`) by `placeId`, with its own visit minutes (`ownMinutes`, null = the place's) and the LEG that arrives at it from the previous stop (`mode`: walking | transit | driving | bicycling, `minutes`, `prose`). `intro` and `closing` are the texts before and after. `rules` are how the planner uses it (`structured: true` lets it propose the route as a whole day). Everything but `title` is optional (an empty route is not suggested to the planner until it has stops and `structured: true`). Undo with POST /changes/{changeId}/revert, while nobody has saved it since.\n\n**Permissions:** `catalog:write`.\n\n**Undo:** the response carries `Bymundi-Change-Id`; `POST /changes/{changeId}/revert` undoes it.","tags":["Catalog"],"x-scopes":["catalog:write"],"x-undo":"change","parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"responses":{"201":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"object":{"type":"string","const":"route"},"id":{"type":"string","format":"uuid"},"title":{"type":"string"},"externalId":{"type":"string"},"intro":{"type":"array","items":{"type":"object","additionalProperties":{}}},"stops":{"type":"array","items":{"type":"object","properties":{"placeId":{"type":"string"},"name":{"type":"string","description":"The place's name — or the stop's stored title when its place no longer resolves."},"placeMinutes":{"anyOf":[{"type":"integer"},{"type":"null"}],"description":"The place's own visit minutes; null when the place is gone."},"ownMinutes":{"anyOf":[{"type":"integer"},{"type":"null"}],"description":"This route's override for the stop; null = the place's."},"leg":{"anyOf":[{"type":"object","properties":{"mode":{"anyOf":[{"type":"string","enum":["walking","transit","driving","bicycling"]},{"type":"null"}]},"minutes":{"anyOf":[{"type":"integer"},{"type":"null"}]},"prose":{"type":"array","items":{"type":"object","additionalProperties":{}}},"source":{"type":"string","description":"Provenance: `source` (authored), `routes` (measured by Google), `manual` (typed)."},"stale":{"type":"boolean","description":"true: measured for a different previous stop — the minutes no longer describe this leg."}},"required":["mode","minutes","prose","source","stale"],"additionalProperties":false},{"type":"null"}],"description":"How you get here from the previous stop; null on the first stop, or when nothing is known."}},"required":["placeId","name","placeMinutes","ownMinutes","leg"],"additionalProperties":false}},"closing":{"type":"array","items":{"type":"object","additionalProperties":{}}},"rules":{"type":"object","properties":{"structured":{"type":"boolean"},"base":{"type":"string"},"tipo":{"anyOf":[{"type":"string","enum":["dia_entero","medio_dia","excursion","tematica","con_experiencias","llegada"]},{"type":"null"}]},"duracion":{"anyOf":[{"type":"string","enum":["medio_dia","dia_entero","dia_entero_largo"]},{"type":"null"}]},"ritmo":{"anyOf":[{"type":"string","enum":["relajado","equilibrado","intenso"]},{"type":"null"}]},"incompatibleDias":{"type":"array","items":{"type":"string","enum":["lunes","martes","miercoles","jueves","viernes","sabado","domingo"]}},"requiereReserva":{"type":"boolean"},"notasUso":{"type":"array","items":{"type":"string"}}},"required":["structured","base","tipo","duracion","ritmo","incompatibleDias","requiereReserva","notasUso"],"additionalProperties":false},"destinos":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false},"description":"Every destino the stops sit in (derived when the route is saved)."},"durationMin":{"anyOf":[{"type":"integer"},{"type":"null"}],"description":"The route's computed length in minutes; null while never computed."},"updatedAt":{"type":"string"}},"required":["object","id","title","externalId","intro","stops","closing","rules","destinos","durationMin","updatedAt"],"additionalProperties":false}}}},"default":{"description":"Error (RFC 9457)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"title":{"type":"string","minLength":1,"maxLength":200},"intro":{"anyOf":[{"type":"string","maxLength":10000},{"type":"array","items":{"type":"object","additionalProperties":{}},"maxItems":200}],"description":"The text before the first stop."},"closing":{"anyOf":[{"type":"string","maxLength":10000},{"type":"array","items":{"type":"object","additionalProperties":{}},"maxItems":200}],"description":"The text after the last stop."},"stops":{"type":"array","items":{"type":"object","properties":{"placeId":{"type":"string","format":"uuid","description":"A catalog place (`punto`) or activity (`actividad`), by id."},"ownMinutes":{"anyOf":[{"type":"integer","minimum":0,"maximum":1440},{"type":"null"}],"description":"This route's own visit minutes for the stop; null or absent = the place's own."},"leg":{"type":"object","properties":{"mode":{"anyOf":[{"type":"string","enum":["walking","transit","driving","bicycling"]},{"type":"null"}]},"minutes":{"anyOf":[{"type":"integer","minimum":0,"maximum":1440},{"type":"null"}],"description":"Travel minutes from the previous stop."},"prose":{"anyOf":[{"type":"string","maxLength":10000},{"type":"array","items":{"type":"object","additionalProperties":{}},"maxItems":200}],"description":"How to get here from the previous stop."}},"additionalProperties":false,"description":"How you get HERE from the previous stop (ignored on the first). Absent = keep the measured leg when the same pair was already on the route."}},"required":["placeId"],"additionalProperties":false},"maxItems":40,"description":"The whole stop list, in order. Absent = unchanged."},"rules":{"type":"object","properties":{"structured":{"type":"boolean","description":"true: the planner may propose it as a whole day (needs at least two stops)."},"base":{"type":"string","maxLength":200},"tipo":{"anyOf":[{"type":"string","enum":["dia_entero","medio_dia","excursion","tematica","con_experiencias","llegada"]},{"type":"null"}]},"duracion":{"anyOf":[{"type":"string","enum":["medio_dia","dia_entero","dia_entero_largo"]},{"type":"null"}]},"ritmo":{"anyOf":[{"type":"string","enum":["relajado","equilibrado","intenso"]},{"type":"null"}]},"incompatibleDias":{"type":"array","items":{"type":"string","enum":["lunes","martes","miercoles","jueves","viernes","sabado","domingo"]},"maxItems":7,"description":"Weekdays it cannot run."},"requiereReserva":{"type":"boolean"},"notasUso":{"type":"array","items":{"type":"string","maxLength":500},"maxItems":20}},"additionalProperties":false,"description":"The route's planning rules; only the fields sent change. `destinos` is derived from the stops."}},"required":["title"],"additionalProperties":false}}}}}},"/catalog/routes/{routeId}":{"get":{"operationId":"catalog.routes.get","summary":"Get a route","description":"Returns one route in full. A route is a day's walk through catalog places: `stops` in order, each a catalog place (`punto`) or activity (`actividad`) by `placeId`, with its own visit minutes (`ownMinutes`, null = the place's) and the LEG that arrives at it from the previous stop (`mode`: walking | transit | driving | bicycling, `minutes`, `prose`). `intro` and `closing` are the texts before and after. `rules` are how the planner uses it (`structured: true` lets it propose the route as a whole day). `destinos` and `durationMin` are derived when it is saved; a leg marked `stale` was measured for a different previous stop.\n\n**Permissions:** `catalog:read`.","tags":["Catalog"],"x-scopes":["catalog:read"],"x-undo":"none","parameters":[{"name":"routeId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"object":{"type":"string","const":"route"},"id":{"type":"string","format":"uuid"},"title":{"type":"string"},"externalId":{"type":"string"},"intro":{"type":"array","items":{"type":"object","additionalProperties":{}}},"stops":{"type":"array","items":{"type":"object","properties":{"placeId":{"type":"string"},"name":{"type":"string","description":"The place's name — or the stop's stored title when its place no longer resolves."},"placeMinutes":{"anyOf":[{"type":"integer"},{"type":"null"}],"description":"The place's own visit minutes; null when the place is gone."},"ownMinutes":{"anyOf":[{"type":"integer"},{"type":"null"}],"description":"This route's override for the stop; null = the place's."},"leg":{"anyOf":[{"type":"object","properties":{"mode":{"anyOf":[{"type":"string","enum":["walking","transit","driving","bicycling"]},{"type":"null"}]},"minutes":{"anyOf":[{"type":"integer"},{"type":"null"}]},"prose":{"type":"array","items":{"type":"object","additionalProperties":{}}},"source":{"type":"string","description":"Provenance: `source` (authored), `routes` (measured by Google), `manual` (typed)."},"stale":{"type":"boolean","description":"true: measured for a different previous stop — the minutes no longer describe this leg."}},"required":["mode","minutes","prose","source","stale"],"additionalProperties":false},{"type":"null"}],"description":"How you get here from the previous stop; null on the first stop, or when nothing is known."}},"required":["placeId","name","placeMinutes","ownMinutes","leg"],"additionalProperties":false}},"closing":{"type":"array","items":{"type":"object","additionalProperties":{}}},"rules":{"type":"object","properties":{"structured":{"type":"boolean"},"base":{"type":"string"},"tipo":{"anyOf":[{"type":"string","enum":["dia_entero","medio_dia","excursion","tematica","con_experiencias","llegada"]},{"type":"null"}]},"duracion":{"anyOf":[{"type":"string","enum":["medio_dia","dia_entero","dia_entero_largo"]},{"type":"null"}]},"ritmo":{"anyOf":[{"type":"string","enum":["relajado","equilibrado","intenso"]},{"type":"null"}]},"incompatibleDias":{"type":"array","items":{"type":"string","enum":["lunes","martes","miercoles","jueves","viernes","sabado","domingo"]}},"requiereReserva":{"type":"boolean"},"notasUso":{"type":"array","items":{"type":"string"}}},"required":["structured","base","tipo","duracion","ritmo","incompatibleDias","requiereReserva","notasUso"],"additionalProperties":false},"destinos":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false},"description":"Every destino the stops sit in (derived when the route is saved)."},"durationMin":{"anyOf":[{"type":"integer"},{"type":"null"}],"description":"The route's computed length in minutes; null while never computed."},"updatedAt":{"type":"string"}},"required":["object","id","title","externalId","intro","stops","closing","rules","destinos","durationMin","updatedAt"],"additionalProperties":false}}}},"default":{"description":"Error (RFC 9457)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"patch":{"operationId":"catalog.routes.update","summary":"Update a route","description":"Edits a route, as its editor's Save. A route is a day's walk through catalog places: `stops` in order, each a catalog place (`punto`) or activity (`actividad`) by `placeId`, with its own visit minutes (`ownMinutes`, null = the place's) and the LEG that arrives at it from the previous stop (`mode`: walking | transit | driving | bicycling, `minutes`, `prose`). `intro` and `closing` are the texts before and after. `rules` are how the planner uses it (`structured: true` lets it propose the route as a whole day). Send only the top-level fields that change; `stops` REPLACES the whole list (a pair of consecutive places that stays keeps its measured leg unless you send one). The route's `destinos` and duration are re-derived. Pass the `updatedAt` you read as `expectedUpdatedAt` to refuse a stale write with a 409 (without it, the version this call reads is the one checked). Undo with POST /changes/{changeId}/revert.\n\n**Permissions:** `catalog:write`.\n\n**Undo:** the response carries `Bymundi-Change-Id`; `POST /changes/{changeId}/revert` undoes it.","tags":["Catalog"],"x-scopes":["catalog:write"],"x-undo":"change","parameters":[{"name":"routeId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"$ref":"#/components/parameters/IdempotencyKey"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"object":{"type":"string","const":"route"},"id":{"type":"string","format":"uuid"},"title":{"type":"string"},"externalId":{"type":"string"},"intro":{"type":"array","items":{"type":"object","additionalProperties":{}}},"stops":{"type":"array","items":{"type":"object","properties":{"placeId":{"type":"string"},"name":{"type":"string","description":"The place's name — or the stop's stored title when its place no longer resolves."},"placeMinutes":{"anyOf":[{"type":"integer"},{"type":"null"}],"description":"The place's own visit minutes; null when the place is gone."},"ownMinutes":{"anyOf":[{"type":"integer"},{"type":"null"}],"description":"This route's override for the stop; null = the place's."},"leg":{"anyOf":[{"type":"object","properties":{"mode":{"anyOf":[{"type":"string","enum":["walking","transit","driving","bicycling"]},{"type":"null"}]},"minutes":{"anyOf":[{"type":"integer"},{"type":"null"}]},"prose":{"type":"array","items":{"type":"object","additionalProperties":{}}},"source":{"type":"string","description":"Provenance: `source` (authored), `routes` (measured by Google), `manual` (typed)."},"stale":{"type":"boolean","description":"true: measured for a different previous stop — the minutes no longer describe this leg."}},"required":["mode","minutes","prose","source","stale"],"additionalProperties":false},{"type":"null"}],"description":"How you get here from the previous stop; null on the first stop, or when nothing is known."}},"required":["placeId","name","placeMinutes","ownMinutes","leg"],"additionalProperties":false}},"closing":{"type":"array","items":{"type":"object","additionalProperties":{}}},"rules":{"type":"object","properties":{"structured":{"type":"boolean"},"base":{"type":"string"},"tipo":{"anyOf":[{"type":"string","enum":["dia_entero","medio_dia","excursion","tematica","con_experiencias","llegada"]},{"type":"null"}]},"duracion":{"anyOf":[{"type":"string","enum":["medio_dia","dia_entero","dia_entero_largo"]},{"type":"null"}]},"ritmo":{"anyOf":[{"type":"string","enum":["relajado","equilibrado","intenso"]},{"type":"null"}]},"incompatibleDias":{"type":"array","items":{"type":"string","enum":["lunes","martes","miercoles","jueves","viernes","sabado","domingo"]}},"requiereReserva":{"type":"boolean"},"notasUso":{"type":"array","items":{"type":"string"}}},"required":["structured","base","tipo","duracion","ritmo","incompatibleDias","requiereReserva","notasUso"],"additionalProperties":false},"destinos":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false},"description":"Every destino the stops sit in (derived when the route is saved)."},"durationMin":{"anyOf":[{"type":"integer"},{"type":"null"}],"description":"The route's computed length in minutes; null while never computed."},"updatedAt":{"type":"string"}},"required":["object","id","title","externalId","intro","stops","closing","rules","destinos","durationMin","updatedAt"],"additionalProperties":false}}}},"default":{"description":"Error (RFC 9457)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"title":{"type":"string","minLength":1,"maxLength":200},"intro":{"anyOf":[{"type":"string","maxLength":10000},{"type":"array","items":{"type":"object","additionalProperties":{}},"maxItems":200}],"description":"The text before the first stop."},"closing":{"anyOf":[{"type":"string","maxLength":10000},{"type":"array","items":{"type":"object","additionalProperties":{}},"maxItems":200}],"description":"The text after the last stop."},"stops":{"type":"array","items":{"type":"object","properties":{"placeId":{"type":"string","format":"uuid","description":"A catalog place (`punto`) or activity (`actividad`), by id."},"ownMinutes":{"anyOf":[{"type":"integer","minimum":0,"maximum":1440},{"type":"null"}],"description":"This route's own visit minutes for the stop; null or absent = the place's own."},"leg":{"type":"object","properties":{"mode":{"anyOf":[{"type":"string","enum":["walking","transit","driving","bicycling"]},{"type":"null"}]},"minutes":{"anyOf":[{"type":"integer","minimum":0,"maximum":1440},{"type":"null"}],"description":"Travel minutes from the previous stop."},"prose":{"anyOf":[{"type":"string","maxLength":10000},{"type":"array","items":{"type":"object","additionalProperties":{}},"maxItems":200}],"description":"How to get here from the previous stop."}},"additionalProperties":false,"description":"How you get HERE from the previous stop (ignored on the first). Absent = keep the measured leg when the same pair was already on the route."}},"required":["placeId"],"additionalProperties":false},"maxItems":40,"description":"The whole stop list, in order. Absent = unchanged."},"rules":{"type":"object","properties":{"structured":{"type":"boolean","description":"true: the planner may propose it as a whole day (needs at least two stops)."},"base":{"type":"string","maxLength":200},"tipo":{"anyOf":[{"type":"string","enum":["dia_entero","medio_dia","excursion","tematica","con_experiencias","llegada"]},{"type":"null"}]},"duracion":{"anyOf":[{"type":"string","enum":["medio_dia","dia_entero","dia_entero_largo"]},{"type":"null"}]},"ritmo":{"anyOf":[{"type":"string","enum":["relajado","equilibrado","intenso"]},{"type":"null"}]},"incompatibleDias":{"type":"array","items":{"type":"string","enum":["lunes","martes","miercoles","jueves","viernes","sabado","domingo"]},"maxItems":7,"description":"Weekdays it cannot run."},"requiereReserva":{"type":"boolean"},"notasUso":{"type":"array","items":{"type":"string","maxLength":500},"maxItems":20}},"additionalProperties":false,"description":"The route's planning rules; only the fields sent change. `destinos` is derived from the stops."},"expectedUpdatedAt":{"type":"string","format":"date-time"}},"required":[],"additionalProperties":false}}}}},"delete":{"operationId":"catalog.routes.delete","summary":"Delete a route","description":"Deletes a route, as its editor's Delete. Days already stamped from it in trips keep their content. Undo with POST /changes/{changeId}/revert: it re-creates the same route, with the same id.\n\n**Permissions:** `catalog:write`.\n\n**Undo:** the response carries `Bymundi-Change-Id`; `POST /changes/{changeId}/revert` undoes it.","tags":["Catalog"],"x-scopes":["catalog:write"],"x-undo":"change","parameters":[{"name":"routeId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"$ref":"#/components/parameters/IdempotencyKey"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"object":{"type":"string","const":"route"},"id":{"type":"string","format":"uuid"},"deleted":{"type":"boolean","const":true}},"required":["object","id","deleted"],"additionalProperties":false}}}},"default":{"description":"Error (RFC 9457)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/changes":{"get":{"operationId":"changes.list","summary":"List changes","description":"Lists the changes this key's owner made through the API, from any of their keys, REST or MCP, most recently updated first — limited to the areas this key can read. Every undoable write records one and returns its id in the `Bymundi-Change-Id` header. Filter by `tripId` (a quote's changes carry its trip), `status` and `thisKeyOnly=true`, and page with `nextCursor`. `updatedSince` also catches reverts.\n\n**Permissions:** any valid key.","tags":["Changes"],"x-scopes":[],"x-undo":"none","parameters":[{"name":"tripId","in":"query","required":false,"schema":{"type":"string","format":"uuid"}},{"name":"status","in":"query","required":false,"schema":{"type":"string","enum":["applying","applied","failed","reverting","reverted"]}},{"name":"updatedSince","in":"query","required":false,"schema":{"type":"string","format":"date-time"}},{"name":"thisKeyOnly","in":"query","required":false,"schema":{"anyOf":[{"type":"boolean"},{"type":"string","enum":["true","false"]}],"description":"Only the changes made with THIS key."}},{"name":"sort","in":"query","required":false,"schema":{"type":"string","enum":["updatedAt","-updatedAt","createdAt","-createdAt"],"default":"-updatedAt"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":100,"default":25}},{"name":"cursor","in":"query","required":false,"schema":{"type":"string","minLength":1,"maxLength":500}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"object":{"type":"string","const":"list"},"data":{"type":"array","items":{"type":"object","properties":{"object":{"type":"string","const":"change"},"id":{"type":"string","format":"uuid"},"operationId":{"type":"string"},"surface":{"type":"string","enum":["rest","mcp"]},"status":{"type":"string","enum":["applying","applied","failed","reverting","reverted"]},"tripIds":{"type":"array","items":{"type":"string"}},"credentialId":{"type":["string","null"]},"error":{"type":["string","null"]},"createdAt":{"type":"string"},"updatedAt":{"type":"string"},"revertedAt":{"type":["string","null"]}},"required":["object","id","operationId","surface","status","tripIds","credentialId","error","createdAt","updatedAt","revertedAt"],"additionalProperties":false}},"nextCursor":{"type":["string","null"]}},"required":["object","data","nextCursor"],"additionalProperties":false}}}},"default":{"description":"Error (RFC 9457)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/changes/{changeId}":{"get":{"operationId":"changes.get","summary":"Get a change","description":"Returns one change: the operation that made it, the trips it touched, and its status (applied, failed, reverting, reverted). `error` says why it failed or why a revert stopped.\n\n**Permissions:** any valid key.","tags":["Changes"],"x-scopes":[],"x-undo":"none","parameters":[{"name":"changeId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"object":{"type":"string","const":"change"},"id":{"type":"string","format":"uuid"},"operationId":{"type":"string"},"surface":{"type":"string","enum":["rest","mcp"]},"status":{"type":"string","enum":["applying","applied","failed","reverting","reverted"]},"tripIds":{"type":"array","items":{"type":"string"}},"credentialId":{"type":["string","null"]},"error":{"type":["string","null"]},"createdAt":{"type":"string"},"updatedAt":{"type":"string"},"revertedAt":{"type":["string","null"]}},"required":["object","id","operationId","surface","status","tripIds","credentialId","error","createdAt","updatedAt","revertedAt"],"additionalProperties":false}}}},"default":{"description":"Error (RFC 9457)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/changes/{changeId}/revert":{"post":{"operationId":"changes.revert","summary":"Undo a change","description":"Undoes a change, as Undo does, and needs the permissions of the operation that made it. It is conditional: if anything the change touched was edited since, it refuses with a 409 and changes nothing (the change stays `applied`). If a LATER step is refused, the change becomes `failed` and the error says `partial: true`. Only an `applied` change can be undone, and an undo cannot itself be undone: make the change again.\n\n**Permissions:** any valid key.","tags":["Changes"],"x-scopes":[],"x-undo":"none","parameters":[{"name":"changeId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"$ref":"#/components/parameters/IdempotencyKey"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"object":{"type":"string","const":"change"},"id":{"type":"string","format":"uuid"},"operationId":{"type":"string"},"surface":{"type":"string","enum":["rest","mcp"]},"status":{"type":"string","enum":["applying","applied","failed","reverting","reverted"]},"tripIds":{"type":"array","items":{"type":"string"}},"credentialId":{"type":["string","null"]},"error":{"type":["string","null"]},"createdAt":{"type":"string"},"updatedAt":{"type":"string"},"revertedAt":{"type":["string","null"]}},"required":["object","id","operationId","surface","status","tripIds","credentialId","error","createdAt","updatedAt","revertedAt"],"additionalProperties":false}}}},"default":{"description":"Error (RFC 9457)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{},"required":[],"additionalProperties":false}}}}}},"/quotes":{"get":{"operationId":"quotes.list","summary":"List quotes","description":"Lists the agency's quotes on live trips, most recently changed first. Filter by `tripId`, `status`, `updatedSince`, `acceptedSince` and up to 5 `metadata[key]=value` pairs, which must all match. For an 'accepted quote' polling trigger (n8n, Zapier), pass `status=accepted` and the last `acceptedAt` you saw as `acceptedSince`: a decision does not change `updatedAt`. Follow `nextCursor` until it is null.\n\n**Permissions:** `quotes:read`.","tags":["Quotes"],"x-scopes":["quotes:read"],"x-undo":"none","parameters":[{"name":"tripId","in":"query","required":false,"schema":{"type":"string","format":"uuid"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":100,"default":25}},{"name":"cursor","in":"query","required":false,"schema":{"type":"string","minLength":1,"maxLength":500}},{"name":"sort","in":"query","required":false,"schema":{"type":"string","enum":["updatedAt","-updatedAt","createdAt","-createdAt"],"default":"-updatedAt"}},{"name":"status","in":"query","required":false,"schema":{"type":"string","enum":["draft","sent","accepted","rejected","expired","superseded"]}},{"name":"updatedSince","in":"query","required":false,"schema":{"type":"string","format":"date-time"}},{"name":"acceptedSince","in":"query","required":false,"schema":{"type":"string","format":"date-time","description":"Only quotes accepted at or after this instant — the 'quote accepted' polling trigger."}},{"name":"metadata","in":"query","required":false,"schema":{"type":"object","additionalProperties":{"type":"string","maxLength":500},"propertyNames":{"pattern":"^[A-Za-z0-9_.-]{1,40}$"}},"style":"deepObject","explode":true}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"object":{"type":"string","const":"list"},"data":{"type":"array","items":{"type":"object","properties":{"object":{"type":"string","const":"quote"},"id":{"type":"string","format":"uuid"},"tripId":{"type":"string","format":"uuid"},"code":{"type":"string"},"name":{"type":"string"},"mode":{"type":"string","enum":["package","per_item"]},"status":{"type":"string","enum":["draft","sent","accepted","rejected","expired","superseded"]},"travelers":{"type":"integer"},"marginPct":{"type":"number"},"finalPriceOverride":{"anyOf":[{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},{"type":"null"}]},"validUntil":{"type":["string","null"]},"ctaUrl":{"type":["string","null"]},"templateId":{"type":["string","null"]},"packages":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false}},"lines":{"type":"array","items":{"anyOf":[{"type":"object","properties":{"kind":{"type":"string","const":"flight"},"id":{"type":"string"},"name":{"type":"string"},"packageId":{"type":["string","null"]},"replacesItemId":{"type":["string","null"]},"marginable":{"type":"boolean"},"bookingRef":{"type":"string"},"comments":{"type":"string"},"catalogRef":{"anyOf":[{"type":"object","properties":{"kind":{"type":"string"},"id":{"type":"string"}},"required":["kind","id"],"additionalProperties":false},{"type":"null"}]},"amount":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"pvp":{"anyOf":[{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},{"type":"null"}]},"role":{"type":"string","enum":["ida","interno","vuelta"]},"mode":{"type":"string","enum":["avion","tren","ferry","autobus","coche"]},"from":{"type":"string"},"to":{"type":"string"},"date":{"type":["string","null"]},"departTime":{"type":"string"},"arriveTime":{"type":"string"},"arriveDayOffset":{"type":"integer"},"stopovers":{"type":"array","items":{"type":"object","properties":{"place":{"type":"string"},"arriveTime":{"type":"string"},"departTime":{"type":"string"},"arriveDayOffset":{"type":"integer"},"flight":{"type":"object","properties":{"flightNo":{"type":"string"},"airline":{"type":"string"},"fromAirport":{"type":"string"},"toAirport":{"type":"string"}},"required":["flightNo","airline","fromAirport","toAirport"],"additionalProperties":false}},"required":["place","arriveTime","departTime","arriveDayOffset","flight"],"additionalProperties":false}},"flight":{"type":"object","properties":{"flightNo":{"type":"string"},"airline":{"type":"string"},"fromAirport":{"type":"string"},"toAirport":{"type":"string"}},"required":["flightNo","airline","fromAirport","toAirport"],"additionalProperties":false},"transferId":{"type":["string","null"]},"price":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"perPax":{"type":"boolean"},"pairedWithId":{"type":["string","null"]}},"required":["kind","id","name","packageId","replacesItemId","marginable","bookingRef","comments","catalogRef","amount","pvp","role","mode","from","to","date","departTime","arriveTime","arriveDayOffset","stopovers","flight","transferId","price","perPax","pairedWithId"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","const":"hotel"},"id":{"type":"string"},"name":{"type":"string"},"packageId":{"type":["string","null"]},"replacesItemId":{"type":["string","null"]},"marginable":{"type":"boolean"},"bookingRef":{"type":"string"},"comments":{"type":"string"},"catalogRef":{"anyOf":[{"type":"object","properties":{"kind":{"type":"string"},"id":{"type":"string"}},"required":["kind","id"],"additionalProperties":false},{"type":"null"}]},"amount":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"pvp":{"anyOf":[{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},{"type":"null"}]},"stopId":{"type":["string","null"]},"city":{"type":"string"},"nights":{"type":"integer"},"board":{"type":"string"},"rooms":{"type":"array","items":{"type":"object","properties":{"type":{"type":"string"},"qty":{"type":"integer"},"price":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"}},"required":["type","qty","price"],"additionalProperties":false}},"optionKind":{"type":"string","enum":["line","hotel"]},"place":{"type":"object","properties":{"placeId":{"type":"string"},"lat":{"type":["number","null"]},"lng":{"type":["number","null"]},"formattedAddress":{"type":"string"}},"required":["placeId","lat","lng","formattedAddress"],"additionalProperties":false}},"required":["kind","id","name","packageId","replacesItemId","marginable","bookingRef","comments","catalogRef","amount","pvp","stopId","city","nights","board","rooms","optionKind","place"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","const":"other"},"id":{"type":"string"},"name":{"type":"string"},"packageId":{"type":["string","null"]},"replacesItemId":{"type":["string","null"]},"marginable":{"type":"boolean"},"bookingRef":{"type":"string"},"comments":{"type":"string"},"catalogRef":{"anyOf":[{"type":"object","properties":{"kind":{"type":"string"},"id":{"type":"string"}},"required":["kind","id"],"additionalProperties":false},{"type":"null"}]},"amount":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"pvp":{"anyOf":[{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},{"type":"null"}]},"tag":{"anyOf":[{"type":"string","enum":["actividad","traslado","seguro"]},{"type":"null"}]},"qty":{"type":"number"},"price":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"perPax":{"type":"boolean"},"range":{"anyOf":[{"type":"object","properties":{"start":{"type":"object","properties":{"offset":{"type":"integer"},"time":{"type":"string"}},"required":["offset","time"],"additionalProperties":false},"end":{"type":"object","properties":{"offset":{"type":"integer"},"time":{"type":"string"}},"required":["offset","time"],"additionalProperties":false}},"required":["start","end"],"additionalProperties":false},{"type":"null"}]},"place":{"type":"object","properties":{"placeId":{"type":"string"},"lat":{"type":["number","null"]},"lng":{"type":["number","null"]},"formattedAddress":{"type":"string"}},"required":["placeId","lat","lng","formattedAddress"],"additionalProperties":false}},"required":["kind","id","name","packageId","replacesItemId","marginable","bookingRef","comments","catalogRef","amount","pvp","tag","qty","price","perPax","range","place"],"additionalProperties":false}]}},"totals":{"type":"object","properties":{"currency":{"type":"string","const":"EUR"},"net":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"marginAmount":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"total":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"finalPrice":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"perPax":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"finalMargin":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"packages":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"deltaNet":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"deltaPvp":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"lineIds":{"type":"array","items":{"type":"string"}}},"required":["id","name","deltaNet","deltaPvp","lineIds"],"additionalProperties":false}}},"required":["currency","net","marginAmount","total","finalPrice","perPax","finalMargin","packages"],"additionalProperties":false},"textOverrides":{"type":"object","additionalProperties":{"type":"string"}},"imageOverrides":{"type":"object","additionalProperties":{"type":"string"}},"sentAt":{"type":["string","null"]},"modifiedSinceSent":{"type":"boolean"},"acceptedAt":{"type":["string","null"]},"acceptedVia":{"anyOf":[{"type":"string","enum":["prospect_link","agent"]},{"type":"null"}]},"acceptedPackageId":{"type":["string","null"]},"acceptedLineIds":{"type":"array","items":{"type":"string"}},"acceptance":{"anyOf":[{"type":"object","properties":{"name":{"type":["string","null"]},"email":{"type":["string","null"]},"phone":{"type":["string","null"]},"message":{"type":["string","null"]}},"required":["name","email","phone","message"],"additionalProperties":false},{"type":"null"}],"description":"What the customer typed when accepting on the quote page — personal data: present only for a key holding `travelers:read`, only on quote reads (a write's response carries null; read the quote), and every such read is audited."},"engagement":{"type":"object","properties":{"views":{"type":"integer"},"uniqueSessions":{"type":"integer"},"activeSeconds":{"type":"integer"},"ctaClicks":{"type":"integer"},"maxScrollPct":{"type":"number"},"sectionsSeen":{"type":"integer"},"interactions":{"type":"integer"},"lastSeenAt":{"type":["string","null"]},"lastCtaAt":{"type":["string","null"]}},"required":["views","uniqueSessions","activeSeconds","ctaClicks","maxScrollPct","sectionsSeen","interactions","lastSeenAt","lastCtaAt"],"additionalProperties":false},"metadata":{"type":"object","additionalProperties":{"type":"string","maxLength":500},"propertyNames":{"pattern":"^[A-Za-z0-9_.-]{1,40}$"}},"appUrl":{"type":["string","null"]},"publicUrl":{"type":["string","null"]},"createdAt":{"type":"string"},"updatedAt":{"type":"string"}},"required":["object","id","tripId","code","name","mode","status","travelers","marginPct","finalPriceOverride","validUntil","ctaUrl","templateId","packages","lines","totals","textOverrides","imageOverrides","sentAt","modifiedSinceSent","acceptedAt","acceptedVia","acceptedPackageId","acceptedLineIds","acceptance","engagement","metadata","appUrl","publicUrl","createdAt","updatedAt"],"additionalProperties":false}},"nextCursor":{"type":["string","null"]}},"required":["object","data","nextCursor"],"additionalProperties":false}}}},"default":{"description":"Error (RFC 9457)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/trips/{tripId}/quotes":{"get":{"operationId":"quotes.listForTrip","summary":"List a trip's quotes","description":"Lists one trip's quotes, as the quote editor's tabs show them — the same filters as GET /quotes. Another agency's trip, an archived one and a catalog working copy are a 404.\n\n**Permissions:** `quotes:read`.","tags":["Quotes"],"x-scopes":["quotes:read"],"x-undo":"none","parameters":[{"name":"tripId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":100,"default":25}},{"name":"cursor","in":"query","required":false,"schema":{"type":"string","minLength":1,"maxLength":500}},{"name":"sort","in":"query","required":false,"schema":{"type":"string","enum":["updatedAt","-updatedAt","createdAt","-createdAt"],"default":"-updatedAt"}},{"name":"status","in":"query","required":false,"schema":{"type":"string","enum":["draft","sent","accepted","rejected","expired","superseded"]}},{"name":"updatedSince","in":"query","required":false,"schema":{"type":"string","format":"date-time"}},{"name":"acceptedSince","in":"query","required":false,"schema":{"type":"string","format":"date-time","description":"Only quotes accepted at or after this instant — the 'quote accepted' polling trigger."}},{"name":"metadata","in":"query","required":false,"schema":{"type":"object","additionalProperties":{"type":"string","maxLength":500},"propertyNames":{"pattern":"^[A-Za-z0-9_.-]{1,40}$"}},"style":"deepObject","explode":true}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"object":{"type":"string","const":"list"},"data":{"type":"array","items":{"type":"object","properties":{"object":{"type":"string","const":"quote"},"id":{"type":"string","format":"uuid"},"tripId":{"type":"string","format":"uuid"},"code":{"type":"string"},"name":{"type":"string"},"mode":{"type":"string","enum":["package","per_item"]},"status":{"type":"string","enum":["draft","sent","accepted","rejected","expired","superseded"]},"travelers":{"type":"integer"},"marginPct":{"type":"number"},"finalPriceOverride":{"anyOf":[{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},{"type":"null"}]},"validUntil":{"type":["string","null"]},"ctaUrl":{"type":["string","null"]},"templateId":{"type":["string","null"]},"packages":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false}},"lines":{"type":"array","items":{"anyOf":[{"type":"object","properties":{"kind":{"type":"string","const":"flight"},"id":{"type":"string"},"name":{"type":"string"},"packageId":{"type":["string","null"]},"replacesItemId":{"type":["string","null"]},"marginable":{"type":"boolean"},"bookingRef":{"type":"string"},"comments":{"type":"string"},"catalogRef":{"anyOf":[{"type":"object","properties":{"kind":{"type":"string"},"id":{"type":"string"}},"required":["kind","id"],"additionalProperties":false},{"type":"null"}]},"amount":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"pvp":{"anyOf":[{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},{"type":"null"}]},"role":{"type":"string","enum":["ida","interno","vuelta"]},"mode":{"type":"string","enum":["avion","tren","ferry","autobus","coche"]},"from":{"type":"string"},"to":{"type":"string"},"date":{"type":["string","null"]},"departTime":{"type":"string"},"arriveTime":{"type":"string"},"arriveDayOffset":{"type":"integer"},"stopovers":{"type":"array","items":{"type":"object","properties":{"place":{"type":"string"},"arriveTime":{"type":"string"},"departTime":{"type":"string"},"arriveDayOffset":{"type":"integer"},"flight":{"type":"object","properties":{"flightNo":{"type":"string"},"airline":{"type":"string"},"fromAirport":{"type":"string"},"toAirport":{"type":"string"}},"required":["flightNo","airline","fromAirport","toAirport"],"additionalProperties":false}},"required":["place","arriveTime","departTime","arriveDayOffset","flight"],"additionalProperties":false}},"flight":{"type":"object","properties":{"flightNo":{"type":"string"},"airline":{"type":"string"},"fromAirport":{"type":"string"},"toAirport":{"type":"string"}},"required":["flightNo","airline","fromAirport","toAirport"],"additionalProperties":false},"transferId":{"type":["string","null"]},"price":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"perPax":{"type":"boolean"},"pairedWithId":{"type":["string","null"]}},"required":["kind","id","name","packageId","replacesItemId","marginable","bookingRef","comments","catalogRef","amount","pvp","role","mode","from","to","date","departTime","arriveTime","arriveDayOffset","stopovers","flight","transferId","price","perPax","pairedWithId"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","const":"hotel"},"id":{"type":"string"},"name":{"type":"string"},"packageId":{"type":["string","null"]},"replacesItemId":{"type":["string","null"]},"marginable":{"type":"boolean"},"bookingRef":{"type":"string"},"comments":{"type":"string"},"catalogRef":{"anyOf":[{"type":"object","properties":{"kind":{"type":"string"},"id":{"type":"string"}},"required":["kind","id"],"additionalProperties":false},{"type":"null"}]},"amount":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"pvp":{"anyOf":[{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},{"type":"null"}]},"stopId":{"type":["string","null"]},"city":{"type":"string"},"nights":{"type":"integer"},"board":{"type":"string"},"rooms":{"type":"array","items":{"type":"object","properties":{"type":{"type":"string"},"qty":{"type":"integer"},"price":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"}},"required":["type","qty","price"],"additionalProperties":false}},"optionKind":{"type":"string","enum":["line","hotel"]},"place":{"type":"object","properties":{"placeId":{"type":"string"},"lat":{"type":["number","null"]},"lng":{"type":["number","null"]},"formattedAddress":{"type":"string"}},"required":["placeId","lat","lng","formattedAddress"],"additionalProperties":false}},"required":["kind","id","name","packageId","replacesItemId","marginable","bookingRef","comments","catalogRef","amount","pvp","stopId","city","nights","board","rooms","optionKind","place"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","const":"other"},"id":{"type":"string"},"name":{"type":"string"},"packageId":{"type":["string","null"]},"replacesItemId":{"type":["string","null"]},"marginable":{"type":"boolean"},"bookingRef":{"type":"string"},"comments":{"type":"string"},"catalogRef":{"anyOf":[{"type":"object","properties":{"kind":{"type":"string"},"id":{"type":"string"}},"required":["kind","id"],"additionalProperties":false},{"type":"null"}]},"amount":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"pvp":{"anyOf":[{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},{"type":"null"}]},"tag":{"anyOf":[{"type":"string","enum":["actividad","traslado","seguro"]},{"type":"null"}]},"qty":{"type":"number"},"price":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"perPax":{"type":"boolean"},"range":{"anyOf":[{"type":"object","properties":{"start":{"type":"object","properties":{"offset":{"type":"integer"},"time":{"type":"string"}},"required":["offset","time"],"additionalProperties":false},"end":{"type":"object","properties":{"offset":{"type":"integer"},"time":{"type":"string"}},"required":["offset","time"],"additionalProperties":false}},"required":["start","end"],"additionalProperties":false},{"type":"null"}]},"place":{"type":"object","properties":{"placeId":{"type":"string"},"lat":{"type":["number","null"]},"lng":{"type":["number","null"]},"formattedAddress":{"type":"string"}},"required":["placeId","lat","lng","formattedAddress"],"additionalProperties":false}},"required":["kind","id","name","packageId","replacesItemId","marginable","bookingRef","comments","catalogRef","amount","pvp","tag","qty","price","perPax","range","place"],"additionalProperties":false}]}},"totals":{"type":"object","properties":{"currency":{"type":"string","const":"EUR"},"net":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"marginAmount":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"total":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"finalPrice":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"perPax":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"finalMargin":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"packages":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"deltaNet":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"deltaPvp":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"lineIds":{"type":"array","items":{"type":"string"}}},"required":["id","name","deltaNet","deltaPvp","lineIds"],"additionalProperties":false}}},"required":["currency","net","marginAmount","total","finalPrice","perPax","finalMargin","packages"],"additionalProperties":false},"textOverrides":{"type":"object","additionalProperties":{"type":"string"}},"imageOverrides":{"type":"object","additionalProperties":{"type":"string"}},"sentAt":{"type":["string","null"]},"modifiedSinceSent":{"type":"boolean"},"acceptedAt":{"type":["string","null"]},"acceptedVia":{"anyOf":[{"type":"string","enum":["prospect_link","agent"]},{"type":"null"}]},"acceptedPackageId":{"type":["string","null"]},"acceptedLineIds":{"type":"array","items":{"type":"string"}},"acceptance":{"anyOf":[{"type":"object","properties":{"name":{"type":["string","null"]},"email":{"type":["string","null"]},"phone":{"type":["string","null"]},"message":{"type":["string","null"]}},"required":["name","email","phone","message"],"additionalProperties":false},{"type":"null"}],"description":"What the customer typed when accepting on the quote page — personal data: present only for a key holding `travelers:read`, only on quote reads (a write's response carries null; read the quote), and every such read is audited."},"engagement":{"type":"object","properties":{"views":{"type":"integer"},"uniqueSessions":{"type":"integer"},"activeSeconds":{"type":"integer"},"ctaClicks":{"type":"integer"},"maxScrollPct":{"type":"number"},"sectionsSeen":{"type":"integer"},"interactions":{"type":"integer"},"lastSeenAt":{"type":["string","null"]},"lastCtaAt":{"type":["string","null"]}},"required":["views","uniqueSessions","activeSeconds","ctaClicks","maxScrollPct","sectionsSeen","interactions","lastSeenAt","lastCtaAt"],"additionalProperties":false},"metadata":{"type":"object","additionalProperties":{"type":"string","maxLength":500},"propertyNames":{"pattern":"^[A-Za-z0-9_.-]{1,40}$"}},"appUrl":{"type":["string","null"]},"publicUrl":{"type":["string","null"]},"createdAt":{"type":"string"},"updatedAt":{"type":"string"}},"required":["object","id","tripId","code","name","mode","status","travelers","marginPct","finalPriceOverride","validUntil","ctaUrl","templateId","packages","lines","totals","textOverrides","imageOverrides","sentAt","modifiedSinceSent","acceptedAt","acceptedVia","acceptedPackageId","acceptedLineIds","acceptance","engagement","metadata","appUrl","publicUrl","createdAt","updatedAt"],"additionalProperties":false}},"nextCursor":{"type":["string","null"]}},"required":["object","data","nextCursor"],"additionalProperties":false}}}},"default":{"description":"Error (RFC 9457)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"post":{"operationId":"quotes.create","summary":"Create a quote","description":"Creates a draft quote on a trip, as the quote editor's + button does: seeded from the trip's design unless `seedFromDesign: false`, priced for the trip's headcount at the agency's default margin unless `marginPct` says otherwise. Add or price lines with POST /quotes/{quoteId}/lines. With `?dryRun=true`, returns a `quote_preview` of the seeded lines and writes nothing. Undo with POST /changes/{changeId}/revert while it is still an untouched draft.\n\n**Permissions:** `quotes:write`.\n\n**Undo:** the response carries `Bymundi-Change-Id`; `POST /changes/{changeId}/revert` undoes it.","tags":["Quotes"],"x-scopes":["quotes:write"],"x-undo":"change","parameters":[{"name":"tripId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"$ref":"#/components/parameters/DryRun"},{"$ref":"#/components/parameters/IdempotencyKey"}],"responses":{"201":{"description":"Success","content":{"application/json":{"schema":{"anyOf":[{"type":"object","properties":{"object":{"type":"string","const":"quote"},"id":{"type":"string","format":"uuid"},"tripId":{"type":"string","format":"uuid"},"code":{"type":"string"},"name":{"type":"string"},"mode":{"type":"string","enum":["package","per_item"]},"status":{"type":"string","enum":["draft","sent","accepted","rejected","expired","superseded"]},"travelers":{"type":"integer"},"marginPct":{"type":"number"},"finalPriceOverride":{"anyOf":[{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},{"type":"null"}]},"validUntil":{"type":["string","null"]},"ctaUrl":{"type":["string","null"]},"templateId":{"type":["string","null"]},"packages":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false}},"lines":{"type":"array","items":{"anyOf":[{"type":"object","properties":{"kind":{"type":"string","const":"flight"},"id":{"type":"string"},"name":{"type":"string"},"packageId":{"type":["string","null"]},"replacesItemId":{"type":["string","null"]},"marginable":{"type":"boolean"},"bookingRef":{"type":"string"},"comments":{"type":"string"},"catalogRef":{"anyOf":[{"type":"object","properties":{"kind":{"type":"string"},"id":{"type":"string"}},"required":["kind","id"],"additionalProperties":false},{"type":"null"}]},"amount":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"pvp":{"anyOf":[{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},{"type":"null"}]},"role":{"type":"string","enum":["ida","interno","vuelta"]},"mode":{"type":"string","enum":["avion","tren","ferry","autobus","coche"]},"from":{"type":"string"},"to":{"type":"string"},"date":{"type":["string","null"]},"departTime":{"type":"string"},"arriveTime":{"type":"string"},"arriveDayOffset":{"type":"integer"},"stopovers":{"type":"array","items":{"type":"object","properties":{"place":{"type":"string"},"arriveTime":{"type":"string"},"departTime":{"type":"string"},"arriveDayOffset":{"type":"integer"},"flight":{"type":"object","properties":{"flightNo":{"type":"string"},"airline":{"type":"string"},"fromAirport":{"type":"string"},"toAirport":{"type":"string"}},"required":["flightNo","airline","fromAirport","toAirport"],"additionalProperties":false}},"required":["place","arriveTime","departTime","arriveDayOffset","flight"],"additionalProperties":false}},"flight":{"type":"object","properties":{"flightNo":{"type":"string"},"airline":{"type":"string"},"fromAirport":{"type":"string"},"toAirport":{"type":"string"}},"required":["flightNo","airline","fromAirport","toAirport"],"additionalProperties":false},"transferId":{"type":["string","null"]},"price":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"perPax":{"type":"boolean"},"pairedWithId":{"type":["string","null"]}},"required":["kind","id","name","packageId","replacesItemId","marginable","bookingRef","comments","catalogRef","amount","pvp","role","mode","from","to","date","departTime","arriveTime","arriveDayOffset","stopovers","flight","transferId","price","perPax","pairedWithId"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","const":"hotel"},"id":{"type":"string"},"name":{"type":"string"},"packageId":{"type":["string","null"]},"replacesItemId":{"type":["string","null"]},"marginable":{"type":"boolean"},"bookingRef":{"type":"string"},"comments":{"type":"string"},"catalogRef":{"anyOf":[{"type":"object","properties":{"kind":{"type":"string"},"id":{"type":"string"}},"required":["kind","id"],"additionalProperties":false},{"type":"null"}]},"amount":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"pvp":{"anyOf":[{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},{"type":"null"}]},"stopId":{"type":["string","null"]},"city":{"type":"string"},"nights":{"type":"integer"},"board":{"type":"string"},"rooms":{"type":"array","items":{"type":"object","properties":{"type":{"type":"string"},"qty":{"type":"integer"},"price":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"}},"required":["type","qty","price"],"additionalProperties":false}},"optionKind":{"type":"string","enum":["line","hotel"]},"place":{"type":"object","properties":{"placeId":{"type":"string"},"lat":{"type":["number","null"]},"lng":{"type":["number","null"]},"formattedAddress":{"type":"string"}},"required":["placeId","lat","lng","formattedAddress"],"additionalProperties":false}},"required":["kind","id","name","packageId","replacesItemId","marginable","bookingRef","comments","catalogRef","amount","pvp","stopId","city","nights","board","rooms","optionKind","place"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","const":"other"},"id":{"type":"string"},"name":{"type":"string"},"packageId":{"type":["string","null"]},"replacesItemId":{"type":["string","null"]},"marginable":{"type":"boolean"},"bookingRef":{"type":"string"},"comments":{"type":"string"},"catalogRef":{"anyOf":[{"type":"object","properties":{"kind":{"type":"string"},"id":{"type":"string"}},"required":["kind","id"],"additionalProperties":false},{"type":"null"}]},"amount":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"pvp":{"anyOf":[{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},{"type":"null"}]},"tag":{"anyOf":[{"type":"string","enum":["actividad","traslado","seguro"]},{"type":"null"}]},"qty":{"type":"number"},"price":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"perPax":{"type":"boolean"},"range":{"anyOf":[{"type":"object","properties":{"start":{"type":"object","properties":{"offset":{"type":"integer"},"time":{"type":"string"}},"required":["offset","time"],"additionalProperties":false},"end":{"type":"object","properties":{"offset":{"type":"integer"},"time":{"type":"string"}},"required":["offset","time"],"additionalProperties":false}},"required":["start","end"],"additionalProperties":false},{"type":"null"}]},"place":{"type":"object","properties":{"placeId":{"type":"string"},"lat":{"type":["number","null"]},"lng":{"type":["number","null"]},"formattedAddress":{"type":"string"}},"required":["placeId","lat","lng","formattedAddress"],"additionalProperties":false}},"required":["kind","id","name","packageId","replacesItemId","marginable","bookingRef","comments","catalogRef","amount","pvp","tag","qty","price","perPax","range","place"],"additionalProperties":false}]}},"totals":{"type":"object","properties":{"currency":{"type":"string","const":"EUR"},"net":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"marginAmount":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"total":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"finalPrice":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"perPax":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"finalMargin":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"packages":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"deltaNet":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"deltaPvp":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"lineIds":{"type":"array","items":{"type":"string"}}},"required":["id","name","deltaNet","deltaPvp","lineIds"],"additionalProperties":false}}},"required":["currency","net","marginAmount","total","finalPrice","perPax","finalMargin","packages"],"additionalProperties":false},"textOverrides":{"type":"object","additionalProperties":{"type":"string"}},"imageOverrides":{"type":"object","additionalProperties":{"type":"string"}},"sentAt":{"type":["string","null"]},"modifiedSinceSent":{"type":"boolean"},"acceptedAt":{"type":["string","null"]},"acceptedVia":{"anyOf":[{"type":"string","enum":["prospect_link","agent"]},{"type":"null"}]},"acceptedPackageId":{"type":["string","null"]},"acceptedLineIds":{"type":"array","items":{"type":"string"}},"acceptance":{"anyOf":[{"type":"object","properties":{"name":{"type":["string","null"]},"email":{"type":["string","null"]},"phone":{"type":["string","null"]},"message":{"type":["string","null"]}},"required":["name","email","phone","message"],"additionalProperties":false},{"type":"null"}],"description":"What the customer typed when accepting on the quote page — personal data: present only for a key holding `travelers:read`, only on quote reads (a write's response carries null; read the quote), and every such read is audited."},"engagement":{"type":"object","properties":{"views":{"type":"integer"},"uniqueSessions":{"type":"integer"},"activeSeconds":{"type":"integer"},"ctaClicks":{"type":"integer"},"maxScrollPct":{"type":"number"},"sectionsSeen":{"type":"integer"},"interactions":{"type":"integer"},"lastSeenAt":{"type":["string","null"]},"lastCtaAt":{"type":["string","null"]}},"required":["views","uniqueSessions","activeSeconds","ctaClicks","maxScrollPct","sectionsSeen","interactions","lastSeenAt","lastCtaAt"],"additionalProperties":false},"metadata":{"type":"object","additionalProperties":{"type":"string","maxLength":500},"propertyNames":{"pattern":"^[A-Za-z0-9_.-]{1,40}$"}},"appUrl":{"type":["string","null"]},"publicUrl":{"type":["string","null"]},"createdAt":{"type":"string"},"updatedAt":{"type":"string"}},"required":["object","id","tripId","code","name","mode","status","travelers","marginPct","finalPriceOverride","validUntil","ctaUrl","templateId","packages","lines","totals","textOverrides","imageOverrides","sentAt","modifiedSinceSent","acceptedAt","acceptedVia","acceptedPackageId","acceptedLineIds","acceptance","engagement","metadata","appUrl","publicUrl","createdAt","updatedAt"],"additionalProperties":false},{"type":"object","properties":{"object":{"type":"string","const":"quote_preview"},"quoteId":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}]},"changes":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"from":{},"to":{}},"required":["field"],"additionalProperties":false}},"sync":{"anyOf":[{"type":"object","properties":{"added":{"type":"integer"},"updated":{"type":"integer"},"removed":{"type":"integer"}},"required":["added","updated","removed"],"additionalProperties":false},{"type":"null"}]},"packages":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false}},"lines":{"type":"array","items":{"anyOf":[{"type":"object","properties":{"kind":{"type":"string","const":"flight"},"id":{"type":"string"},"name":{"type":"string"},"packageId":{"type":["string","null"]},"replacesItemId":{"type":["string","null"]},"marginable":{"type":"boolean"},"bookingRef":{"type":"string"},"comments":{"type":"string"},"catalogRef":{"anyOf":[{"type":"object","properties":{"kind":{"type":"string"},"id":{"type":"string"}},"required":["kind","id"],"additionalProperties":false},{"type":"null"}]},"amount":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"pvp":{"anyOf":[{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},{"type":"null"}]},"role":{"type":"string","enum":["ida","interno","vuelta"]},"mode":{"type":"string","enum":["avion","tren","ferry","autobus","coche"]},"from":{"type":"string"},"to":{"type":"string"},"date":{"type":["string","null"]},"departTime":{"type":"string"},"arriveTime":{"type":"string"},"arriveDayOffset":{"type":"integer"},"stopovers":{"type":"array","items":{"type":"object","properties":{"place":{"type":"string"},"arriveTime":{"type":"string"},"departTime":{"type":"string"},"arriveDayOffset":{"type":"integer"},"flight":{"type":"object","properties":{"flightNo":{"type":"string"},"airline":{"type":"string"},"fromAirport":{"type":"string"},"toAirport":{"type":"string"}},"required":["flightNo","airline","fromAirport","toAirport"],"additionalProperties":false}},"required":["place","arriveTime","departTime","arriveDayOffset","flight"],"additionalProperties":false}},"flight":{"type":"object","properties":{"flightNo":{"type":"string"},"airline":{"type":"string"},"fromAirport":{"type":"string"},"toAirport":{"type":"string"}},"required":["flightNo","airline","fromAirport","toAirport"],"additionalProperties":false},"transferId":{"type":["string","null"]},"price":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"perPax":{"type":"boolean"},"pairedWithId":{"type":["string","null"]}},"required":["kind","id","name","packageId","replacesItemId","marginable","bookingRef","comments","catalogRef","amount","pvp","role","mode","from","to","date","departTime","arriveTime","arriveDayOffset","stopovers","flight","transferId","price","perPax","pairedWithId"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","const":"hotel"},"id":{"type":"string"},"name":{"type":"string"},"packageId":{"type":["string","null"]},"replacesItemId":{"type":["string","null"]},"marginable":{"type":"boolean"},"bookingRef":{"type":"string"},"comments":{"type":"string"},"catalogRef":{"anyOf":[{"type":"object","properties":{"kind":{"type":"string"},"id":{"type":"string"}},"required":["kind","id"],"additionalProperties":false},{"type":"null"}]},"amount":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"pvp":{"anyOf":[{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},{"type":"null"}]},"stopId":{"type":["string","null"]},"city":{"type":"string"},"nights":{"type":"integer"},"board":{"type":"string"},"rooms":{"type":"array","items":{"type":"object","properties":{"type":{"type":"string"},"qty":{"type":"integer"},"price":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"}},"required":["type","qty","price"],"additionalProperties":false}},"optionKind":{"type":"string","enum":["line","hotel"]},"place":{"type":"object","properties":{"placeId":{"type":"string"},"lat":{"type":["number","null"]},"lng":{"type":["number","null"]},"formattedAddress":{"type":"string"}},"required":["placeId","lat","lng","formattedAddress"],"additionalProperties":false}},"required":["kind","id","name","packageId","replacesItemId","marginable","bookingRef","comments","catalogRef","amount","pvp","stopId","city","nights","board","rooms","optionKind","place"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","const":"other"},"id":{"type":"string"},"name":{"type":"string"},"packageId":{"type":["string","null"]},"replacesItemId":{"type":["string","null"]},"marginable":{"type":"boolean"},"bookingRef":{"type":"string"},"comments":{"type":"string"},"catalogRef":{"anyOf":[{"type":"object","properties":{"kind":{"type":"string"},"id":{"type":"string"}},"required":["kind","id"],"additionalProperties":false},{"type":"null"}]},"amount":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"pvp":{"anyOf":[{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},{"type":"null"}]},"tag":{"anyOf":[{"type":"string","enum":["actividad","traslado","seguro"]},{"type":"null"}]},"qty":{"type":"number"},"price":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"perPax":{"type":"boolean"},"range":{"anyOf":[{"type":"object","properties":{"start":{"type":"object","properties":{"offset":{"type":"integer"},"time":{"type":"string"}},"required":["offset","time"],"additionalProperties":false},"end":{"type":"object","properties":{"offset":{"type":"integer"},"time":{"type":"string"}},"required":["offset","time"],"additionalProperties":false}},"required":["start","end"],"additionalProperties":false},{"type":"null"}]},"place":{"type":"object","properties":{"placeId":{"type":"string"},"lat":{"type":["number","null"]},"lng":{"type":["number","null"]},"formattedAddress":{"type":"string"}},"required":["placeId","lat","lng","formattedAddress"],"additionalProperties":false}},"required":["kind","id","name","packageId","replacesItemId","marginable","bookingRef","comments","catalogRef","amount","pvp","tag","qty","price","perPax","range","place"],"additionalProperties":false}]}},"totals":{"type":"object","properties":{"currency":{"type":"string","const":"EUR"},"net":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"marginAmount":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"total":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"finalPrice":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"perPax":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"finalMargin":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"packages":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"deltaNet":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"deltaPvp":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"lineIds":{"type":"array","items":{"type":"string"}}},"required":["id","name","deltaNet","deltaPvp","lineIds"],"additionalProperties":false}}},"required":["currency","net","marginAmount","total","finalPrice","perPax","finalMargin","packages"],"additionalProperties":false}},"required":["object","quoteId","changes","sync","packages","lines","totals"],"additionalProperties":false}]}}}},"default":{"description":"Error (RFC 9457)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":200,"description":"Defaults to `Propuesta N`, as the quote editor names them."},"mode":{"type":"string","enum":["package","per_item"],"default":"package","description":"`package`: one price, with up to 3 upgrade packages. `per_item`: a basket the customer picks lines from. Cannot change later."},"seedFromDesign":{"type":"boolean","default":true,"description":"Start with one line per journey and one hotel per stop of the trip's design, as the quote editor does."},"templateId":{"type":"string","format":"uuid"},"marginPct":{"type":"number","minimum":0,"maximum":99,"description":"Defaults to the agency's default margin."},"finalPriceOverride":{"type":"string","pattern":"^-?\\d{1,9}(\\.\\d{1,2})?$"},"validUntil":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$"},"ctaUrl":{"type":"string","maxLength":500},"metadata":{"type":"object","additionalProperties":{"anyOf":[{"type":"string","maxLength":500},{"type":"null"}]},"propertyNames":{"pattern":"^[A-Za-z0-9_.-]{1,40}$"}}},"required":[],"additionalProperties":false}}}}}},"/quotes/{quoteId}":{"get":{"operationId":"quotes.get","summary":"Get a quote","description":"Returns one quote with everything the quote editor shows: its mode (a package quote with upgrade packages, or a per_item basket), lines, packages, bill totals, status and decision, whether it changed since it was sent, the customer's engagement with the public page, the public link and your metadata. Money is a decimal string in `totals.currency`.\n\n**Permissions:** `quotes:read`.","tags":["Quotes"],"x-scopes":["quotes:read"],"x-undo":"none","parameters":[{"name":"quoteId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"object":{"type":"string","const":"quote"},"id":{"type":"string","format":"uuid"},"tripId":{"type":"string","format":"uuid"},"code":{"type":"string"},"name":{"type":"string"},"mode":{"type":"string","enum":["package","per_item"]},"status":{"type":"string","enum":["draft","sent","accepted","rejected","expired","superseded"]},"travelers":{"type":"integer"},"marginPct":{"type":"number"},"finalPriceOverride":{"anyOf":[{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},{"type":"null"}]},"validUntil":{"type":["string","null"]},"ctaUrl":{"type":["string","null"]},"templateId":{"type":["string","null"]},"packages":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false}},"lines":{"type":"array","items":{"anyOf":[{"type":"object","properties":{"kind":{"type":"string","const":"flight"},"id":{"type":"string"},"name":{"type":"string"},"packageId":{"type":["string","null"]},"replacesItemId":{"type":["string","null"]},"marginable":{"type":"boolean"},"bookingRef":{"type":"string"},"comments":{"type":"string"},"catalogRef":{"anyOf":[{"type":"object","properties":{"kind":{"type":"string"},"id":{"type":"string"}},"required":["kind","id"],"additionalProperties":false},{"type":"null"}]},"amount":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"pvp":{"anyOf":[{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},{"type":"null"}]},"role":{"type":"string","enum":["ida","interno","vuelta"]},"mode":{"type":"string","enum":["avion","tren","ferry","autobus","coche"]},"from":{"type":"string"},"to":{"type":"string"},"date":{"type":["string","null"]},"departTime":{"type":"string"},"arriveTime":{"type":"string"},"arriveDayOffset":{"type":"integer"},"stopovers":{"type":"array","items":{"type":"object","properties":{"place":{"type":"string"},"arriveTime":{"type":"string"},"departTime":{"type":"string"},"arriveDayOffset":{"type":"integer"},"flight":{"type":"object","properties":{"flightNo":{"type":"string"},"airline":{"type":"string"},"fromAirport":{"type":"string"},"toAirport":{"type":"string"}},"required":["flightNo","airline","fromAirport","toAirport"],"additionalProperties":false}},"required":["place","arriveTime","departTime","arriveDayOffset","flight"],"additionalProperties":false}},"flight":{"type":"object","properties":{"flightNo":{"type":"string"},"airline":{"type":"string"},"fromAirport":{"type":"string"},"toAirport":{"type":"string"}},"required":["flightNo","airline","fromAirport","toAirport"],"additionalProperties":false},"transferId":{"type":["string","null"]},"price":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"perPax":{"type":"boolean"},"pairedWithId":{"type":["string","null"]}},"required":["kind","id","name","packageId","replacesItemId","marginable","bookingRef","comments","catalogRef","amount","pvp","role","mode","from","to","date","departTime","arriveTime","arriveDayOffset","stopovers","flight","transferId","price","perPax","pairedWithId"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","const":"hotel"},"id":{"type":"string"},"name":{"type":"string"},"packageId":{"type":["string","null"]},"replacesItemId":{"type":["string","null"]},"marginable":{"type":"boolean"},"bookingRef":{"type":"string"},"comments":{"type":"string"},"catalogRef":{"anyOf":[{"type":"object","properties":{"kind":{"type":"string"},"id":{"type":"string"}},"required":["kind","id"],"additionalProperties":false},{"type":"null"}]},"amount":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"pvp":{"anyOf":[{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},{"type":"null"}]},"stopId":{"type":["string","null"]},"city":{"type":"string"},"nights":{"type":"integer"},"board":{"type":"string"},"rooms":{"type":"array","items":{"type":"object","properties":{"type":{"type":"string"},"qty":{"type":"integer"},"price":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"}},"required":["type","qty","price"],"additionalProperties":false}},"optionKind":{"type":"string","enum":["line","hotel"]},"place":{"type":"object","properties":{"placeId":{"type":"string"},"lat":{"type":["number","null"]},"lng":{"type":["number","null"]},"formattedAddress":{"type":"string"}},"required":["placeId","lat","lng","formattedAddress"],"additionalProperties":false}},"required":["kind","id","name","packageId","replacesItemId","marginable","bookingRef","comments","catalogRef","amount","pvp","stopId","city","nights","board","rooms","optionKind","place"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","const":"other"},"id":{"type":"string"},"name":{"type":"string"},"packageId":{"type":["string","null"]},"replacesItemId":{"type":["string","null"]},"marginable":{"type":"boolean"},"bookingRef":{"type":"string"},"comments":{"type":"string"},"catalogRef":{"anyOf":[{"type":"object","properties":{"kind":{"type":"string"},"id":{"type":"string"}},"required":["kind","id"],"additionalProperties":false},{"type":"null"}]},"amount":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"pvp":{"anyOf":[{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},{"type":"null"}]},"tag":{"anyOf":[{"type":"string","enum":["actividad","traslado","seguro"]},{"type":"null"}]},"qty":{"type":"number"},"price":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"perPax":{"type":"boolean"},"range":{"anyOf":[{"type":"object","properties":{"start":{"type":"object","properties":{"offset":{"type":"integer"},"time":{"type":"string"}},"required":["offset","time"],"additionalProperties":false},"end":{"type":"object","properties":{"offset":{"type":"integer"},"time":{"type":"string"}},"required":["offset","time"],"additionalProperties":false}},"required":["start","end"],"additionalProperties":false},{"type":"null"}]},"place":{"type":"object","properties":{"placeId":{"type":"string"},"lat":{"type":["number","null"]},"lng":{"type":["number","null"]},"formattedAddress":{"type":"string"}},"required":["placeId","lat","lng","formattedAddress"],"additionalProperties":false}},"required":["kind","id","name","packageId","replacesItemId","marginable","bookingRef","comments","catalogRef","amount","pvp","tag","qty","price","perPax","range","place"],"additionalProperties":false}]}},"totals":{"type":"object","properties":{"currency":{"type":"string","const":"EUR"},"net":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"marginAmount":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"total":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"finalPrice":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"perPax":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"finalMargin":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"packages":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"deltaNet":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"deltaPvp":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"lineIds":{"type":"array","items":{"type":"string"}}},"required":["id","name","deltaNet","deltaPvp","lineIds"],"additionalProperties":false}}},"required":["currency","net","marginAmount","total","finalPrice","perPax","finalMargin","packages"],"additionalProperties":false},"textOverrides":{"type":"object","additionalProperties":{"type":"string"}},"imageOverrides":{"type":"object","additionalProperties":{"type":"string"}},"sentAt":{"type":["string","null"]},"modifiedSinceSent":{"type":"boolean"},"acceptedAt":{"type":["string","null"]},"acceptedVia":{"anyOf":[{"type":"string","enum":["prospect_link","agent"]},{"type":"null"}]},"acceptedPackageId":{"type":["string","null"]},"acceptedLineIds":{"type":"array","items":{"type":"string"}},"acceptance":{"anyOf":[{"type":"object","properties":{"name":{"type":["string","null"]},"email":{"type":["string","null"]},"phone":{"type":["string","null"]},"message":{"type":["string","null"]}},"required":["name","email","phone","message"],"additionalProperties":false},{"type":"null"}],"description":"What the customer typed when accepting on the quote page — personal data: present only for a key holding `travelers:read`, only on quote reads (a write's response carries null; read the quote), and every such read is audited."},"engagement":{"type":"object","properties":{"views":{"type":"integer"},"uniqueSessions":{"type":"integer"},"activeSeconds":{"type":"integer"},"ctaClicks":{"type":"integer"},"maxScrollPct":{"type":"number"},"sectionsSeen":{"type":"integer"},"interactions":{"type":"integer"},"lastSeenAt":{"type":["string","null"]},"lastCtaAt":{"type":["string","null"]}},"required":["views","uniqueSessions","activeSeconds","ctaClicks","maxScrollPct","sectionsSeen","interactions","lastSeenAt","lastCtaAt"],"additionalProperties":false},"metadata":{"type":"object","additionalProperties":{"type":"string","maxLength":500},"propertyNames":{"pattern":"^[A-Za-z0-9_.-]{1,40}$"}},"appUrl":{"type":["string","null"]},"publicUrl":{"type":["string","null"]},"createdAt":{"type":"string"},"updatedAt":{"type":"string"}},"required":["object","id","tripId","code","name","mode","status","travelers","marginPct","finalPriceOverride","validUntil","ctaUrl","templateId","packages","lines","totals","textOverrides","imageOverrides","sentAt","modifiedSinceSent","acceptedAt","acceptedVia","acceptedPackageId","acceptedLineIds","acceptance","engagement","metadata","appUrl","publicUrl","createdAt","updatedAt"],"additionalProperties":false}}}},"default":{"description":"Error (RFC 9457)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"patch":{"operationId":"quotes.update","summary":"Update a quote","description":"Changes the quote's own fields, as the quote editor's header and copy editor do: name, travelers (must equal the trip's headcount), marginPct, finalPriceOverride, validUntil, ctaUrl, templateId, and the template's editable texts and images (`textOverrides`, `imageOverrides`: merged key by key, `null` restores the template's). `metadata` merges key by key. Lines have their own endpoint. Pass the `updatedAt` you read as `expectedUpdatedAt` to refuse a stale write with a 409. With `?dryRun=true`, returns a `quote_preview` with each field's from/to and the new totals.\n\n**Permissions:** `quotes:write`.\n\n**Undo:** the response carries `Bymundi-Change-Id`; `POST /changes/{changeId}/revert` undoes it.","tags":["Quotes"],"x-scopes":["quotes:write"],"x-undo":"change","parameters":[{"name":"quoteId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"$ref":"#/components/parameters/DryRun"},{"$ref":"#/components/parameters/IdempotencyKey"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"anyOf":[{"type":"object","properties":{"object":{"type":"string","const":"quote"},"id":{"type":"string","format":"uuid"},"tripId":{"type":"string","format":"uuid"},"code":{"type":"string"},"name":{"type":"string"},"mode":{"type":"string","enum":["package","per_item"]},"status":{"type":"string","enum":["draft","sent","accepted","rejected","expired","superseded"]},"travelers":{"type":"integer"},"marginPct":{"type":"number"},"finalPriceOverride":{"anyOf":[{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},{"type":"null"}]},"validUntil":{"type":["string","null"]},"ctaUrl":{"type":["string","null"]},"templateId":{"type":["string","null"]},"packages":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false}},"lines":{"type":"array","items":{"anyOf":[{"type":"object","properties":{"kind":{"type":"string","const":"flight"},"id":{"type":"string"},"name":{"type":"string"},"packageId":{"type":["string","null"]},"replacesItemId":{"type":["string","null"]},"marginable":{"type":"boolean"},"bookingRef":{"type":"string"},"comments":{"type":"string"},"catalogRef":{"anyOf":[{"type":"object","properties":{"kind":{"type":"string"},"id":{"type":"string"}},"required":["kind","id"],"additionalProperties":false},{"type":"null"}]},"amount":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"pvp":{"anyOf":[{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},{"type":"null"}]},"role":{"type":"string","enum":["ida","interno","vuelta"]},"mode":{"type":"string","enum":["avion","tren","ferry","autobus","coche"]},"from":{"type":"string"},"to":{"type":"string"},"date":{"type":["string","null"]},"departTime":{"type":"string"},"arriveTime":{"type":"string"},"arriveDayOffset":{"type":"integer"},"stopovers":{"type":"array","items":{"type":"object","properties":{"place":{"type":"string"},"arriveTime":{"type":"string"},"departTime":{"type":"string"},"arriveDayOffset":{"type":"integer"},"flight":{"type":"object","properties":{"flightNo":{"type":"string"},"airline":{"type":"string"},"fromAirport":{"type":"string"},"toAirport":{"type":"string"}},"required":["flightNo","airline","fromAirport","toAirport"],"additionalProperties":false}},"required":["place","arriveTime","departTime","arriveDayOffset","flight"],"additionalProperties":false}},"flight":{"type":"object","properties":{"flightNo":{"type":"string"},"airline":{"type":"string"},"fromAirport":{"type":"string"},"toAirport":{"type":"string"}},"required":["flightNo","airline","fromAirport","toAirport"],"additionalProperties":false},"transferId":{"type":["string","null"]},"price":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"perPax":{"type":"boolean"},"pairedWithId":{"type":["string","null"]}},"required":["kind","id","name","packageId","replacesItemId","marginable","bookingRef","comments","catalogRef","amount","pvp","role","mode","from","to","date","departTime","arriveTime","arriveDayOffset","stopovers","flight","transferId","price","perPax","pairedWithId"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","const":"hotel"},"id":{"type":"string"},"name":{"type":"string"},"packageId":{"type":["string","null"]},"replacesItemId":{"type":["string","null"]},"marginable":{"type":"boolean"},"bookingRef":{"type":"string"},"comments":{"type":"string"},"catalogRef":{"anyOf":[{"type":"object","properties":{"kind":{"type":"string"},"id":{"type":"string"}},"required":["kind","id"],"additionalProperties":false},{"type":"null"}]},"amount":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"pvp":{"anyOf":[{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},{"type":"null"}]},"stopId":{"type":["string","null"]},"city":{"type":"string"},"nights":{"type":"integer"},"board":{"type":"string"},"rooms":{"type":"array","items":{"type":"object","properties":{"type":{"type":"string"},"qty":{"type":"integer"},"price":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"}},"required":["type","qty","price"],"additionalProperties":false}},"optionKind":{"type":"string","enum":["line","hotel"]},"place":{"type":"object","properties":{"placeId":{"type":"string"},"lat":{"type":["number","null"]},"lng":{"type":["number","null"]},"formattedAddress":{"type":"string"}},"required":["placeId","lat","lng","formattedAddress"],"additionalProperties":false}},"required":["kind","id","name","packageId","replacesItemId","marginable","bookingRef","comments","catalogRef","amount","pvp","stopId","city","nights","board","rooms","optionKind","place"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","const":"other"},"id":{"type":"string"},"name":{"type":"string"},"packageId":{"type":["string","null"]},"replacesItemId":{"type":["string","null"]},"marginable":{"type":"boolean"},"bookingRef":{"type":"string"},"comments":{"type":"string"},"catalogRef":{"anyOf":[{"type":"object","properties":{"kind":{"type":"string"},"id":{"type":"string"}},"required":["kind","id"],"additionalProperties":false},{"type":"null"}]},"amount":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"pvp":{"anyOf":[{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},{"type":"null"}]},"tag":{"anyOf":[{"type":"string","enum":["actividad","traslado","seguro"]},{"type":"null"}]},"qty":{"type":"number"},"price":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"perPax":{"type":"boolean"},"range":{"anyOf":[{"type":"object","properties":{"start":{"type":"object","properties":{"offset":{"type":"integer"},"time":{"type":"string"}},"required":["offset","time"],"additionalProperties":false},"end":{"type":"object","properties":{"offset":{"type":"integer"},"time":{"type":"string"}},"required":["offset","time"],"additionalProperties":false}},"required":["start","end"],"additionalProperties":false},{"type":"null"}]},"place":{"type":"object","properties":{"placeId":{"type":"string"},"lat":{"type":["number","null"]},"lng":{"type":["number","null"]},"formattedAddress":{"type":"string"}},"required":["placeId","lat","lng","formattedAddress"],"additionalProperties":false}},"required":["kind","id","name","packageId","replacesItemId","marginable","bookingRef","comments","catalogRef","amount","pvp","tag","qty","price","perPax","range","place"],"additionalProperties":false}]}},"totals":{"type":"object","properties":{"currency":{"type":"string","const":"EUR"},"net":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"marginAmount":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"total":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"finalPrice":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"perPax":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"finalMargin":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"packages":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"deltaNet":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"deltaPvp":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"lineIds":{"type":"array","items":{"type":"string"}}},"required":["id","name","deltaNet","deltaPvp","lineIds"],"additionalProperties":false}}},"required":["currency","net","marginAmount","total","finalPrice","perPax","finalMargin","packages"],"additionalProperties":false},"textOverrides":{"type":"object","additionalProperties":{"type":"string"}},"imageOverrides":{"type":"object","additionalProperties":{"type":"string"}},"sentAt":{"type":["string","null"]},"modifiedSinceSent":{"type":"boolean"},"acceptedAt":{"type":["string","null"]},"acceptedVia":{"anyOf":[{"type":"string","enum":["prospect_link","agent"]},{"type":"null"}]},"acceptedPackageId":{"type":["string","null"]},"acceptedLineIds":{"type":"array","items":{"type":"string"}},"acceptance":{"anyOf":[{"type":"object","properties":{"name":{"type":["string","null"]},"email":{"type":["string","null"]},"phone":{"type":["string","null"]},"message":{"type":["string","null"]}},"required":["name","email","phone","message"],"additionalProperties":false},{"type":"null"}],"description":"What the customer typed when accepting on the quote page — personal data: present only for a key holding `travelers:read`, only on quote reads (a write's response carries null; read the quote), and every such read is audited."},"engagement":{"type":"object","properties":{"views":{"type":"integer"},"uniqueSessions":{"type":"integer"},"activeSeconds":{"type":"integer"},"ctaClicks":{"type":"integer"},"maxScrollPct":{"type":"number"},"sectionsSeen":{"type":"integer"},"interactions":{"type":"integer"},"lastSeenAt":{"type":["string","null"]},"lastCtaAt":{"type":["string","null"]}},"required":["views","uniqueSessions","activeSeconds","ctaClicks","maxScrollPct","sectionsSeen","interactions","lastSeenAt","lastCtaAt"],"additionalProperties":false},"metadata":{"type":"object","additionalProperties":{"type":"string","maxLength":500},"propertyNames":{"pattern":"^[A-Za-z0-9_.-]{1,40}$"}},"appUrl":{"type":["string","null"]},"publicUrl":{"type":["string","null"]},"createdAt":{"type":"string"},"updatedAt":{"type":"string"}},"required":["object","id","tripId","code","name","mode","status","travelers","marginPct","finalPriceOverride","validUntil","ctaUrl","templateId","packages","lines","totals","textOverrides","imageOverrides","sentAt","modifiedSinceSent","acceptedAt","acceptedVia","acceptedPackageId","acceptedLineIds","acceptance","engagement","metadata","appUrl","publicUrl","createdAt","updatedAt"],"additionalProperties":false},{"type":"object","properties":{"object":{"type":"string","const":"quote_preview"},"quoteId":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}]},"changes":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"from":{},"to":{}},"required":["field"],"additionalProperties":false}},"sync":{"anyOf":[{"type":"object","properties":{"added":{"type":"integer"},"updated":{"type":"integer"},"removed":{"type":"integer"}},"required":["added","updated","removed"],"additionalProperties":false},{"type":"null"}]},"packages":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false}},"lines":{"type":"array","items":{"anyOf":[{"type":"object","properties":{"kind":{"type":"string","const":"flight"},"id":{"type":"string"},"name":{"type":"string"},"packageId":{"type":["string","null"]},"replacesItemId":{"type":["string","null"]},"marginable":{"type":"boolean"},"bookingRef":{"type":"string"},"comments":{"type":"string"},"catalogRef":{"anyOf":[{"type":"object","properties":{"kind":{"type":"string"},"id":{"type":"string"}},"required":["kind","id"],"additionalProperties":false},{"type":"null"}]},"amount":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"pvp":{"anyOf":[{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},{"type":"null"}]},"role":{"type":"string","enum":["ida","interno","vuelta"]},"mode":{"type":"string","enum":["avion","tren","ferry","autobus","coche"]},"from":{"type":"string"},"to":{"type":"string"},"date":{"type":["string","null"]},"departTime":{"type":"string"},"arriveTime":{"type":"string"},"arriveDayOffset":{"type":"integer"},"stopovers":{"type":"array","items":{"type":"object","properties":{"place":{"type":"string"},"arriveTime":{"type":"string"},"departTime":{"type":"string"},"arriveDayOffset":{"type":"integer"},"flight":{"type":"object","properties":{"flightNo":{"type":"string"},"airline":{"type":"string"},"fromAirport":{"type":"string"},"toAirport":{"type":"string"}},"required":["flightNo","airline","fromAirport","toAirport"],"additionalProperties":false}},"required":["place","arriveTime","departTime","arriveDayOffset","flight"],"additionalProperties":false}},"flight":{"type":"object","properties":{"flightNo":{"type":"string"},"airline":{"type":"string"},"fromAirport":{"type":"string"},"toAirport":{"type":"string"}},"required":["flightNo","airline","fromAirport","toAirport"],"additionalProperties":false},"transferId":{"type":["string","null"]},"price":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"perPax":{"type":"boolean"},"pairedWithId":{"type":["string","null"]}},"required":["kind","id","name","packageId","replacesItemId","marginable","bookingRef","comments","catalogRef","amount","pvp","role","mode","from","to","date","departTime","arriveTime","arriveDayOffset","stopovers","flight","transferId","price","perPax","pairedWithId"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","const":"hotel"},"id":{"type":"string"},"name":{"type":"string"},"packageId":{"type":["string","null"]},"replacesItemId":{"type":["string","null"]},"marginable":{"type":"boolean"},"bookingRef":{"type":"string"},"comments":{"type":"string"},"catalogRef":{"anyOf":[{"type":"object","properties":{"kind":{"type":"string"},"id":{"type":"string"}},"required":["kind","id"],"additionalProperties":false},{"type":"null"}]},"amount":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"pvp":{"anyOf":[{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},{"type":"null"}]},"stopId":{"type":["string","null"]},"city":{"type":"string"},"nights":{"type":"integer"},"board":{"type":"string"},"rooms":{"type":"array","items":{"type":"object","properties":{"type":{"type":"string"},"qty":{"type":"integer"},"price":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"}},"required":["type","qty","price"],"additionalProperties":false}},"optionKind":{"type":"string","enum":["line","hotel"]},"place":{"type":"object","properties":{"placeId":{"type":"string"},"lat":{"type":["number","null"]},"lng":{"type":["number","null"]},"formattedAddress":{"type":"string"}},"required":["placeId","lat","lng","formattedAddress"],"additionalProperties":false}},"required":["kind","id","name","packageId","replacesItemId","marginable","bookingRef","comments","catalogRef","amount","pvp","stopId","city","nights","board","rooms","optionKind","place"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","const":"other"},"id":{"type":"string"},"name":{"type":"string"},"packageId":{"type":["string","null"]},"replacesItemId":{"type":["string","null"]},"marginable":{"type":"boolean"},"bookingRef":{"type":"string"},"comments":{"type":"string"},"catalogRef":{"anyOf":[{"type":"object","properties":{"kind":{"type":"string"},"id":{"type":"string"}},"required":["kind","id"],"additionalProperties":false},{"type":"null"}]},"amount":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"pvp":{"anyOf":[{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},{"type":"null"}]},"tag":{"anyOf":[{"type":"string","enum":["actividad","traslado","seguro"]},{"type":"null"}]},"qty":{"type":"number"},"price":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"perPax":{"type":"boolean"},"range":{"anyOf":[{"type":"object","properties":{"start":{"type":"object","properties":{"offset":{"type":"integer"},"time":{"type":"string"}},"required":["offset","time"],"additionalProperties":false},"end":{"type":"object","properties":{"offset":{"type":"integer"},"time":{"type":"string"}},"required":["offset","time"],"additionalProperties":false}},"required":["start","end"],"additionalProperties":false},{"type":"null"}]},"place":{"type":"object","properties":{"placeId":{"type":"string"},"lat":{"type":["number","null"]},"lng":{"type":["number","null"]},"formattedAddress":{"type":"string"}},"required":["placeId","lat","lng","formattedAddress"],"additionalProperties":false}},"required":["kind","id","name","packageId","replacesItemId","marginable","bookingRef","comments","catalogRef","amount","pvp","tag","qty","price","perPax","range","place"],"additionalProperties":false}]}},"totals":{"type":"object","properties":{"currency":{"type":"string","const":"EUR"},"net":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"marginAmount":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"total":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"finalPrice":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"perPax":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"finalMargin":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"packages":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"deltaNet":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"deltaPvp":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"lineIds":{"type":"array","items":{"type":"string"}}},"required":["id","name","deltaNet","deltaPvp","lineIds"],"additionalProperties":false}}},"required":["currency","net","marginAmount","total","finalPrice","perPax","finalMargin","packages"],"additionalProperties":false}},"required":["object","quoteId","changes","sync","packages","lines","totals"],"additionalProperties":false}]}}}},"default":{"description":"Error (RFC 9457)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":200},"travelers":{"type":"integer","minimum":1,"maximum":40,"description":"Must equal the trip's headcount."},"marginPct":{"type":"number","minimum":0,"maximum":99,"description":"A % of the SALE price."},"finalPriceOverride":{"anyOf":[{"type":"string","pattern":"^-?\\d{1,9}(\\.\\d{1,2})?$"},{"type":"null"}],"description":"The rounded price the customer is asked to pay; null = the computed total."},"validUntil":{"anyOf":[{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$"},{"type":"null"}]},"ctaUrl":{"anyOf":[{"type":"string","maxLength":500},{"type":"null"}],"description":"Where the public page's button leads (WhatsApp, email, a URL)."},"templateId":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"description":"A quote template; null = the agency's default."},"textOverrides":{"type":"object","additionalProperties":{"anyOf":[{"type":"string","maxLength":4000},{"type":"null"}]},"propertyNames":{"minLength":1,"maxLength":100},"description":"The template's editable texts, by key; null restores the template's text."},"imageOverrides":{"type":"object","additionalProperties":{"anyOf":[{"type":"string","maxLength":2000},{"type":"null"}]},"propertyNames":{"minLength":1,"maxLength":100},"description":"The template's editable images (URLs), by key; null restores the template's image."},"expectedUpdatedAt":{"type":"string","format":"date-time","description":"The quote's updatedAt as you read it; the write is refused (409) if the quote changed since."},"metadata":{"type":"object","additionalProperties":{"anyOf":[{"type":"string","maxLength":500},{"type":"null"}]},"propertyNames":{"pattern":"^[A-Za-z0-9_.-]{1,40}$"}}},"required":[],"additionalProperties":false}}}}},"delete":{"operationId":"quotes.delete","summary":"Delete a quote","description":"Deletes a quote and its public page, as the quote editor's Delete does. It cannot be undone, so `confirm` (a query parameter) must be the quote's exact name. The API refuses an accepted quote (`quote_sold`: reopen it first) and a quote with any payment (`quote_has_payments`).\n\n**Permissions:** `quotes:write`.","tags":["Quotes"],"x-scopes":["quotes:write"],"x-undo":"none","parameters":[{"name":"quoteId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"confirm","in":"query","required":true,"schema":{"type":"string","minLength":1,"maxLength":200,"description":"The quote's exact name."}},{"$ref":"#/components/parameters/IdempotencyKey"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"object":{"type":"string","const":"deleted_quote"},"id":{"type":"string","format":"uuid"},"tripId":{"type":"string","format":"uuid"},"name":{"type":"string"}},"required":["object","id","tripId","name"],"additionalProperties":false}}}},"default":{"description":"Error (RFC 9457)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/quote-templates":{"get":{"operationId":"quotes.templates.list","summary":"List quote templates","description":"Lists the agency's quote templates — what the public quote page looks like — in one page. `isDefault` marks the one a quote with `templateId: null` uses. Set a quote's template with PATCH /quotes/{quoteId}.\n\n**Permissions:** `quotes:read`.","tags":["Quote templates"],"x-scopes":["quotes:read"],"x-undo":"none","parameters":[],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"object":{"type":"string","const":"list"},"data":{"type":"array","items":{"type":"object","properties":{"object":{"type":"string","const":"quote_template"},"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"isDefault":{"type":"boolean"},"updatedAt":{"type":"string"}},"required":["object","id","name","isDefault","updatedAt"],"additionalProperties":false}},"nextCursor":{"type":["string","null"]}},"required":["object","data","nextCursor"],"additionalProperties":false}}}},"default":{"description":"Error (RFC 9457)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/quote-templates/{templateId}":{"get":{"operationId":"quotes.templates.get","summary":"Get a quote template","description":"Returns one quote template with its HTML (HTML, CSS and Liquid, as the agency wrote it). Editing templates is not in the API yet.\n\n**Permissions:** `quotes:read`.","tags":["Quote templates"],"x-scopes":["quotes:read"],"x-undo":"none","parameters":[{"name":"templateId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"object":{"type":"string","const":"quote_template"},"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"isDefault":{"type":"boolean"},"updatedAt":{"type":"string"},"html":{"type":"string"}},"required":["object","id","name","isDefault","updatedAt","html"],"additionalProperties":false}}}},"default":{"description":"Error (RFC 9457)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/quotes/{quoteId}/lines":{"post":{"operationId":"quotes.editLines","summary":"Edit a quote's lines and packages","description":"Applies up to 50 ops to a quote's lines and packages as ONE change: `add_line` (a flight/transport, hotel or other line; into a package with `packageId`, or as an upgrade replacing a base line with `replacesItemId`), `update_line`, `remove_line` (a base line's upgrades go with it), `add_package` (up to 3; package quotes only), `rename_package`, `remove_package` (only when no line uses it). A later op may refer to an earlier add by its `clientId`. Lines that follow the trip's design refuse edits to what the design owns (a linked transport's route, dates and times; a linked hotel's city): change the design, then POST /quotes/{quoteId}/sync-design. Money is a decimal string; only an 'other' line may be negative (a discount). If any op is refused, nothing is written. With `?dryRun=true`, returns a `quote_preview` of the resulting lines and totals.\n\n**Permissions:** `quotes:write`.\n\n**Undo:** the response carries `Bymundi-Change-Id`; `POST /changes/{changeId}/revert` undoes it.","tags":["Quotes"],"x-scopes":["quotes:write"],"x-undo":"change","parameters":[{"name":"quoteId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"$ref":"#/components/parameters/DryRun"},{"$ref":"#/components/parameters/IdempotencyKey"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"anyOf":[{"type":"object","properties":{"object":{"type":"string","const":"quote_edit"},"quote":{"type":"object","properties":{"object":{"type":"string","const":"quote"},"id":{"type":"string","format":"uuid"},"tripId":{"type":"string","format":"uuid"},"code":{"type":"string"},"name":{"type":"string"},"mode":{"type":"string","enum":["package","per_item"]},"status":{"type":"string","enum":["draft","sent","accepted","rejected","expired","superseded"]},"travelers":{"type":"integer"},"marginPct":{"type":"number"},"finalPriceOverride":{"anyOf":[{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},{"type":"null"}]},"validUntil":{"type":["string","null"]},"ctaUrl":{"type":["string","null"]},"templateId":{"type":["string","null"]},"packages":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false}},"lines":{"type":"array","items":{"anyOf":[{"type":"object","properties":{"kind":{"type":"string","const":"flight"},"id":{"type":"string"},"name":{"type":"string"},"packageId":{"type":["string","null"]},"replacesItemId":{"type":["string","null"]},"marginable":{"type":"boolean"},"bookingRef":{"type":"string"},"comments":{"type":"string"},"catalogRef":{"anyOf":[{"type":"object","properties":{"kind":{"type":"string"},"id":{"type":"string"}},"required":["kind","id"],"additionalProperties":false},{"type":"null"}]},"amount":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"pvp":{"anyOf":[{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},{"type":"null"}]},"role":{"type":"string","enum":["ida","interno","vuelta"]},"mode":{"type":"string","enum":["avion","tren","ferry","autobus","coche"]},"from":{"type":"string"},"to":{"type":"string"},"date":{"type":["string","null"]},"departTime":{"type":"string"},"arriveTime":{"type":"string"},"arriveDayOffset":{"type":"integer"},"stopovers":{"type":"array","items":{"type":"object","properties":{"place":{"type":"string"},"arriveTime":{"type":"string"},"departTime":{"type":"string"},"arriveDayOffset":{"type":"integer"},"flight":{"type":"object","properties":{"flightNo":{"type":"string"},"airline":{"type":"string"},"fromAirport":{"type":"string"},"toAirport":{"type":"string"}},"required":["flightNo","airline","fromAirport","toAirport"],"additionalProperties":false}},"required":["place","arriveTime","departTime","arriveDayOffset","flight"],"additionalProperties":false}},"flight":{"type":"object","properties":{"flightNo":{"type":"string"},"airline":{"type":"string"},"fromAirport":{"type":"string"},"toAirport":{"type":"string"}},"required":["flightNo","airline","fromAirport","toAirport"],"additionalProperties":false},"transferId":{"type":["string","null"]},"price":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"perPax":{"type":"boolean"},"pairedWithId":{"type":["string","null"]}},"required":["kind","id","name","packageId","replacesItemId","marginable","bookingRef","comments","catalogRef","amount","pvp","role","mode","from","to","date","departTime","arriveTime","arriveDayOffset","stopovers","flight","transferId","price","perPax","pairedWithId"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","const":"hotel"},"id":{"type":"string"},"name":{"type":"string"},"packageId":{"type":["string","null"]},"replacesItemId":{"type":["string","null"]},"marginable":{"type":"boolean"},"bookingRef":{"type":"string"},"comments":{"type":"string"},"catalogRef":{"anyOf":[{"type":"object","properties":{"kind":{"type":"string"},"id":{"type":"string"}},"required":["kind","id"],"additionalProperties":false},{"type":"null"}]},"amount":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"pvp":{"anyOf":[{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},{"type":"null"}]},"stopId":{"type":["string","null"]},"city":{"type":"string"},"nights":{"type":"integer"},"board":{"type":"string"},"rooms":{"type":"array","items":{"type":"object","properties":{"type":{"type":"string"},"qty":{"type":"integer"},"price":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"}},"required":["type","qty","price"],"additionalProperties":false}},"optionKind":{"type":"string","enum":["line","hotel"]},"place":{"type":"object","properties":{"placeId":{"type":"string"},"lat":{"type":["number","null"]},"lng":{"type":["number","null"]},"formattedAddress":{"type":"string"}},"required":["placeId","lat","lng","formattedAddress"],"additionalProperties":false}},"required":["kind","id","name","packageId","replacesItemId","marginable","bookingRef","comments","catalogRef","amount","pvp","stopId","city","nights","board","rooms","optionKind","place"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","const":"other"},"id":{"type":"string"},"name":{"type":"string"},"packageId":{"type":["string","null"]},"replacesItemId":{"type":["string","null"]},"marginable":{"type":"boolean"},"bookingRef":{"type":"string"},"comments":{"type":"string"},"catalogRef":{"anyOf":[{"type":"object","properties":{"kind":{"type":"string"},"id":{"type":"string"}},"required":["kind","id"],"additionalProperties":false},{"type":"null"}]},"amount":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"pvp":{"anyOf":[{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},{"type":"null"}]},"tag":{"anyOf":[{"type":"string","enum":["actividad","traslado","seguro"]},{"type":"null"}]},"qty":{"type":"number"},"price":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"perPax":{"type":"boolean"},"range":{"anyOf":[{"type":"object","properties":{"start":{"type":"object","properties":{"offset":{"type":"integer"},"time":{"type":"string"}},"required":["offset","time"],"additionalProperties":false},"end":{"type":"object","properties":{"offset":{"type":"integer"},"time":{"type":"string"}},"required":["offset","time"],"additionalProperties":false}},"required":["start","end"],"additionalProperties":false},{"type":"null"}]},"place":{"type":"object","properties":{"placeId":{"type":"string"},"lat":{"type":["number","null"]},"lng":{"type":["number","null"]},"formattedAddress":{"type":"string"}},"required":["placeId","lat","lng","formattedAddress"],"additionalProperties":false}},"required":["kind","id","name","packageId","replacesItemId","marginable","bookingRef","comments","catalogRef","amount","pvp","tag","qty","price","perPax","range","place"],"additionalProperties":false}]}},"totals":{"type":"object","properties":{"currency":{"type":"string","const":"EUR"},"net":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"marginAmount":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"total":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"finalPrice":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"perPax":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"finalMargin":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"packages":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"deltaNet":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"deltaPvp":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"lineIds":{"type":"array","items":{"type":"string"}}},"required":["id","name","deltaNet","deltaPvp","lineIds"],"additionalProperties":false}}},"required":["currency","net","marginAmount","total","finalPrice","perPax","finalMargin","packages"],"additionalProperties":false},"textOverrides":{"type":"object","additionalProperties":{"type":"string"}},"imageOverrides":{"type":"object","additionalProperties":{"type":"string"}},"sentAt":{"type":["string","null"]},"modifiedSinceSent":{"type":"boolean"},"acceptedAt":{"type":["string","null"]},"acceptedVia":{"anyOf":[{"type":"string","enum":["prospect_link","agent"]},{"type":"null"}]},"acceptedPackageId":{"type":["string","null"]},"acceptedLineIds":{"type":"array","items":{"type":"string"}},"acceptance":{"anyOf":[{"type":"object","properties":{"name":{"type":["string","null"]},"email":{"type":["string","null"]},"phone":{"type":["string","null"]},"message":{"type":["string","null"]}},"required":["name","email","phone","message"],"additionalProperties":false},{"type":"null"}],"description":"What the customer typed when accepting on the quote page — personal data: present only for a key holding `travelers:read`, only on quote reads (a write's response carries null; read the quote), and every such read is audited."},"engagement":{"type":"object","properties":{"views":{"type":"integer"},"uniqueSessions":{"type":"integer"},"activeSeconds":{"type":"integer"},"ctaClicks":{"type":"integer"},"maxScrollPct":{"type":"number"},"sectionsSeen":{"type":"integer"},"interactions":{"type":"integer"},"lastSeenAt":{"type":["string","null"]},"lastCtaAt":{"type":["string","null"]}},"required":["views","uniqueSessions","activeSeconds","ctaClicks","maxScrollPct","sectionsSeen","interactions","lastSeenAt","lastCtaAt"],"additionalProperties":false},"metadata":{"type":"object","additionalProperties":{"type":"string","maxLength":500},"propertyNames":{"pattern":"^[A-Za-z0-9_.-]{1,40}$"}},"appUrl":{"type":["string","null"]},"publicUrl":{"type":["string","null"]},"createdAt":{"type":"string"},"updatedAt":{"type":"string"}},"required":["object","id","tripId","code","name","mode","status","travelers","marginPct","finalPriceOverride","validUntil","ctaUrl","templateId","packages","lines","totals","textOverrides","imageOverrides","sentAt","modifiedSinceSent","acceptedAt","acceptedVia","acceptedPackageId","acceptedLineIds","acceptance","engagement","metadata","appUrl","publicUrl","createdAt","updatedAt"],"additionalProperties":false},"created":{"type":"array","items":{"type":"object","properties":{"clientId":{"type":["string","null"]},"id":{"type":"string"},"kind":{"type":"string","enum":["line","package"]}},"required":["clientId","id","kind"],"additionalProperties":false}},"removed":{"type":"array","items":{"type":"string"}}},"required":["object","quote","created","removed"],"additionalProperties":false},{"type":"object","properties":{"object":{"type":"string","const":"quote_preview"},"quoteId":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}]},"changes":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"from":{},"to":{}},"required":["field"],"additionalProperties":false}},"sync":{"anyOf":[{"type":"object","properties":{"added":{"type":"integer"},"updated":{"type":"integer"},"removed":{"type":"integer"}},"required":["added","updated","removed"],"additionalProperties":false},{"type":"null"}]},"packages":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false}},"lines":{"type":"array","items":{"anyOf":[{"type":"object","properties":{"kind":{"type":"string","const":"flight"},"id":{"type":"string"},"name":{"type":"string"},"packageId":{"type":["string","null"]},"replacesItemId":{"type":["string","null"]},"marginable":{"type":"boolean"},"bookingRef":{"type":"string"},"comments":{"type":"string"},"catalogRef":{"anyOf":[{"type":"object","properties":{"kind":{"type":"string"},"id":{"type":"string"}},"required":["kind","id"],"additionalProperties":false},{"type":"null"}]},"amount":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"pvp":{"anyOf":[{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},{"type":"null"}]},"role":{"type":"string","enum":["ida","interno","vuelta"]},"mode":{"type":"string","enum":["avion","tren","ferry","autobus","coche"]},"from":{"type":"string"},"to":{"type":"string"},"date":{"type":["string","null"]},"departTime":{"type":"string"},"arriveTime":{"type":"string"},"arriveDayOffset":{"type":"integer"},"stopovers":{"type":"array","items":{"type":"object","properties":{"place":{"type":"string"},"arriveTime":{"type":"string"},"departTime":{"type":"string"},"arriveDayOffset":{"type":"integer"},"flight":{"type":"object","properties":{"flightNo":{"type":"string"},"airline":{"type":"string"},"fromAirport":{"type":"string"},"toAirport":{"type":"string"}},"required":["flightNo","airline","fromAirport","toAirport"],"additionalProperties":false}},"required":["place","arriveTime","departTime","arriveDayOffset","flight"],"additionalProperties":false}},"flight":{"type":"object","properties":{"flightNo":{"type":"string"},"airline":{"type":"string"},"fromAirport":{"type":"string"},"toAirport":{"type":"string"}},"required":["flightNo","airline","fromAirport","toAirport"],"additionalProperties":false},"transferId":{"type":["string","null"]},"price":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"perPax":{"type":"boolean"},"pairedWithId":{"type":["string","null"]}},"required":["kind","id","name","packageId","replacesItemId","marginable","bookingRef","comments","catalogRef","amount","pvp","role","mode","from","to","date","departTime","arriveTime","arriveDayOffset","stopovers","flight","transferId","price","perPax","pairedWithId"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","const":"hotel"},"id":{"type":"string"},"name":{"type":"string"},"packageId":{"type":["string","null"]},"replacesItemId":{"type":["string","null"]},"marginable":{"type":"boolean"},"bookingRef":{"type":"string"},"comments":{"type":"string"},"catalogRef":{"anyOf":[{"type":"object","properties":{"kind":{"type":"string"},"id":{"type":"string"}},"required":["kind","id"],"additionalProperties":false},{"type":"null"}]},"amount":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"pvp":{"anyOf":[{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},{"type":"null"}]},"stopId":{"type":["string","null"]},"city":{"type":"string"},"nights":{"type":"integer"},"board":{"type":"string"},"rooms":{"type":"array","items":{"type":"object","properties":{"type":{"type":"string"},"qty":{"type":"integer"},"price":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"}},"required":["type","qty","price"],"additionalProperties":false}},"optionKind":{"type":"string","enum":["line","hotel"]},"place":{"type":"object","properties":{"placeId":{"type":"string"},"lat":{"type":["number","null"]},"lng":{"type":["number","null"]},"formattedAddress":{"type":"string"}},"required":["placeId","lat","lng","formattedAddress"],"additionalProperties":false}},"required":["kind","id","name","packageId","replacesItemId","marginable","bookingRef","comments","catalogRef","amount","pvp","stopId","city","nights","board","rooms","optionKind","place"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","const":"other"},"id":{"type":"string"},"name":{"type":"string"},"packageId":{"type":["string","null"]},"replacesItemId":{"type":["string","null"]},"marginable":{"type":"boolean"},"bookingRef":{"type":"string"},"comments":{"type":"string"},"catalogRef":{"anyOf":[{"type":"object","properties":{"kind":{"type":"string"},"id":{"type":"string"}},"required":["kind","id"],"additionalProperties":false},{"type":"null"}]},"amount":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"pvp":{"anyOf":[{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},{"type":"null"}]},"tag":{"anyOf":[{"type":"string","enum":["actividad","traslado","seguro"]},{"type":"null"}]},"qty":{"type":"number"},"price":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"perPax":{"type":"boolean"},"range":{"anyOf":[{"type":"object","properties":{"start":{"type":"object","properties":{"offset":{"type":"integer"},"time":{"type":"string"}},"required":["offset","time"],"additionalProperties":false},"end":{"type":"object","properties":{"offset":{"type":"integer"},"time":{"type":"string"}},"required":["offset","time"],"additionalProperties":false}},"required":["start","end"],"additionalProperties":false},{"type":"null"}]},"place":{"type":"object","properties":{"placeId":{"type":"string"},"lat":{"type":["number","null"]},"lng":{"type":["number","null"]},"formattedAddress":{"type":"string"}},"required":["placeId","lat","lng","formattedAddress"],"additionalProperties":false}},"required":["kind","id","name","packageId","replacesItemId","marginable","bookingRef","comments","catalogRef","amount","pvp","tag","qty","price","perPax","range","place"],"additionalProperties":false}]}},"totals":{"type":"object","properties":{"currency":{"type":"string","const":"EUR"},"net":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"marginAmount":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"total":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"finalPrice":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"perPax":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"finalMargin":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"packages":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"deltaNet":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"deltaPvp":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"lineIds":{"type":"array","items":{"type":"string"}}},"required":["id","name","deltaNet","deltaPvp","lineIds"],"additionalProperties":false}}},"required":["currency","net","marginAmount","total","finalPrice","perPax","finalMargin","packages"],"additionalProperties":false}},"required":["object","quoteId","changes","sync","packages","lines","totals"],"additionalProperties":false}]}}}},"default":{"description":"Error (RFC 9457)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"ops":{"type":"array","items":{"anyOf":[{"type":"object","properties":{"op":{"type":"string","const":"add_line"},"clientId":{"type":"string","pattern":"^[A-Za-z0-9_-]{1,40}$","description":"Your own name for what this op creates, so later ops in the same batch can refer to it."},"line":{"anyOf":[{"type":"object","properties":{"kind":{"type":"string","const":"flight"},"name":{"type":"string","maxLength":300},"bookingRef":{"type":"string","maxLength":100,"description":"The booking reference (localizador)."},"comments":{"type":"string","maxLength":4000},"marginable":{"type":"boolean","description":"Whether the quote's margin applies to this line (default true)."},"catalogRef":{"anyOf":[{"type":"object","properties":{"kind":{"type":"string","minLength":1,"maxLength":40},"id":{"type":"string","minLength":1,"maxLength":100}},"required":["kind","id"],"additionalProperties":false},{"type":"null"}]},"packageId":{"anyOf":[{"type":"string","minLength":1,"maxLength":64,"description":"A line or package id from get_quote, or the clientId an earlier op in this batch gave it."},{"type":"null"}],"description":"Put the line in an upgrade package (package quotes only)."},"replacesItemId":{"anyOf":[{"type":"string","minLength":1,"maxLength":64,"description":"A line or package id from get_quote, or the clientId an earlier op in this batch gave it."},{"type":"null"}],"description":"Make the line an upgrade of this base line, inside packageId. Same kind as the base."},"role":{"type":"string","enum":["ida","interno","vuelta"]},"mode":{"type":"string","enum":["avion","tren","ferry","autobus","coche"]},"from":{"type":"string","maxLength":200},"to":{"type":"string","maxLength":200},"date":{"anyOf":[{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$"},{"type":"null"}]},"departTime":{"type":"string","pattern":"^(?:[01]\\d|2[0-3]):[0-5]\\d$|^$"},"arriveTime":{"type":"string","pattern":"^(?:[01]\\d|2[0-3]):[0-5]\\d$|^$"},"arriveDayOffset":{"type":"integer","minimum":0,"maximum":14},"flight":{"type":"object","properties":{"flightNo":{"type":"string","maxLength":12},"airline":{"type":"string","maxLength":8},"fromAirport":{"type":"string","maxLength":8},"toAirport":{"type":"string","maxLength":8}},"additionalProperties":false},"price":{"type":"string","pattern":"^-?\\d{1,9}(\\.\\d{1,2})?$"},"perPax":{"type":"boolean"},"pairedWithId":{"anyOf":[{"type":"string","minLength":1,"maxLength":64,"description":"A line or package id from get_quote, or the clientId an earlier op in this batch gave it."},{"type":"null"}],"description":"On a return: the outbound flight line that carries the round-trip price."}},"required":["kind"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","const":"hotel"},"name":{"type":"string","maxLength":300},"bookingRef":{"type":"string","maxLength":100,"description":"The booking reference (localizador)."},"comments":{"type":"string","maxLength":4000},"marginable":{"type":"boolean","description":"Whether the quote's margin applies to this line (default true)."},"catalogRef":{"anyOf":[{"type":"object","properties":{"kind":{"type":"string","minLength":1,"maxLength":40},"id":{"type":"string","minLength":1,"maxLength":100}},"required":["kind","id"],"additionalProperties":false},{"type":"null"}]},"packageId":{"anyOf":[{"type":"string","minLength":1,"maxLength":64,"description":"A line or package id from get_quote, or the clientId an earlier op in this batch gave it."},{"type":"null"}],"description":"Put the line in an upgrade package (package quotes only)."},"replacesItemId":{"anyOf":[{"type":"string","minLength":1,"maxLength":64,"description":"A line or package id from get_quote, or the clientId an earlier op in this batch gave it."},{"type":"null"}],"description":"Make the line an upgrade of this base line, inside packageId. Same kind as the base."},"stopId":{"type":"string","minLength":1,"maxLength":64,"description":"A stop of the trip's design: the hotel takes the stop's city."},"city":{"type":"string","maxLength":200},"nights":{"type":"integer","minimum":0,"maximum":365},"board":{"type":"string","maxLength":200},"rooms":{"type":"array","items":{"type":"object","properties":{"type":{"type":"string","maxLength":200},"qty":{"type":"integer","minimum":1,"maximum":50},"price":{"type":"string","pattern":"^-?\\d{1,9}(\\.\\d{1,2})?$","description":"Per STAY, not per night."}},"required":["type","qty","price"],"additionalProperties":false},"minItems":1,"maxItems":20},"optionKind":{"type":"string","enum":["line","hotel"]},"place":{"type":"object","properties":{"placeId":{"type":"string","maxLength":300},"lat":{"anyOf":[{"type":"number","minimum":-90,"maximum":90},{"type":"null"}]},"lng":{"anyOf":[{"type":"number","minimum":-180,"maximum":180},{"type":"null"}]},"formattedAddress":{"type":"string","maxLength":500}},"required":["placeId","lat","lng","formattedAddress"],"additionalProperties":false}},"required":["kind"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","const":"other"},"name":{"type":"string","maxLength":300},"bookingRef":{"type":"string","maxLength":100,"description":"The booking reference (localizador)."},"comments":{"type":"string","maxLength":4000},"marginable":{"type":"boolean","description":"Whether the quote's margin applies to this line (default true)."},"catalogRef":{"anyOf":[{"type":"object","properties":{"kind":{"type":"string","minLength":1,"maxLength":40},"id":{"type":"string","minLength":1,"maxLength":100}},"required":["kind","id"],"additionalProperties":false},{"type":"null"}]},"packageId":{"anyOf":[{"type":"string","minLength":1,"maxLength":64,"description":"A line or package id from get_quote, or the clientId an earlier op in this batch gave it."},{"type":"null"}],"description":"Put the line in an upgrade package (package quotes only)."},"replacesItemId":{"anyOf":[{"type":"string","minLength":1,"maxLength":64,"description":"A line or package id from get_quote, or the clientId an earlier op in this batch gave it."},{"type":"null"}],"description":"Make the line an upgrade of this base line, inside packageId. Same kind as the base."},"tag":{"anyOf":[{"type":"string","enum":["actividad","traslado","seguro"]},{"type":"null"}]},"qty":{"type":"number","minimum":0,"maximum":10000},"price":{"type":"string","pattern":"^-?\\d{1,9}(\\.\\d{1,2})?$","description":"Unit price; negative for a discount."},"perPax":{"type":"boolean"},"range":{"anyOf":[{"type":"object","properties":{"start":{"type":"object","properties":{"offset":{"type":"integer","minimum":0,"maximum":365},"time":{"type":"string","pattern":"^(?:[01]\\d|2[0-3]):[0-5]\\d$|^$"}},"required":["offset","time"],"additionalProperties":false},"end":{"type":"object","properties":{"offset":{"type":"integer","minimum":0,"maximum":365},"time":{"type":"string","pattern":"^(?:[01]\\d|2[0-3]):[0-5]\\d$|^$"}},"required":["offset","time"],"additionalProperties":false}},"required":["start","end"],"additionalProperties":false},{"type":"null"}]},"place":{"type":"object","properties":{"placeId":{"type":"string","maxLength":300},"lat":{"anyOf":[{"type":"number","minimum":-90,"maximum":90},{"type":"null"}]},"lng":{"anyOf":[{"type":"number","minimum":-180,"maximum":180},{"type":"null"}]},"formattedAddress":{"type":"string","maxLength":500}},"required":["placeId","lat","lng","formattedAddress"],"additionalProperties":false}},"required":["kind"],"additionalProperties":false}]}},"required":["op","line"],"additionalProperties":false},{"type":"object","properties":{"op":{"type":"string","const":"update_line"},"id":{"type":"string","minLength":1,"maxLength":64,"description":"A line or package id from get_quote, or the clientId an earlier op in this batch gave it."},"set":{"type":"object","properties":{"name":{"type":"string","maxLength":300},"bookingRef":{"type":"string","maxLength":100,"description":"The booking reference (localizador)."},"comments":{"type":"string","maxLength":4000},"marginable":{"type":"boolean","description":"Whether the quote's margin applies to this line (default true)."},"catalogRef":{"anyOf":[{"type":"object","properties":{"kind":{"type":"string","minLength":1,"maxLength":40},"id":{"type":"string","minLength":1,"maxLength":100}},"required":["kind","id"],"additionalProperties":false},{"type":"null"}]},"role":{"type":"string","enum":["ida","interno","vuelta"]},"mode":{"type":"string","enum":["avion","tren","ferry","autobus","coche"]},"from":{"type":"string","maxLength":200},"to":{"type":"string","maxLength":200},"date":{"anyOf":[{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$"},{"type":"null"}]},"departTime":{"type":"string","pattern":"^(?:[01]\\d|2[0-3]):[0-5]\\d$|^$"},"arriveTime":{"type":"string","pattern":"^(?:[01]\\d|2[0-3]):[0-5]\\d$|^$"},"arriveDayOffset":{"type":"integer","minimum":0,"maximum":14},"flight":{"type":"object","properties":{"flightNo":{"type":"string","maxLength":12},"airline":{"type":"string","maxLength":8},"fromAirport":{"type":"string","maxLength":8},"toAirport":{"type":"string","maxLength":8}},"additionalProperties":false},"price":{"type":"string","pattern":"^-?\\d{1,9}(\\.\\d{1,2})?$","description":"Unit price; negative for a discount."},"perPax":{"type":"boolean"},"pairedWithId":{"anyOf":[{"type":"string","minLength":1,"maxLength":64,"description":"A line or package id from get_quote, or the clientId an earlier op in this batch gave it."},{"type":"null"}],"description":"On a return: the outbound flight line that carries the round-trip price."},"city":{"type":"string","maxLength":200},"nights":{"type":"integer","minimum":0,"maximum":365},"board":{"type":"string","maxLength":200},"rooms":{"type":"array","items":{"type":"object","properties":{"type":{"type":"string","maxLength":200},"qty":{"type":"integer","minimum":1,"maximum":50},"price":{"type":"string","pattern":"^-?\\d{1,9}(\\.\\d{1,2})?$","description":"Per STAY, not per night."}},"required":["type","qty","price"],"additionalProperties":false},"minItems":1,"maxItems":20},"optionKind":{"type":"string","enum":["line","hotel"]},"place":{"type":"object","properties":{"placeId":{"type":"string","maxLength":300},"lat":{"anyOf":[{"type":"number","minimum":-90,"maximum":90},{"type":"null"}]},"lng":{"anyOf":[{"type":"number","minimum":-180,"maximum":180},{"type":"null"}]},"formattedAddress":{"type":"string","maxLength":500}},"required":["placeId","lat","lng","formattedAddress"],"additionalProperties":false},"tag":{"anyOf":[{"type":"string","enum":["actividad","traslado","seguro"]},{"type":"null"}]},"qty":{"type":"number","minimum":0,"maximum":10000},"range":{"anyOf":[{"type":"object","properties":{"start":{"type":"object","properties":{"offset":{"type":"integer","minimum":0,"maximum":365},"time":{"type":"string","pattern":"^(?:[01]\\d|2[0-3]):[0-5]\\d$|^$"}},"required":["offset","time"],"additionalProperties":false},"end":{"type":"object","properties":{"offset":{"type":"integer","minimum":0,"maximum":365},"time":{"type":"string","pattern":"^(?:[01]\\d|2[0-3]):[0-5]\\d$|^$"}},"required":["offset","time"],"additionalProperties":false}},"required":["start","end"],"additionalProperties":false},{"type":"null"}]}},"additionalProperties":false}},"required":["op","id","set"],"additionalProperties":false},{"type":"object","properties":{"op":{"type":"string","const":"remove_line"},"id":{"type":"string","minLength":1,"maxLength":64,"description":"A line or package id from get_quote, or the clientId an earlier op in this batch gave it."}},"required":["op","id"],"additionalProperties":false},{"type":"object","properties":{"op":{"type":"string","const":"add_package"},"clientId":{"type":"string","pattern":"^[A-Za-z0-9_-]{1,40}$","description":"Your own name for what this op creates, so later ops in the same batch can refer to it."},"name":{"type":"string","minLength":1,"maxLength":60}},"required":["op"],"additionalProperties":false},{"type":"object","properties":{"op":{"type":"string","const":"rename_package"},"id":{"type":"string","minLength":1,"maxLength":64,"description":"A line or package id from get_quote, or the clientId an earlier op in this batch gave it."},"name":{"type":"string","minLength":1,"maxLength":60}},"required":["op","id","name"],"additionalProperties":false},{"type":"object","properties":{"op":{"type":"string","const":"remove_package"},"id":{"type":"string","minLength":1,"maxLength":64,"description":"A line or package id from get_quote, or the clientId an earlier op in this batch gave it."}},"required":["op","id"],"additionalProperties":false}]},"minItems":1,"maxItems":50},"expectedUpdatedAt":{"type":"string","format":"date-time","description":"The quote's updatedAt as you read it; the write is refused (409) if the quote changed since."}},"required":["ops"],"additionalProperties":false}}}}}},"/quotes/{quoteId}/sync-design":{"post":{"operationId":"quotes.syncDesign","summary":"Sync a quote with the trip's design","description":"Does what the quote editor's Sync does: adds a priced line for each new journey and a hotel for each new stop of the trip's design, updates what the design owns on linked lines (routes, dates, times, cities, nights), and removes linked lines whose journey or stop is gone — only if nobody priced or edited them. Returns the counts. A trip with no design is a 422. With `?dryRun=true`, returns a `quote_preview` with the counts and the resulting lines.\n\n**Permissions:** `quotes:write`.\n\n**Undo:** the response carries `Bymundi-Change-Id`; `POST /changes/{changeId}/revert` undoes it.","tags":["Quotes"],"x-scopes":["quotes:write"],"x-undo":"change","parameters":[{"name":"quoteId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"$ref":"#/components/parameters/DryRun"},{"$ref":"#/components/parameters/IdempotencyKey"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"anyOf":[{"type":"object","properties":{"object":{"type":"string","const":"quote_sync"},"quote":{"type":"object","properties":{"object":{"type":"string","const":"quote"},"id":{"type":"string","format":"uuid"},"tripId":{"type":"string","format":"uuid"},"code":{"type":"string"},"name":{"type":"string"},"mode":{"type":"string","enum":["package","per_item"]},"status":{"type":"string","enum":["draft","sent","accepted","rejected","expired","superseded"]},"travelers":{"type":"integer"},"marginPct":{"type":"number"},"finalPriceOverride":{"anyOf":[{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},{"type":"null"}]},"validUntil":{"type":["string","null"]},"ctaUrl":{"type":["string","null"]},"templateId":{"type":["string","null"]},"packages":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false}},"lines":{"type":"array","items":{"anyOf":[{"type":"object","properties":{"kind":{"type":"string","const":"flight"},"id":{"type":"string"},"name":{"type":"string"},"packageId":{"type":["string","null"]},"replacesItemId":{"type":["string","null"]},"marginable":{"type":"boolean"},"bookingRef":{"type":"string"},"comments":{"type":"string"},"catalogRef":{"anyOf":[{"type":"object","properties":{"kind":{"type":"string"},"id":{"type":"string"}},"required":["kind","id"],"additionalProperties":false},{"type":"null"}]},"amount":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"pvp":{"anyOf":[{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},{"type":"null"}]},"role":{"type":"string","enum":["ida","interno","vuelta"]},"mode":{"type":"string","enum":["avion","tren","ferry","autobus","coche"]},"from":{"type":"string"},"to":{"type":"string"},"date":{"type":["string","null"]},"departTime":{"type":"string"},"arriveTime":{"type":"string"},"arriveDayOffset":{"type":"integer"},"stopovers":{"type":"array","items":{"type":"object","properties":{"place":{"type":"string"},"arriveTime":{"type":"string"},"departTime":{"type":"string"},"arriveDayOffset":{"type":"integer"},"flight":{"type":"object","properties":{"flightNo":{"type":"string"},"airline":{"type":"string"},"fromAirport":{"type":"string"},"toAirport":{"type":"string"}},"required":["flightNo","airline","fromAirport","toAirport"],"additionalProperties":false}},"required":["place","arriveTime","departTime","arriveDayOffset","flight"],"additionalProperties":false}},"flight":{"type":"object","properties":{"flightNo":{"type":"string"},"airline":{"type":"string"},"fromAirport":{"type":"string"},"toAirport":{"type":"string"}},"required":["flightNo","airline","fromAirport","toAirport"],"additionalProperties":false},"transferId":{"type":["string","null"]},"price":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"perPax":{"type":"boolean"},"pairedWithId":{"type":["string","null"]}},"required":["kind","id","name","packageId","replacesItemId","marginable","bookingRef","comments","catalogRef","amount","pvp","role","mode","from","to","date","departTime","arriveTime","arriveDayOffset","stopovers","flight","transferId","price","perPax","pairedWithId"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","const":"hotel"},"id":{"type":"string"},"name":{"type":"string"},"packageId":{"type":["string","null"]},"replacesItemId":{"type":["string","null"]},"marginable":{"type":"boolean"},"bookingRef":{"type":"string"},"comments":{"type":"string"},"catalogRef":{"anyOf":[{"type":"object","properties":{"kind":{"type":"string"},"id":{"type":"string"}},"required":["kind","id"],"additionalProperties":false},{"type":"null"}]},"amount":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"pvp":{"anyOf":[{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},{"type":"null"}]},"stopId":{"type":["string","null"]},"city":{"type":"string"},"nights":{"type":"integer"},"board":{"type":"string"},"rooms":{"type":"array","items":{"type":"object","properties":{"type":{"type":"string"},"qty":{"type":"integer"},"price":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"}},"required":["type","qty","price"],"additionalProperties":false}},"optionKind":{"type":"string","enum":["line","hotel"]},"place":{"type":"object","properties":{"placeId":{"type":"string"},"lat":{"type":["number","null"]},"lng":{"type":["number","null"]},"formattedAddress":{"type":"string"}},"required":["placeId","lat","lng","formattedAddress"],"additionalProperties":false}},"required":["kind","id","name","packageId","replacesItemId","marginable","bookingRef","comments","catalogRef","amount","pvp","stopId","city","nights","board","rooms","optionKind","place"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","const":"other"},"id":{"type":"string"},"name":{"type":"string"},"packageId":{"type":["string","null"]},"replacesItemId":{"type":["string","null"]},"marginable":{"type":"boolean"},"bookingRef":{"type":"string"},"comments":{"type":"string"},"catalogRef":{"anyOf":[{"type":"object","properties":{"kind":{"type":"string"},"id":{"type":"string"}},"required":["kind","id"],"additionalProperties":false},{"type":"null"}]},"amount":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"pvp":{"anyOf":[{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},{"type":"null"}]},"tag":{"anyOf":[{"type":"string","enum":["actividad","traslado","seguro"]},{"type":"null"}]},"qty":{"type":"number"},"price":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"perPax":{"type":"boolean"},"range":{"anyOf":[{"type":"object","properties":{"start":{"type":"object","properties":{"offset":{"type":"integer"},"time":{"type":"string"}},"required":["offset","time"],"additionalProperties":false},"end":{"type":"object","properties":{"offset":{"type":"integer"},"time":{"type":"string"}},"required":["offset","time"],"additionalProperties":false}},"required":["start","end"],"additionalProperties":false},{"type":"null"}]},"place":{"type":"object","properties":{"placeId":{"type":"string"},"lat":{"type":["number","null"]},"lng":{"type":["number","null"]},"formattedAddress":{"type":"string"}},"required":["placeId","lat","lng","formattedAddress"],"additionalProperties":false}},"required":["kind","id","name","packageId","replacesItemId","marginable","bookingRef","comments","catalogRef","amount","pvp","tag","qty","price","perPax","range","place"],"additionalProperties":false}]}},"totals":{"type":"object","properties":{"currency":{"type":"string","const":"EUR"},"net":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"marginAmount":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"total":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"finalPrice":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"perPax":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"finalMargin":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"packages":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"deltaNet":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"deltaPvp":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"lineIds":{"type":"array","items":{"type":"string"}}},"required":["id","name","deltaNet","deltaPvp","lineIds"],"additionalProperties":false}}},"required":["currency","net","marginAmount","total","finalPrice","perPax","finalMargin","packages"],"additionalProperties":false},"textOverrides":{"type":"object","additionalProperties":{"type":"string"}},"imageOverrides":{"type":"object","additionalProperties":{"type":"string"}},"sentAt":{"type":["string","null"]},"modifiedSinceSent":{"type":"boolean"},"acceptedAt":{"type":["string","null"]},"acceptedVia":{"anyOf":[{"type":"string","enum":["prospect_link","agent"]},{"type":"null"}]},"acceptedPackageId":{"type":["string","null"]},"acceptedLineIds":{"type":"array","items":{"type":"string"}},"acceptance":{"anyOf":[{"type":"object","properties":{"name":{"type":["string","null"]},"email":{"type":["string","null"]},"phone":{"type":["string","null"]},"message":{"type":["string","null"]}},"required":["name","email","phone","message"],"additionalProperties":false},{"type":"null"}],"description":"What the customer typed when accepting on the quote page — personal data: present only for a key holding `travelers:read`, only on quote reads (a write's response carries null; read the quote), and every such read is audited."},"engagement":{"type":"object","properties":{"views":{"type":"integer"},"uniqueSessions":{"type":"integer"},"activeSeconds":{"type":"integer"},"ctaClicks":{"type":"integer"},"maxScrollPct":{"type":"number"},"sectionsSeen":{"type":"integer"},"interactions":{"type":"integer"},"lastSeenAt":{"type":["string","null"]},"lastCtaAt":{"type":["string","null"]}},"required":["views","uniqueSessions","activeSeconds","ctaClicks","maxScrollPct","sectionsSeen","interactions","lastSeenAt","lastCtaAt"],"additionalProperties":false},"metadata":{"type":"object","additionalProperties":{"type":"string","maxLength":500},"propertyNames":{"pattern":"^[A-Za-z0-9_.-]{1,40}$"}},"appUrl":{"type":["string","null"]},"publicUrl":{"type":["string","null"]},"createdAt":{"type":"string"},"updatedAt":{"type":"string"}},"required":["object","id","tripId","code","name","mode","status","travelers","marginPct","finalPriceOverride","validUntil","ctaUrl","templateId","packages","lines","totals","textOverrides","imageOverrides","sentAt","modifiedSinceSent","acceptedAt","acceptedVia","acceptedPackageId","acceptedLineIds","acceptance","engagement","metadata","appUrl","publicUrl","createdAt","updatedAt"],"additionalProperties":false},"added":{"type":"integer"},"updated":{"type":"integer"},"removed":{"type":"integer"}},"required":["object","quote","added","updated","removed"],"additionalProperties":false},{"type":"object","properties":{"object":{"type":"string","const":"quote_preview"},"quoteId":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}]},"changes":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"from":{},"to":{}},"required":["field"],"additionalProperties":false}},"sync":{"anyOf":[{"type":"object","properties":{"added":{"type":"integer"},"updated":{"type":"integer"},"removed":{"type":"integer"}},"required":["added","updated","removed"],"additionalProperties":false},{"type":"null"}]},"packages":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false}},"lines":{"type":"array","items":{"anyOf":[{"type":"object","properties":{"kind":{"type":"string","const":"flight"},"id":{"type":"string"},"name":{"type":"string"},"packageId":{"type":["string","null"]},"replacesItemId":{"type":["string","null"]},"marginable":{"type":"boolean"},"bookingRef":{"type":"string"},"comments":{"type":"string"},"catalogRef":{"anyOf":[{"type":"object","properties":{"kind":{"type":"string"},"id":{"type":"string"}},"required":["kind","id"],"additionalProperties":false},{"type":"null"}]},"amount":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"pvp":{"anyOf":[{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},{"type":"null"}]},"role":{"type":"string","enum":["ida","interno","vuelta"]},"mode":{"type":"string","enum":["avion","tren","ferry","autobus","coche"]},"from":{"type":"string"},"to":{"type":"string"},"date":{"type":["string","null"]},"departTime":{"type":"string"},"arriveTime":{"type":"string"},"arriveDayOffset":{"type":"integer"},"stopovers":{"type":"array","items":{"type":"object","properties":{"place":{"type":"string"},"arriveTime":{"type":"string"},"departTime":{"type":"string"},"arriveDayOffset":{"type":"integer"},"flight":{"type":"object","properties":{"flightNo":{"type":"string"},"airline":{"type":"string"},"fromAirport":{"type":"string"},"toAirport":{"type":"string"}},"required":["flightNo","airline","fromAirport","toAirport"],"additionalProperties":false}},"required":["place","arriveTime","departTime","arriveDayOffset","flight"],"additionalProperties":false}},"flight":{"type":"object","properties":{"flightNo":{"type":"string"},"airline":{"type":"string"},"fromAirport":{"type":"string"},"toAirport":{"type":"string"}},"required":["flightNo","airline","fromAirport","toAirport"],"additionalProperties":false},"transferId":{"type":["string","null"]},"price":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"perPax":{"type":"boolean"},"pairedWithId":{"type":["string","null"]}},"required":["kind","id","name","packageId","replacesItemId","marginable","bookingRef","comments","catalogRef","amount","pvp","role","mode","from","to","date","departTime","arriveTime","arriveDayOffset","stopovers","flight","transferId","price","perPax","pairedWithId"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","const":"hotel"},"id":{"type":"string"},"name":{"type":"string"},"packageId":{"type":["string","null"]},"replacesItemId":{"type":["string","null"]},"marginable":{"type":"boolean"},"bookingRef":{"type":"string"},"comments":{"type":"string"},"catalogRef":{"anyOf":[{"type":"object","properties":{"kind":{"type":"string"},"id":{"type":"string"}},"required":["kind","id"],"additionalProperties":false},{"type":"null"}]},"amount":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"pvp":{"anyOf":[{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},{"type":"null"}]},"stopId":{"type":["string","null"]},"city":{"type":"string"},"nights":{"type":"integer"},"board":{"type":"string"},"rooms":{"type":"array","items":{"type":"object","properties":{"type":{"type":"string"},"qty":{"type":"integer"},"price":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"}},"required":["type","qty","price"],"additionalProperties":false}},"optionKind":{"type":"string","enum":["line","hotel"]},"place":{"type":"object","properties":{"placeId":{"type":"string"},"lat":{"type":["number","null"]},"lng":{"type":["number","null"]},"formattedAddress":{"type":"string"}},"required":["placeId","lat","lng","formattedAddress"],"additionalProperties":false}},"required":["kind","id","name","packageId","replacesItemId","marginable","bookingRef","comments","catalogRef","amount","pvp","stopId","city","nights","board","rooms","optionKind","place"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","const":"other"},"id":{"type":"string"},"name":{"type":"string"},"packageId":{"type":["string","null"]},"replacesItemId":{"type":["string","null"]},"marginable":{"type":"boolean"},"bookingRef":{"type":"string"},"comments":{"type":"string"},"catalogRef":{"anyOf":[{"type":"object","properties":{"kind":{"type":"string"},"id":{"type":"string"}},"required":["kind","id"],"additionalProperties":false},{"type":"null"}]},"amount":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"pvp":{"anyOf":[{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},{"type":"null"}]},"tag":{"anyOf":[{"type":"string","enum":["actividad","traslado","seguro"]},{"type":"null"}]},"qty":{"type":"number"},"price":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"perPax":{"type":"boolean"},"range":{"anyOf":[{"type":"object","properties":{"start":{"type":"object","properties":{"offset":{"type":"integer"},"time":{"type":"string"}},"required":["offset","time"],"additionalProperties":false},"end":{"type":"object","properties":{"offset":{"type":"integer"},"time":{"type":"string"}},"required":["offset","time"],"additionalProperties":false}},"required":["start","end"],"additionalProperties":false},{"type":"null"}]},"place":{"type":"object","properties":{"placeId":{"type":"string"},"lat":{"type":["number","null"]},"lng":{"type":["number","null"]},"formattedAddress":{"type":"string"}},"required":["placeId","lat","lng","formattedAddress"],"additionalProperties":false}},"required":["kind","id","name","packageId","replacesItemId","marginable","bookingRef","comments","catalogRef","amount","pvp","tag","qty","price","perPax","range","place"],"additionalProperties":false}]}},"totals":{"type":"object","properties":{"currency":{"type":"string","const":"EUR"},"net":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"marginAmount":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"total":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"finalPrice":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"perPax":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"finalMargin":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"packages":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"deltaNet":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"deltaPvp":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"lineIds":{"type":"array","items":{"type":"string"}}},"required":["id","name","deltaNet","deltaPvp","lineIds"],"additionalProperties":false}}},"required":["currency","net","marginAmount","total","finalPrice","perPax","finalMargin","packages"],"additionalProperties":false}},"required":["object","quoteId","changes","sync","packages","lines","totals"],"additionalProperties":false}]}}}},"default":{"description":"Error (RFC 9457)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"expectedUpdatedAt":{"type":"string","format":"date-time","description":"The quote's updatedAt as you read it; the write is refused (409) if the quote changed since."}},"required":[],"additionalProperties":false}}}}}},"/quotes/{quoteId}/send":{"post":{"operationId":"quotes.send","summary":"Send a quote","description":"Publishes the quote's public page, as the quote editor's Send / Update link does: renders the agency's template with the quote as it is now and stores that snapshot at `publicUrl`, which you share with the customer (nothing is emailed). A first send moves the trip from `nueva` to `propuesta_enviada`. Re-sending an accepted or rejected quote refreshes its page and keeps its status. With `?dryRun=true`, renders the page and returns its HTML without publishing — the quote editor's preview. A template with a Liquid error is a 422 naming it.\n\n**Permissions:** `quotes:write`.","tags":["Quotes"],"x-scopes":["quotes:write"],"x-undo":"none","parameters":[{"name":"quoteId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"$ref":"#/components/parameters/DryRun"},{"$ref":"#/components/parameters/IdempotencyKey"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"anyOf":[{"type":"object","properties":{"object":{"type":"string","const":"quote"},"id":{"type":"string","format":"uuid"},"tripId":{"type":"string","format":"uuid"},"code":{"type":"string"},"name":{"type":"string"},"mode":{"type":"string","enum":["package","per_item"]},"status":{"type":"string","enum":["draft","sent","accepted","rejected","expired","superseded"]},"travelers":{"type":"integer"},"marginPct":{"type":"number"},"finalPriceOverride":{"anyOf":[{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},{"type":"null"}]},"validUntil":{"type":["string","null"]},"ctaUrl":{"type":["string","null"]},"templateId":{"type":["string","null"]},"packages":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false}},"lines":{"type":"array","items":{"anyOf":[{"type":"object","properties":{"kind":{"type":"string","const":"flight"},"id":{"type":"string"},"name":{"type":"string"},"packageId":{"type":["string","null"]},"replacesItemId":{"type":["string","null"]},"marginable":{"type":"boolean"},"bookingRef":{"type":"string"},"comments":{"type":"string"},"catalogRef":{"anyOf":[{"type":"object","properties":{"kind":{"type":"string"},"id":{"type":"string"}},"required":["kind","id"],"additionalProperties":false},{"type":"null"}]},"amount":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"pvp":{"anyOf":[{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},{"type":"null"}]},"role":{"type":"string","enum":["ida","interno","vuelta"]},"mode":{"type":"string","enum":["avion","tren","ferry","autobus","coche"]},"from":{"type":"string"},"to":{"type":"string"},"date":{"type":["string","null"]},"departTime":{"type":"string"},"arriveTime":{"type":"string"},"arriveDayOffset":{"type":"integer"},"stopovers":{"type":"array","items":{"type":"object","properties":{"place":{"type":"string"},"arriveTime":{"type":"string"},"departTime":{"type":"string"},"arriveDayOffset":{"type":"integer"},"flight":{"type":"object","properties":{"flightNo":{"type":"string"},"airline":{"type":"string"},"fromAirport":{"type":"string"},"toAirport":{"type":"string"}},"required":["flightNo","airline","fromAirport","toAirport"],"additionalProperties":false}},"required":["place","arriveTime","departTime","arriveDayOffset","flight"],"additionalProperties":false}},"flight":{"type":"object","properties":{"flightNo":{"type":"string"},"airline":{"type":"string"},"fromAirport":{"type":"string"},"toAirport":{"type":"string"}},"required":["flightNo","airline","fromAirport","toAirport"],"additionalProperties":false},"transferId":{"type":["string","null"]},"price":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"perPax":{"type":"boolean"},"pairedWithId":{"type":["string","null"]}},"required":["kind","id","name","packageId","replacesItemId","marginable","bookingRef","comments","catalogRef","amount","pvp","role","mode","from","to","date","departTime","arriveTime","arriveDayOffset","stopovers","flight","transferId","price","perPax","pairedWithId"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","const":"hotel"},"id":{"type":"string"},"name":{"type":"string"},"packageId":{"type":["string","null"]},"replacesItemId":{"type":["string","null"]},"marginable":{"type":"boolean"},"bookingRef":{"type":"string"},"comments":{"type":"string"},"catalogRef":{"anyOf":[{"type":"object","properties":{"kind":{"type":"string"},"id":{"type":"string"}},"required":["kind","id"],"additionalProperties":false},{"type":"null"}]},"amount":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"pvp":{"anyOf":[{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},{"type":"null"}]},"stopId":{"type":["string","null"]},"city":{"type":"string"},"nights":{"type":"integer"},"board":{"type":"string"},"rooms":{"type":"array","items":{"type":"object","properties":{"type":{"type":"string"},"qty":{"type":"integer"},"price":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"}},"required":["type","qty","price"],"additionalProperties":false}},"optionKind":{"type":"string","enum":["line","hotel"]},"place":{"type":"object","properties":{"placeId":{"type":"string"},"lat":{"type":["number","null"]},"lng":{"type":["number","null"]},"formattedAddress":{"type":"string"}},"required":["placeId","lat","lng","formattedAddress"],"additionalProperties":false}},"required":["kind","id","name","packageId","replacesItemId","marginable","bookingRef","comments","catalogRef","amount","pvp","stopId","city","nights","board","rooms","optionKind","place"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","const":"other"},"id":{"type":"string"},"name":{"type":"string"},"packageId":{"type":["string","null"]},"replacesItemId":{"type":["string","null"]},"marginable":{"type":"boolean"},"bookingRef":{"type":"string"},"comments":{"type":"string"},"catalogRef":{"anyOf":[{"type":"object","properties":{"kind":{"type":"string"},"id":{"type":"string"}},"required":["kind","id"],"additionalProperties":false},{"type":"null"}]},"amount":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"pvp":{"anyOf":[{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},{"type":"null"}]},"tag":{"anyOf":[{"type":"string","enum":["actividad","traslado","seguro"]},{"type":"null"}]},"qty":{"type":"number"},"price":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"perPax":{"type":"boolean"},"range":{"anyOf":[{"type":"object","properties":{"start":{"type":"object","properties":{"offset":{"type":"integer"},"time":{"type":"string"}},"required":["offset","time"],"additionalProperties":false},"end":{"type":"object","properties":{"offset":{"type":"integer"},"time":{"type":"string"}},"required":["offset","time"],"additionalProperties":false}},"required":["start","end"],"additionalProperties":false},{"type":"null"}]},"place":{"type":"object","properties":{"placeId":{"type":"string"},"lat":{"type":["number","null"]},"lng":{"type":["number","null"]},"formattedAddress":{"type":"string"}},"required":["placeId","lat","lng","formattedAddress"],"additionalProperties":false}},"required":["kind","id","name","packageId","replacesItemId","marginable","bookingRef","comments","catalogRef","amount","pvp","tag","qty","price","perPax","range","place"],"additionalProperties":false}]}},"totals":{"type":"object","properties":{"currency":{"type":"string","const":"EUR"},"net":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"marginAmount":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"total":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"finalPrice":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"perPax":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"finalMargin":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"packages":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"deltaNet":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"deltaPvp":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"lineIds":{"type":"array","items":{"type":"string"}}},"required":["id","name","deltaNet","deltaPvp","lineIds"],"additionalProperties":false}}},"required":["currency","net","marginAmount","total","finalPrice","perPax","finalMargin","packages"],"additionalProperties":false},"textOverrides":{"type":"object","additionalProperties":{"type":"string"}},"imageOverrides":{"type":"object","additionalProperties":{"type":"string"}},"sentAt":{"type":["string","null"]},"modifiedSinceSent":{"type":"boolean"},"acceptedAt":{"type":["string","null"]},"acceptedVia":{"anyOf":[{"type":"string","enum":["prospect_link","agent"]},{"type":"null"}]},"acceptedPackageId":{"type":["string","null"]},"acceptedLineIds":{"type":"array","items":{"type":"string"}},"acceptance":{"anyOf":[{"type":"object","properties":{"name":{"type":["string","null"]},"email":{"type":["string","null"]},"phone":{"type":["string","null"]},"message":{"type":["string","null"]}},"required":["name","email","phone","message"],"additionalProperties":false},{"type":"null"}],"description":"What the customer typed when accepting on the quote page — personal data: present only for a key holding `travelers:read`, only on quote reads (a write's response carries null; read the quote), and every such read is audited."},"engagement":{"type":"object","properties":{"views":{"type":"integer"},"uniqueSessions":{"type":"integer"},"activeSeconds":{"type":"integer"},"ctaClicks":{"type":"integer"},"maxScrollPct":{"type":"number"},"sectionsSeen":{"type":"integer"},"interactions":{"type":"integer"},"lastSeenAt":{"type":["string","null"]},"lastCtaAt":{"type":["string","null"]}},"required":["views","uniqueSessions","activeSeconds","ctaClicks","maxScrollPct","sectionsSeen","interactions","lastSeenAt","lastCtaAt"],"additionalProperties":false},"metadata":{"type":"object","additionalProperties":{"type":"string","maxLength":500},"propertyNames":{"pattern":"^[A-Za-z0-9_.-]{1,40}$"}},"appUrl":{"type":["string","null"]},"publicUrl":{"type":["string","null"]},"createdAt":{"type":"string"},"updatedAt":{"type":"string"}},"required":["object","id","tripId","code","name","mode","status","travelers","marginPct","finalPriceOverride","validUntil","ctaUrl","templateId","packages","lines","totals","textOverrides","imageOverrides","sentAt","modifiedSinceSent","acceptedAt","acceptedVia","acceptedPackageId","acceptedLineIds","acceptance","engagement","metadata","appUrl","publicUrl","createdAt","updatedAt"],"additionalProperties":false},{"type":"object","properties":{"object":{"type":"string","const":"quote_send_preview"},"quoteId":{"type":"string","format":"uuid"},"htmlBytes":{"type":"integer"},"html":{"type":"string"}},"required":["object","quoteId","htmlBytes","html"],"additionalProperties":false}]}}}},"default":{"description":"Error (RFC 9457)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{},"required":[],"additionalProperties":false}}}}}},"/quotes/{quoteId}/accept":{"post":{"operationId":"quotes.accept","summary":"Accept a quote on the customer's behalf","description":"Records that the customer accepted, as the quote editor's Accept does (`acceptedVia: agent`). A package quote takes the chosen `packageId` (absent or null = the base proposal); a per_item quote takes the `lineIds` the customer bought. Accepting a package quote supersedes any other accepted package quote of the trip, and moves the trip to `aceptada` from `nueva`, `propuesta_enviada` or `rechazada`. To bring the accepted services into the itinerary, then call POST /trips/{tripId}/itinerary/sync. Undo with POST /quotes/{quoteId}/reopen.\n\n**Permissions:** `quotes:write`.\n\n**Undo:** call `quotes.reopen`.","tags":["Quotes"],"x-scopes":["quotes:write"],"x-undo":{"restore":"quotes.reopen"},"parameters":[{"name":"quoteId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"$ref":"#/components/parameters/IdempotencyKey"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"object":{"type":"string","const":"quote"},"id":{"type":"string","format":"uuid"},"tripId":{"type":"string","format":"uuid"},"code":{"type":"string"},"name":{"type":"string"},"mode":{"type":"string","enum":["package","per_item"]},"status":{"type":"string","enum":["draft","sent","accepted","rejected","expired","superseded"]},"travelers":{"type":"integer"},"marginPct":{"type":"number"},"finalPriceOverride":{"anyOf":[{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},{"type":"null"}]},"validUntil":{"type":["string","null"]},"ctaUrl":{"type":["string","null"]},"templateId":{"type":["string","null"]},"packages":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false}},"lines":{"type":"array","items":{"anyOf":[{"type":"object","properties":{"kind":{"type":"string","const":"flight"},"id":{"type":"string"},"name":{"type":"string"},"packageId":{"type":["string","null"]},"replacesItemId":{"type":["string","null"]},"marginable":{"type":"boolean"},"bookingRef":{"type":"string"},"comments":{"type":"string"},"catalogRef":{"anyOf":[{"type":"object","properties":{"kind":{"type":"string"},"id":{"type":"string"}},"required":["kind","id"],"additionalProperties":false},{"type":"null"}]},"amount":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"pvp":{"anyOf":[{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},{"type":"null"}]},"role":{"type":"string","enum":["ida","interno","vuelta"]},"mode":{"type":"string","enum":["avion","tren","ferry","autobus","coche"]},"from":{"type":"string"},"to":{"type":"string"},"date":{"type":["string","null"]},"departTime":{"type":"string"},"arriveTime":{"type":"string"},"arriveDayOffset":{"type":"integer"},"stopovers":{"type":"array","items":{"type":"object","properties":{"place":{"type":"string"},"arriveTime":{"type":"string"},"departTime":{"type":"string"},"arriveDayOffset":{"type":"integer"},"flight":{"type":"object","properties":{"flightNo":{"type":"string"},"airline":{"type":"string"},"fromAirport":{"type":"string"},"toAirport":{"type":"string"}},"required":["flightNo","airline","fromAirport","toAirport"],"additionalProperties":false}},"required":["place","arriveTime","departTime","arriveDayOffset","flight"],"additionalProperties":false}},"flight":{"type":"object","properties":{"flightNo":{"type":"string"},"airline":{"type":"string"},"fromAirport":{"type":"string"},"toAirport":{"type":"string"}},"required":["flightNo","airline","fromAirport","toAirport"],"additionalProperties":false},"transferId":{"type":["string","null"]},"price":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"perPax":{"type":"boolean"},"pairedWithId":{"type":["string","null"]}},"required":["kind","id","name","packageId","replacesItemId","marginable","bookingRef","comments","catalogRef","amount","pvp","role","mode","from","to","date","departTime","arriveTime","arriveDayOffset","stopovers","flight","transferId","price","perPax","pairedWithId"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","const":"hotel"},"id":{"type":"string"},"name":{"type":"string"},"packageId":{"type":["string","null"]},"replacesItemId":{"type":["string","null"]},"marginable":{"type":"boolean"},"bookingRef":{"type":"string"},"comments":{"type":"string"},"catalogRef":{"anyOf":[{"type":"object","properties":{"kind":{"type":"string"},"id":{"type":"string"}},"required":["kind","id"],"additionalProperties":false},{"type":"null"}]},"amount":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"pvp":{"anyOf":[{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},{"type":"null"}]},"stopId":{"type":["string","null"]},"city":{"type":"string"},"nights":{"type":"integer"},"board":{"type":"string"},"rooms":{"type":"array","items":{"type":"object","properties":{"type":{"type":"string"},"qty":{"type":"integer"},"price":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"}},"required":["type","qty","price"],"additionalProperties":false}},"optionKind":{"type":"string","enum":["line","hotel"]},"place":{"type":"object","properties":{"placeId":{"type":"string"},"lat":{"type":["number","null"]},"lng":{"type":["number","null"]},"formattedAddress":{"type":"string"}},"required":["placeId","lat","lng","formattedAddress"],"additionalProperties":false}},"required":["kind","id","name","packageId","replacesItemId","marginable","bookingRef","comments","catalogRef","amount","pvp","stopId","city","nights","board","rooms","optionKind","place"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","const":"other"},"id":{"type":"string"},"name":{"type":"string"},"packageId":{"type":["string","null"]},"replacesItemId":{"type":["string","null"]},"marginable":{"type":"boolean"},"bookingRef":{"type":"string"},"comments":{"type":"string"},"catalogRef":{"anyOf":[{"type":"object","properties":{"kind":{"type":"string"},"id":{"type":"string"}},"required":["kind","id"],"additionalProperties":false},{"type":"null"}]},"amount":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"pvp":{"anyOf":[{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},{"type":"null"}]},"tag":{"anyOf":[{"type":"string","enum":["actividad","traslado","seguro"]},{"type":"null"}]},"qty":{"type":"number"},"price":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"perPax":{"type":"boolean"},"range":{"anyOf":[{"type":"object","properties":{"start":{"type":"object","properties":{"offset":{"type":"integer"},"time":{"type":"string"}},"required":["offset","time"],"additionalProperties":false},"end":{"type":"object","properties":{"offset":{"type":"integer"},"time":{"type":"string"}},"required":["offset","time"],"additionalProperties":false}},"required":["start","end"],"additionalProperties":false},{"type":"null"}]},"place":{"type":"object","properties":{"placeId":{"type":"string"},"lat":{"type":["number","null"]},"lng":{"type":["number","null"]},"formattedAddress":{"type":"string"}},"required":["placeId","lat","lng","formattedAddress"],"additionalProperties":false}},"required":["kind","id","name","packageId","replacesItemId","marginable","bookingRef","comments","catalogRef","amount","pvp","tag","qty","price","perPax","range","place"],"additionalProperties":false}]}},"totals":{"type":"object","properties":{"currency":{"type":"string","const":"EUR"},"net":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"marginAmount":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"total":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"finalPrice":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"perPax":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"finalMargin":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"packages":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"deltaNet":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"deltaPvp":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"lineIds":{"type":"array","items":{"type":"string"}}},"required":["id","name","deltaNet","deltaPvp","lineIds"],"additionalProperties":false}}},"required":["currency","net","marginAmount","total","finalPrice","perPax","finalMargin","packages"],"additionalProperties":false},"textOverrides":{"type":"object","additionalProperties":{"type":"string"}},"imageOverrides":{"type":"object","additionalProperties":{"type":"string"}},"sentAt":{"type":["string","null"]},"modifiedSinceSent":{"type":"boolean"},"acceptedAt":{"type":["string","null"]},"acceptedVia":{"anyOf":[{"type":"string","enum":["prospect_link","agent"]},{"type":"null"}]},"acceptedPackageId":{"type":["string","null"]},"acceptedLineIds":{"type":"array","items":{"type":"string"}},"acceptance":{"anyOf":[{"type":"object","properties":{"name":{"type":["string","null"]},"email":{"type":["string","null"]},"phone":{"type":["string","null"]},"message":{"type":["string","null"]}},"required":["name","email","phone","message"],"additionalProperties":false},{"type":"null"}],"description":"What the customer typed when accepting on the quote page — personal data: present only for a key holding `travelers:read`, only on quote reads (a write's response carries null; read the quote), and every such read is audited."},"engagement":{"type":"object","properties":{"views":{"type":"integer"},"uniqueSessions":{"type":"integer"},"activeSeconds":{"type":"integer"},"ctaClicks":{"type":"integer"},"maxScrollPct":{"type":"number"},"sectionsSeen":{"type":"integer"},"interactions":{"type":"integer"},"lastSeenAt":{"type":["string","null"]},"lastCtaAt":{"type":["string","null"]}},"required":["views","uniqueSessions","activeSeconds","ctaClicks","maxScrollPct","sectionsSeen","interactions","lastSeenAt","lastCtaAt"],"additionalProperties":false},"metadata":{"type":"object","additionalProperties":{"type":"string","maxLength":500},"propertyNames":{"pattern":"^[A-Za-z0-9_.-]{1,40}$"}},"appUrl":{"type":["string","null"]},"publicUrl":{"type":["string","null"]},"createdAt":{"type":"string"},"updatedAt":{"type":"string"}},"required":["object","id","tripId","code","name","mode","status","travelers","marginPct","finalPriceOverride","validUntil","ctaUrl","templateId","packages","lines","totals","textOverrides","imageOverrides","sentAt","modifiedSinceSent","acceptedAt","acceptedVia","acceptedPackageId","acceptedLineIds","acceptance","engagement","metadata","appUrl","publicUrl","createdAt","updatedAt"],"additionalProperties":false}}}},"default":{"description":"Error (RFC 9457)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"packageId":{"anyOf":[{"type":"string","minLength":1,"maxLength":64},{"type":"null"}],"description":"A package quote: the package chosen; absent or null = the base proposal."},"lineIds":{"type":"array","items":{"type":"string","minLength":1,"maxLength":64},"minItems":1,"maxItems":200,"description":"A per_item quote: the lines the customer bought."}},"required":[],"additionalProperties":false}}}}}},"/quotes/{quoteId}/reject":{"post":{"operationId":"quotes.reject","summary":"Reject a quote on the customer's behalf","description":"Records that the customer declined, as the quote editor's Reject does. When no quote of the trip is left draft, sent or accepted, the trip moves to `rechazada`. Undo with POST /quotes/{quoteId}/reopen.\n\n**Permissions:** `quotes:write`.\n\n**Undo:** call `quotes.reopen`.","tags":["Quotes"],"x-scopes":["quotes:write"],"x-undo":{"restore":"quotes.reopen"},"parameters":[{"name":"quoteId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"$ref":"#/components/parameters/IdempotencyKey"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"object":{"type":"string","const":"quote"},"id":{"type":"string","format":"uuid"},"tripId":{"type":"string","format":"uuid"},"code":{"type":"string"},"name":{"type":"string"},"mode":{"type":"string","enum":["package","per_item"]},"status":{"type":"string","enum":["draft","sent","accepted","rejected","expired","superseded"]},"travelers":{"type":"integer"},"marginPct":{"type":"number"},"finalPriceOverride":{"anyOf":[{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},{"type":"null"}]},"validUntil":{"type":["string","null"]},"ctaUrl":{"type":["string","null"]},"templateId":{"type":["string","null"]},"packages":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false}},"lines":{"type":"array","items":{"anyOf":[{"type":"object","properties":{"kind":{"type":"string","const":"flight"},"id":{"type":"string"},"name":{"type":"string"},"packageId":{"type":["string","null"]},"replacesItemId":{"type":["string","null"]},"marginable":{"type":"boolean"},"bookingRef":{"type":"string"},"comments":{"type":"string"},"catalogRef":{"anyOf":[{"type":"object","properties":{"kind":{"type":"string"},"id":{"type":"string"}},"required":["kind","id"],"additionalProperties":false},{"type":"null"}]},"amount":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"pvp":{"anyOf":[{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},{"type":"null"}]},"role":{"type":"string","enum":["ida","interno","vuelta"]},"mode":{"type":"string","enum":["avion","tren","ferry","autobus","coche"]},"from":{"type":"string"},"to":{"type":"string"},"date":{"type":["string","null"]},"departTime":{"type":"string"},"arriveTime":{"type":"string"},"arriveDayOffset":{"type":"integer"},"stopovers":{"type":"array","items":{"type":"object","properties":{"place":{"type":"string"},"arriveTime":{"type":"string"},"departTime":{"type":"string"},"arriveDayOffset":{"type":"integer"},"flight":{"type":"object","properties":{"flightNo":{"type":"string"},"airline":{"type":"string"},"fromAirport":{"type":"string"},"toAirport":{"type":"string"}},"required":["flightNo","airline","fromAirport","toAirport"],"additionalProperties":false}},"required":["place","arriveTime","departTime","arriveDayOffset","flight"],"additionalProperties":false}},"flight":{"type":"object","properties":{"flightNo":{"type":"string"},"airline":{"type":"string"},"fromAirport":{"type":"string"},"toAirport":{"type":"string"}},"required":["flightNo","airline","fromAirport","toAirport"],"additionalProperties":false},"transferId":{"type":["string","null"]},"price":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"perPax":{"type":"boolean"},"pairedWithId":{"type":["string","null"]}},"required":["kind","id","name","packageId","replacesItemId","marginable","bookingRef","comments","catalogRef","amount","pvp","role","mode","from","to","date","departTime","arriveTime","arriveDayOffset","stopovers","flight","transferId","price","perPax","pairedWithId"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","const":"hotel"},"id":{"type":"string"},"name":{"type":"string"},"packageId":{"type":["string","null"]},"replacesItemId":{"type":["string","null"]},"marginable":{"type":"boolean"},"bookingRef":{"type":"string"},"comments":{"type":"string"},"catalogRef":{"anyOf":[{"type":"object","properties":{"kind":{"type":"string"},"id":{"type":"string"}},"required":["kind","id"],"additionalProperties":false},{"type":"null"}]},"amount":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"pvp":{"anyOf":[{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},{"type":"null"}]},"stopId":{"type":["string","null"]},"city":{"type":"string"},"nights":{"type":"integer"},"board":{"type":"string"},"rooms":{"type":"array","items":{"type":"object","properties":{"type":{"type":"string"},"qty":{"type":"integer"},"price":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"}},"required":["type","qty","price"],"additionalProperties":false}},"optionKind":{"type":"string","enum":["line","hotel"]},"place":{"type":"object","properties":{"placeId":{"type":"string"},"lat":{"type":["number","null"]},"lng":{"type":["number","null"]},"formattedAddress":{"type":"string"}},"required":["placeId","lat","lng","formattedAddress"],"additionalProperties":false}},"required":["kind","id","name","packageId","replacesItemId","marginable","bookingRef","comments","catalogRef","amount","pvp","stopId","city","nights","board","rooms","optionKind","place"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","const":"other"},"id":{"type":"string"},"name":{"type":"string"},"packageId":{"type":["string","null"]},"replacesItemId":{"type":["string","null"]},"marginable":{"type":"boolean"},"bookingRef":{"type":"string"},"comments":{"type":"string"},"catalogRef":{"anyOf":[{"type":"object","properties":{"kind":{"type":"string"},"id":{"type":"string"}},"required":["kind","id"],"additionalProperties":false},{"type":"null"}]},"amount":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"pvp":{"anyOf":[{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},{"type":"null"}]},"tag":{"anyOf":[{"type":"string","enum":["actividad","traslado","seguro"]},{"type":"null"}]},"qty":{"type":"number"},"price":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"perPax":{"type":"boolean"},"range":{"anyOf":[{"type":"object","properties":{"start":{"type":"object","properties":{"offset":{"type":"integer"},"time":{"type":"string"}},"required":["offset","time"],"additionalProperties":false},"end":{"type":"object","properties":{"offset":{"type":"integer"},"time":{"type":"string"}},"required":["offset","time"],"additionalProperties":false}},"required":["start","end"],"additionalProperties":false},{"type":"null"}]},"place":{"type":"object","properties":{"placeId":{"type":"string"},"lat":{"type":["number","null"]},"lng":{"type":["number","null"]},"formattedAddress":{"type":"string"}},"required":["placeId","lat","lng","formattedAddress"],"additionalProperties":false}},"required":["kind","id","name","packageId","replacesItemId","marginable","bookingRef","comments","catalogRef","amount","pvp","tag","qty","price","perPax","range","place"],"additionalProperties":false}]}},"totals":{"type":"object","properties":{"currency":{"type":"string","const":"EUR"},"net":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"marginAmount":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"total":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"finalPrice":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"perPax":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"finalMargin":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"packages":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"deltaNet":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"deltaPvp":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"lineIds":{"type":"array","items":{"type":"string"}}},"required":["id","name","deltaNet","deltaPvp","lineIds"],"additionalProperties":false}}},"required":["currency","net","marginAmount","total","finalPrice","perPax","finalMargin","packages"],"additionalProperties":false},"textOverrides":{"type":"object","additionalProperties":{"type":"string"}},"imageOverrides":{"type":"object","additionalProperties":{"type":"string"}},"sentAt":{"type":["string","null"]},"modifiedSinceSent":{"type":"boolean"},"acceptedAt":{"type":["string","null"]},"acceptedVia":{"anyOf":[{"type":"string","enum":["prospect_link","agent"]},{"type":"null"}]},"acceptedPackageId":{"type":["string","null"]},"acceptedLineIds":{"type":"array","items":{"type":"string"}},"acceptance":{"anyOf":[{"type":"object","properties":{"name":{"type":["string","null"]},"email":{"type":["string","null"]},"phone":{"type":["string","null"]},"message":{"type":["string","null"]}},"required":["name","email","phone","message"],"additionalProperties":false},{"type":"null"}],"description":"What the customer typed when accepting on the quote page — personal data: present only for a key holding `travelers:read`, only on quote reads (a write's response carries null; read the quote), and every such read is audited."},"engagement":{"type":"object","properties":{"views":{"type":"integer"},"uniqueSessions":{"type":"integer"},"activeSeconds":{"type":"integer"},"ctaClicks":{"type":"integer"},"maxScrollPct":{"type":"number"},"sectionsSeen":{"type":"integer"},"interactions":{"type":"integer"},"lastSeenAt":{"type":["string","null"]},"lastCtaAt":{"type":["string","null"]}},"required":["views","uniqueSessions","activeSeconds","ctaClicks","maxScrollPct","sectionsSeen","interactions","lastSeenAt","lastCtaAt"],"additionalProperties":false},"metadata":{"type":"object","additionalProperties":{"type":"string","maxLength":500},"propertyNames":{"pattern":"^[A-Za-z0-9_.-]{1,40}$"}},"appUrl":{"type":["string","null"]},"publicUrl":{"type":["string","null"]},"createdAt":{"type":"string"},"updatedAt":{"type":"string"}},"required":["object","id","tripId","code","name","mode","status","travelers","marginPct","finalPriceOverride","validUntil","ctaUrl","templateId","packages","lines","totals","textOverrides","imageOverrides","sentAt","modifiedSinceSent","acceptedAt","acceptedVia","acceptedPackageId","acceptedLineIds","acceptance","engagement","metadata","appUrl","publicUrl","createdAt","updatedAt"],"additionalProperties":false}}}},"default":{"description":"Error (RFC 9457)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{},"required":[],"additionalProperties":false}}}}}},"/quotes/{quoteId}/reopen":{"post":{"operationId":"quotes.reopen","summary":"Reopen a quote","description":"Takes an accepted or rejected quote back to `sent`, as the quote editor's Reopen does; reopening an accepted quote also takes the trip back from `aceptada`. It is how an acceptance or a rejection is undone.\n\n**Permissions:** `quotes:write`.","tags":["Quotes"],"x-scopes":["quotes:write"],"x-undo":"none","parameters":[{"name":"quoteId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"$ref":"#/components/parameters/IdempotencyKey"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"object":{"type":"string","const":"quote"},"id":{"type":"string","format":"uuid"},"tripId":{"type":"string","format":"uuid"},"code":{"type":"string"},"name":{"type":"string"},"mode":{"type":"string","enum":["package","per_item"]},"status":{"type":"string","enum":["draft","sent","accepted","rejected","expired","superseded"]},"travelers":{"type":"integer"},"marginPct":{"type":"number"},"finalPriceOverride":{"anyOf":[{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},{"type":"null"}]},"validUntil":{"type":["string","null"]},"ctaUrl":{"type":["string","null"]},"templateId":{"type":["string","null"]},"packages":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false}},"lines":{"type":"array","items":{"anyOf":[{"type":"object","properties":{"kind":{"type":"string","const":"flight"},"id":{"type":"string"},"name":{"type":"string"},"packageId":{"type":["string","null"]},"replacesItemId":{"type":["string","null"]},"marginable":{"type":"boolean"},"bookingRef":{"type":"string"},"comments":{"type":"string"},"catalogRef":{"anyOf":[{"type":"object","properties":{"kind":{"type":"string"},"id":{"type":"string"}},"required":["kind","id"],"additionalProperties":false},{"type":"null"}]},"amount":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"pvp":{"anyOf":[{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},{"type":"null"}]},"role":{"type":"string","enum":["ida","interno","vuelta"]},"mode":{"type":"string","enum":["avion","tren","ferry","autobus","coche"]},"from":{"type":"string"},"to":{"type":"string"},"date":{"type":["string","null"]},"departTime":{"type":"string"},"arriveTime":{"type":"string"},"arriveDayOffset":{"type":"integer"},"stopovers":{"type":"array","items":{"type":"object","properties":{"place":{"type":"string"},"arriveTime":{"type":"string"},"departTime":{"type":"string"},"arriveDayOffset":{"type":"integer"},"flight":{"type":"object","properties":{"flightNo":{"type":"string"},"airline":{"type":"string"},"fromAirport":{"type":"string"},"toAirport":{"type":"string"}},"required":["flightNo","airline","fromAirport","toAirport"],"additionalProperties":false}},"required":["place","arriveTime","departTime","arriveDayOffset","flight"],"additionalProperties":false}},"flight":{"type":"object","properties":{"flightNo":{"type":"string"},"airline":{"type":"string"},"fromAirport":{"type":"string"},"toAirport":{"type":"string"}},"required":["flightNo","airline","fromAirport","toAirport"],"additionalProperties":false},"transferId":{"type":["string","null"]},"price":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"perPax":{"type":"boolean"},"pairedWithId":{"type":["string","null"]}},"required":["kind","id","name","packageId","replacesItemId","marginable","bookingRef","comments","catalogRef","amount","pvp","role","mode","from","to","date","departTime","arriveTime","arriveDayOffset","stopovers","flight","transferId","price","perPax","pairedWithId"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","const":"hotel"},"id":{"type":"string"},"name":{"type":"string"},"packageId":{"type":["string","null"]},"replacesItemId":{"type":["string","null"]},"marginable":{"type":"boolean"},"bookingRef":{"type":"string"},"comments":{"type":"string"},"catalogRef":{"anyOf":[{"type":"object","properties":{"kind":{"type":"string"},"id":{"type":"string"}},"required":["kind","id"],"additionalProperties":false},{"type":"null"}]},"amount":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"pvp":{"anyOf":[{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},{"type":"null"}]},"stopId":{"type":["string","null"]},"city":{"type":"string"},"nights":{"type":"integer"},"board":{"type":"string"},"rooms":{"type":"array","items":{"type":"object","properties":{"type":{"type":"string"},"qty":{"type":"integer"},"price":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"}},"required":["type","qty","price"],"additionalProperties":false}},"optionKind":{"type":"string","enum":["line","hotel"]},"place":{"type":"object","properties":{"placeId":{"type":"string"},"lat":{"type":["number","null"]},"lng":{"type":["number","null"]},"formattedAddress":{"type":"string"}},"required":["placeId","lat","lng","formattedAddress"],"additionalProperties":false}},"required":["kind","id","name","packageId","replacesItemId","marginable","bookingRef","comments","catalogRef","amount","pvp","stopId","city","nights","board","rooms","optionKind","place"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","const":"other"},"id":{"type":"string"},"name":{"type":"string"},"packageId":{"type":["string","null"]},"replacesItemId":{"type":["string","null"]},"marginable":{"type":"boolean"},"bookingRef":{"type":"string"},"comments":{"type":"string"},"catalogRef":{"anyOf":[{"type":"object","properties":{"kind":{"type":"string"},"id":{"type":"string"}},"required":["kind","id"],"additionalProperties":false},{"type":"null"}]},"amount":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"pvp":{"anyOf":[{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},{"type":"null"}]},"tag":{"anyOf":[{"type":"string","enum":["actividad","traslado","seguro"]},{"type":"null"}]},"qty":{"type":"number"},"price":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"perPax":{"type":"boolean"},"range":{"anyOf":[{"type":"object","properties":{"start":{"type":"object","properties":{"offset":{"type":"integer"},"time":{"type":"string"}},"required":["offset","time"],"additionalProperties":false},"end":{"type":"object","properties":{"offset":{"type":"integer"},"time":{"type":"string"}},"required":["offset","time"],"additionalProperties":false}},"required":["start","end"],"additionalProperties":false},{"type":"null"}]},"place":{"type":"object","properties":{"placeId":{"type":"string"},"lat":{"type":["number","null"]},"lng":{"type":["number","null"]},"formattedAddress":{"type":"string"}},"required":["placeId","lat","lng","formattedAddress"],"additionalProperties":false}},"required":["kind","id","name","packageId","replacesItemId","marginable","bookingRef","comments","catalogRef","amount","pvp","tag","qty","price","perPax","range","place"],"additionalProperties":false}]}},"totals":{"type":"object","properties":{"currency":{"type":"string","const":"EUR"},"net":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"marginAmount":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"total":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"finalPrice":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"perPax":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"finalMargin":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"packages":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"deltaNet":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"deltaPvp":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"lineIds":{"type":"array","items":{"type":"string"}}},"required":["id","name","deltaNet","deltaPvp","lineIds"],"additionalProperties":false}}},"required":["currency","net","marginAmount","total","finalPrice","perPax","finalMargin","packages"],"additionalProperties":false},"textOverrides":{"type":"object","additionalProperties":{"type":"string"}},"imageOverrides":{"type":"object","additionalProperties":{"type":"string"}},"sentAt":{"type":["string","null"]},"modifiedSinceSent":{"type":"boolean"},"acceptedAt":{"type":["string","null"]},"acceptedVia":{"anyOf":[{"type":"string","enum":["prospect_link","agent"]},{"type":"null"}]},"acceptedPackageId":{"type":["string","null"]},"acceptedLineIds":{"type":"array","items":{"type":"string"}},"acceptance":{"anyOf":[{"type":"object","properties":{"name":{"type":["string","null"]},"email":{"type":["string","null"]},"phone":{"type":["string","null"]},"message":{"type":["string","null"]}},"required":["name","email","phone","message"],"additionalProperties":false},{"type":"null"}],"description":"What the customer typed when accepting on the quote page — personal data: present only for a key holding `travelers:read`, only on quote reads (a write's response carries null; read the quote), and every such read is audited."},"engagement":{"type":"object","properties":{"views":{"type":"integer"},"uniqueSessions":{"type":"integer"},"activeSeconds":{"type":"integer"},"ctaClicks":{"type":"integer"},"maxScrollPct":{"type":"number"},"sectionsSeen":{"type":"integer"},"interactions":{"type":"integer"},"lastSeenAt":{"type":["string","null"]},"lastCtaAt":{"type":["string","null"]}},"required":["views","uniqueSessions","activeSeconds","ctaClicks","maxScrollPct","sectionsSeen","interactions","lastSeenAt","lastCtaAt"],"additionalProperties":false},"metadata":{"type":"object","additionalProperties":{"type":"string","maxLength":500},"propertyNames":{"pattern":"^[A-Za-z0-9_.-]{1,40}$"}},"appUrl":{"type":["string","null"]},"publicUrl":{"type":["string","null"]},"createdAt":{"type":"string"},"updatedAt":{"type":"string"}},"required":["object","id","tripId","code","name","mode","status","travelers","marginPct","finalPriceOverride","validUntil","ctaUrl","templateId","packages","lines","totals","textOverrides","imageOverrides","sentAt","modifiedSinceSent","acceptedAt","acceptedVia","acceptedPackageId","acceptedLineIds","acceptance","engagement","metadata","appUrl","publicUrl","createdAt","updatedAt"],"additionalProperties":false}}}},"default":{"description":"Error (RFC 9457)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{},"required":[],"additionalProperties":false}}}}}},"/documents":{"get":{"operationId":"documents.list","summary":"List documents","description":"Lists the agency's documents on live trips, most recently changed first. Filter by `tripId`, `folderId` (`none` = loose), `visibility` and `updatedSince`. For a 'new or changed document' polling trigger (n8n, Zapier), pass the last `updatedAt` you saw as `updatedSince` with `sort=updatedAt`: an upload, a rename, a move and a release to travelers all move `updatedAt`. Uploads that were never completed are not listed. Follow `nextCursor` until it is null.\n\n**Permissions:** `documents:read`.","tags":["Documents"],"x-scopes":["documents:read"],"x-undo":"none","parameters":[{"name":"tripId","in":"query","required":false,"schema":{"type":"string","format":"uuid"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":100,"default":25}},{"name":"cursor","in":"query","required":false,"schema":{"type":"string","minLength":1,"maxLength":500}},{"name":"sort","in":"query","required":false,"schema":{"type":"string","enum":["updatedAt","-updatedAt","createdAt","-createdAt"],"default":"-updatedAt"}},{"name":"folderId","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"uuid"},{"type":"string","const":"none"}],"description":"One folder's documents; `none` = the loose ones (in no folder)."}},{"name":"visibility","in":"query","required":false,"schema":{"type":"string","enum":["staff","traveler"]}},{"name":"updatedSince","in":"query","required":false,"schema":{"type":"string","format":"date-time"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"object":{"type":"string","const":"list"},"data":{"type":"array","items":{"type":"object","properties":{"object":{"type":"string","const":"document"},"id":{"type":"string","format":"uuid"},"tripId":{"type":"string","format":"uuid"},"folderId":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"description":"The folder it is filed in; null = loose (in no folder)."},"name":{"type":"string"},"mimeType":{"type":"string"},"byteSize":{"type":"integer","minimum":0},"status":{"type":"string","enum":["pending","ready"],"description":"`pending`: reserved, the upload is not complete — never listed. `ready`: a document."},"visibility":{"type":"string","enum":["staff","traveler"],"description":"`staff`: internal, only the agency sees it. `traveler`: released to the trip's travelers."},"visibleToTravelersNow":{"type":"boolean","description":"Released AND the trip is published: the traveler's app shows it right now."},"visibleAt":{"type":["string","null"],"description":"When it was last released to travelers; null while internal."},"visibleBy":{"anyOf":[{"type":"object","properties":{"id":{"type":"string"},"name":{"type":["string","null"]}},"required":["id","name"],"additionalProperties":false},{"type":"null"}]},"uploadedBy":{"anyOf":[{"type":"object","properties":{"id":{"type":"string"},"name":{"type":["string","null"]}},"required":["id","name"],"additionalProperties":false},{"type":"null"}]},"createdAt":{"type":"string"},"updatedAt":{"type":"string"},"appUrl":{"type":["string","null"],"description":"The trip's Documents tab in bymundi."}},"required":["object","id","tripId","folderId","name","mimeType","byteSize","status","visibility","visibleToTravelersNow","visibleAt","visibleBy","uploadedBy","createdAt","updatedAt","appUrl"],"additionalProperties":false}},"nextCursor":{"type":["string","null"]}},"required":["object","data","nextCursor"],"additionalProperties":false}}}},"default":{"description":"Error (RFC 9457)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/trips/{tripId}/documents":{"get":{"operationId":"documents.listForTrip","summary":"List a trip's documents","description":"Lists one trip's documents as its Documents tab shows them — the same filters as GET /documents. `visibility: staff` is the internal zone, `traveler` the documents released to travelers; `visibleToTravelersNow` says whether the traveler's app shows one right now (released AND the trip published). Folders are at GET /trips/{tripId}/document-folders. Another agency's trip, an archived one and a catalog working copy are a 404.\n\n**Permissions:** `documents:read`.","tags":["Documents"],"x-scopes":["documents:read"],"x-undo":"none","parameters":[{"name":"tripId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":100,"default":25}},{"name":"cursor","in":"query","required":false,"schema":{"type":"string","minLength":1,"maxLength":500}},{"name":"sort","in":"query","required":false,"schema":{"type":"string","enum":["updatedAt","-updatedAt","createdAt","-createdAt"],"default":"-updatedAt"}},{"name":"folderId","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"uuid"},{"type":"string","const":"none"}],"description":"One folder's documents; `none` = the loose ones (in no folder)."}},{"name":"visibility","in":"query","required":false,"schema":{"type":"string","enum":["staff","traveler"]}},{"name":"updatedSince","in":"query","required":false,"schema":{"type":"string","format":"date-time"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"object":{"type":"string","const":"list"},"data":{"type":"array","items":{"type":"object","properties":{"object":{"type":"string","const":"document"},"id":{"type":"string","format":"uuid"},"tripId":{"type":"string","format":"uuid"},"folderId":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"description":"The folder it is filed in; null = loose (in no folder)."},"name":{"type":"string"},"mimeType":{"type":"string"},"byteSize":{"type":"integer","minimum":0},"status":{"type":"string","enum":["pending","ready"],"description":"`pending`: reserved, the upload is not complete — never listed. `ready`: a document."},"visibility":{"type":"string","enum":["staff","traveler"],"description":"`staff`: internal, only the agency sees it. `traveler`: released to the trip's travelers."},"visibleToTravelersNow":{"type":"boolean","description":"Released AND the trip is published: the traveler's app shows it right now."},"visibleAt":{"type":["string","null"],"description":"When it was last released to travelers; null while internal."},"visibleBy":{"anyOf":[{"type":"object","properties":{"id":{"type":"string"},"name":{"type":["string","null"]}},"required":["id","name"],"additionalProperties":false},{"type":"null"}]},"uploadedBy":{"anyOf":[{"type":"object","properties":{"id":{"type":"string"},"name":{"type":["string","null"]}},"required":["id","name"],"additionalProperties":false},{"type":"null"}]},"createdAt":{"type":"string"},"updatedAt":{"type":"string"},"appUrl":{"type":["string","null"],"description":"The trip's Documents tab in bymundi."}},"required":["object","id","tripId","folderId","name","mimeType","byteSize","status","visibility","visibleToTravelersNow","visibleAt","visibleBy","uploadedBy","createdAt","updatedAt","appUrl"],"additionalProperties":false}},"nextCursor":{"type":["string","null"]}},"required":["object","data","nextCursor"],"additionalProperties":false}}}},"default":{"description":"Error (RFC 9457)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"post":{"operationId":"documents.startUpload","summary":"Start a document upload","description":"Reserves a document on a trip and returns a single-use upload URL (valid 2 hours). Then PUT the file's bytes to `upload.url` with exactly `upload.headers` — no Authorization header — and call POST /documents/{documentId}/complete. Until completed the document is `pending`: invisible, never listed, and removed after 24 hours. The size and type recorded are what actually arrives, not what you declare here. Up to 5 MB; the accepted types are the enum of `mimeType`.\n\n**Permissions:** `documents:write`.","tags":["Documents"],"x-scopes":["documents:write"],"x-undo":"none","parameters":[{"name":"tripId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"$ref":"#/components/parameters/IdempotencyKey"}],"responses":{"201":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"object":{"type":"string","const":"document_upload"},"document":{"type":"object","properties":{"object":{"type":"string","const":"document"},"id":{"type":"string","format":"uuid"},"tripId":{"type":"string","format":"uuid"},"folderId":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"description":"The folder it is filed in; null = loose (in no folder)."},"name":{"type":"string"},"mimeType":{"type":"string"},"byteSize":{"type":"integer","minimum":0},"status":{"type":"string","enum":["pending","ready"],"description":"`pending`: reserved, the upload is not complete — never listed. `ready`: a document."},"visibility":{"type":"string","enum":["staff","traveler"],"description":"`staff`: internal, only the agency sees it. `traveler`: released to the trip's travelers."},"visibleToTravelersNow":{"type":"boolean","description":"Released AND the trip is published: the traveler's app shows it right now."},"visibleAt":{"type":["string","null"],"description":"When it was last released to travelers; null while internal."},"visibleBy":{"anyOf":[{"type":"object","properties":{"id":{"type":"string"},"name":{"type":["string","null"]}},"required":["id","name"],"additionalProperties":false},{"type":"null"}]},"uploadedBy":{"anyOf":[{"type":"object","properties":{"id":{"type":"string"},"name":{"type":["string","null"]}},"required":["id","name"],"additionalProperties":false},{"type":"null"}]},"createdAt":{"type":"string"},"updatedAt":{"type":"string"},"appUrl":{"type":["string","null"],"description":"The trip's Documents tab in bymundi."}},"required":["object","id","tripId","folderId","name","mimeType","byteSize","status","visibility","visibleToTravelersNow","visibleAt","visibleBy","uploadedBy","createdAt","updatedAt","appUrl"],"additionalProperties":false},"upload":{"type":"object","properties":{"method":{"type":"string","const":"PUT"},"url":{"type":"string","format":"uri","description":"Single-use: PUT the file's bytes here once."},"headers":{"type":"object","additionalProperties":{"type":"string"},"description":"Send exactly these headers with the PUT."},"expiresAt":{"type":"string"}},"required":["method","url","headers","expiresAt"],"additionalProperties":false}},"required":["object","document","upload"],"additionalProperties":false}}}},"default":{"description":"Error (RFC 9457)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":200,"description":"The name shown in bymundi, with its extension (e.g. 'Kyoto hotel voucher.pdf')."},"mimeType":{"type":"string","enum":["application/pdf","image/png","image/jpeg","image/webp","image/gif","application/msword","application/vnd.openxmlformats-officedocument.wordprocessingml.document","application/vnd.ms-excel","application/vnd.openxmlformats-officedocument.spreadsheetml.sheet","application/vnd.ms-powerpoint","application/vnd.openxmlformats-officedocument.presentationml.presentation","text/plain","text/csv","application/zip"],"description":"The file's type — only these are accepted."},"byteSize":{"type":"integer","minimum":1,"maximum":5242880,"description":"The file's size in bytes (at most 5 MB)."}},"required":["name","mimeType","byteSize"],"additionalProperties":false}}}}}},"/documents/{documentId}":{"get":{"operationId":"documents.get","summary":"Get a document","description":"Returns one document — also a `pending` one, so you can check an upload you started. Its bytes are at GET /documents/{documentId}/download.\n\n**Permissions:** `documents:read`.","tags":["Documents"],"x-scopes":["documents:read"],"x-undo":"none","parameters":[{"name":"documentId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"object":{"type":"string","const":"document"},"id":{"type":"string","format":"uuid"},"tripId":{"type":"string","format":"uuid"},"folderId":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"description":"The folder it is filed in; null = loose (in no folder)."},"name":{"type":"string"},"mimeType":{"type":"string"},"byteSize":{"type":"integer","minimum":0},"status":{"type":"string","enum":["pending","ready"],"description":"`pending`: reserved, the upload is not complete — never listed. `ready`: a document."},"visibility":{"type":"string","enum":["staff","traveler"],"description":"`staff`: internal, only the agency sees it. `traveler`: released to the trip's travelers."},"visibleToTravelersNow":{"type":"boolean","description":"Released AND the trip is published: the traveler's app shows it right now."},"visibleAt":{"type":["string","null"],"description":"When it was last released to travelers; null while internal."},"visibleBy":{"anyOf":[{"type":"object","properties":{"id":{"type":"string"},"name":{"type":["string","null"]}},"required":["id","name"],"additionalProperties":false},{"type":"null"}]},"uploadedBy":{"anyOf":[{"type":"object","properties":{"id":{"type":"string"},"name":{"type":["string","null"]}},"required":["id","name"],"additionalProperties":false},{"type":"null"}]},"createdAt":{"type":"string"},"updatedAt":{"type":"string"},"appUrl":{"type":["string","null"],"description":"The trip's Documents tab in bymundi."}},"required":["object","id","tripId","folderId","name","mimeType","byteSize","status","visibility","visibleToTravelersNow","visibleAt","visibleBy","uploadedBy","createdAt","updatedAt","appUrl"],"additionalProperties":false}}}},"default":{"description":"Error (RFC 9457)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"patch":{"operationId":"documents.update","summary":"Update a document","description":"Renames a document, releases it to the trip's travelers (`visibility: traveler`) or takes it back to internal (`staff`), and files it in a folder (`folderId`; null = loose) — the Documents tab's Make visible, Back to internal and Move to folder, in one write. Travelers see a released document only while the trip is published (`visibleToTravelersNow`). Pass the `updatedAt` you read, exactly as you read it, as `expectedUpdatedAt` to refuse a stale write with a 409. Undo with POST /changes/{changeId}/revert.\n\n**Permissions:** `documents:write`.\n\n**Undo:** the response carries `Bymundi-Change-Id`; `POST /changes/{changeId}/revert` undoes it.","tags":["Documents"],"x-scopes":["documents:write"],"x-undo":"change","parameters":[{"name":"documentId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"$ref":"#/components/parameters/IdempotencyKey"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"object":{"type":"string","const":"document"},"id":{"type":"string","format":"uuid"},"tripId":{"type":"string","format":"uuid"},"folderId":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"description":"The folder it is filed in; null = loose (in no folder)."},"name":{"type":"string"},"mimeType":{"type":"string"},"byteSize":{"type":"integer","minimum":0},"status":{"type":"string","enum":["pending","ready"],"description":"`pending`: reserved, the upload is not complete — never listed. `ready`: a document."},"visibility":{"type":"string","enum":["staff","traveler"],"description":"`staff`: internal, only the agency sees it. `traveler`: released to the trip's travelers."},"visibleToTravelersNow":{"type":"boolean","description":"Released AND the trip is published: the traveler's app shows it right now."},"visibleAt":{"type":["string","null"],"description":"When it was last released to travelers; null while internal."},"visibleBy":{"anyOf":[{"type":"object","properties":{"id":{"type":"string"},"name":{"type":["string","null"]}},"required":["id","name"],"additionalProperties":false},{"type":"null"}]},"uploadedBy":{"anyOf":[{"type":"object","properties":{"id":{"type":"string"},"name":{"type":["string","null"]}},"required":["id","name"],"additionalProperties":false},{"type":"null"}]},"createdAt":{"type":"string"},"updatedAt":{"type":"string"},"appUrl":{"type":["string","null"],"description":"The trip's Documents tab in bymundi."}},"required":["object","id","tripId","folderId","name","mimeType","byteSize","status","visibility","visibleToTravelersNow","visibleAt","visibleBy","uploadedBy","createdAt","updatedAt","appUrl"],"additionalProperties":false}}}},"default":{"description":"Error (RFC 9457)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":200,"description":"The name shown in bymundi, with its extension (e.g. 'Kyoto hotel voucher.pdf')."},"visibility":{"type":"string","enum":["staff","traveler"]},"folderId":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"description":"A folder of the same trip; null = loose (in no folder)."},"expectedUpdatedAt":{"type":"string","format":"date-time","description":"The document's `updatedAt` as you read it."}},"required":[],"additionalProperties":false}}}}},"delete":{"operationId":"documents.delete","summary":"Delete a document","description":"Deletes a document and its file, as the Documents tab's Delete does. It cannot be undone, so `confirm` (a query parameter) must be the document's exact name. To hide a document from travelers without deleting it, PATCH it to `visibility: staff`.\n\n**Permissions:** `documents:write`.","tags":["Documents"],"x-scopes":["documents:write"],"x-undo":"none","parameters":[{"name":"documentId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"confirm","in":"query","required":true,"schema":{"type":"string","minLength":1,"maxLength":200,"description":"The document's exact name."}},{"$ref":"#/components/parameters/IdempotencyKey"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"object":{"type":"string","const":"document"},"id":{"type":"string","format":"uuid"},"deleted":{"type":"boolean","const":true}},"required":["object","id","deleted"],"additionalProperties":false}}}},"default":{"description":"Error (RFC 9457)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/documents/{documentId}/download":{"get":{"operationId":"documents.download","summary":"Get a document's download link","description":"Returns a signed link, valid for 5 minutes, that downloads the file under its name (an n8n HTTP Request node can fetch it as binary). A `pending` document is a 409 `upload_incomplete`.\n\n**Permissions:** `documents:read`.","tags":["Documents"],"x-scopes":["documents:read"],"x-undo":"none","parameters":[{"name":"documentId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"object":{"type":"string","const":"document_download"},"documentId":{"type":"string","format":"uuid"},"name":{"type":"string"},"mimeType":{"type":"string"},"byteSize":{"type":"integer","minimum":0},"url":{"type":"string","format":"uri","description":"A signed link that downloads the file as `name`."},"expiresAt":{"type":"string"}},"required":["object","documentId","name","mimeType","byteSize","url","expiresAt"],"additionalProperties":false}}}},"default":{"description":"Error (RFC 9457)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/documents/{documentId}/complete":{"post":{"operationId":"documents.completeUpload","summary":"Complete a document upload","description":"Completes an upload after its bytes were PUT: the document appears in the trip's Documents tab — internal (`visibility: staff`) unless you release it with `visibility: traveler`, optionally into a folder (`folderId`), as dropping a file on a visible folder does. The recorded size and type are the ones storage received. Nothing uploaded yet is a 422 `upload_missing`; a second completion a 409 `already_complete`. Undo with POST /changes/{changeId}/revert: it deletes the upload while nobody has changed it since.\n\n**Permissions:** `documents:write`.\n\n**Undo:** the response carries `Bymundi-Change-Id`; `POST /changes/{changeId}/revert` undoes it.","tags":["Documents"],"x-scopes":["documents:write"],"x-undo":"change","parameters":[{"name":"documentId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"$ref":"#/components/parameters/IdempotencyKey"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"object":{"type":"string","const":"document"},"id":{"type":"string","format":"uuid"},"tripId":{"type":"string","format":"uuid"},"folderId":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"description":"The folder it is filed in; null = loose (in no folder)."},"name":{"type":"string"},"mimeType":{"type":"string"},"byteSize":{"type":"integer","minimum":0},"status":{"type":"string","enum":["pending","ready"],"description":"`pending`: reserved, the upload is not complete — never listed. `ready`: a document."},"visibility":{"type":"string","enum":["staff","traveler"],"description":"`staff`: internal, only the agency sees it. `traveler`: released to the trip's travelers."},"visibleToTravelersNow":{"type":"boolean","description":"Released AND the trip is published: the traveler's app shows it right now."},"visibleAt":{"type":["string","null"],"description":"When it was last released to travelers; null while internal."},"visibleBy":{"anyOf":[{"type":"object","properties":{"id":{"type":"string"},"name":{"type":["string","null"]}},"required":["id","name"],"additionalProperties":false},{"type":"null"}]},"uploadedBy":{"anyOf":[{"type":"object","properties":{"id":{"type":"string"},"name":{"type":["string","null"]}},"required":["id","name"],"additionalProperties":false},{"type":"null"}]},"createdAt":{"type":"string"},"updatedAt":{"type":"string"},"appUrl":{"type":["string","null"],"description":"The trip's Documents tab in bymundi."}},"required":["object","id","tripId","folderId","name","mimeType","byteSize","status","visibility","visibleToTravelersNow","visibleAt","visibleBy","uploadedBy","createdAt","updatedAt","appUrl"],"additionalProperties":false}}}},"default":{"description":"Error (RFC 9457)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"visibility":{"type":"string","enum":["staff","traveler"],"default":"staff","description":"`staff` (the default) keeps it internal; `traveler` releases it to the trip's travelers."},"folderId":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"description":"File it in this folder of the trip; null or absent = loose."}},"required":[],"additionalProperties":false}}}}}},"/trips/{tripId}/document-folders":{"get":{"operationId":"documents.folders.list","summary":"List a trip's document folders","description":"Lists a trip's document folders by name, each with how many documents it holds, in one page. Documents name their folder in `folderId`.\n\n**Permissions:** `documents:read`.","tags":["Documents"],"x-scopes":["documents:read"],"x-undo":"none","parameters":[{"name":"tripId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"object":{"type":"string","const":"list"},"data":{"type":"array","items":{"type":"object","properties":{"object":{"type":"string","const":"document_folder"},"id":{"type":"string","format":"uuid"},"tripId":{"type":"string","format":"uuid"},"name":{"type":"string"},"documentCount":{"type":"integer","minimum":0,"description":"Ready documents filed in it."},"createdAt":{"type":"string"}},"required":["object","id","tripId","name","documentCount","createdAt"],"additionalProperties":false}},"nextCursor":{"type":["string","null"]}},"required":["object","data","nextCursor"],"additionalProperties":false}}}},"default":{"description":"Error (RFC 9457)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"post":{"operationId":"documents.folders.create","summary":"Create a document folder","description":"Creates a folder in a trip's documents, as New folder does. File documents into it with PATCH /documents/{documentId}. Undo with POST /changes/{changeId}/revert while it is still empty.\n\n**Permissions:** `documents:write`.\n\n**Undo:** the response carries `Bymundi-Change-Id`; `POST /changes/{changeId}/revert` undoes it.","tags":["Documents"],"x-scopes":["documents:write"],"x-undo":"change","parameters":[{"name":"tripId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"$ref":"#/components/parameters/IdempotencyKey"}],"responses":{"201":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"object":{"type":"string","const":"document_folder"},"id":{"type":"string","format":"uuid"},"tripId":{"type":"string","format":"uuid"},"name":{"type":"string"},"documentCount":{"type":"integer","minimum":0,"description":"Ready documents filed in it."},"createdAt":{"type":"string"}},"required":["object","id","tripId","name","documentCount","createdAt"],"additionalProperties":false}}}},"default":{"description":"Error (RFC 9457)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":200,"description":"As travelers will see it, e.g. 'Flights', 'Hotels', 'Insurance'."}},"required":["name"],"additionalProperties":false}}}}}},"/document-folders/{folderId}":{"patch":{"operationId":"documents.folders.update","summary":"Rename a document folder","description":"Renames one of a trip's document folders. Undo with POST /changes/{changeId}/revert.\n\n**Permissions:** `documents:write`.\n\n**Undo:** the response carries `Bymundi-Change-Id`; `POST /changes/{changeId}/revert` undoes it.","tags":["Documents"],"x-scopes":["documents:write"],"x-undo":"change","parameters":[{"name":"folderId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"$ref":"#/components/parameters/IdempotencyKey"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"object":{"type":"string","const":"document_folder"},"id":{"type":"string","format":"uuid"},"tripId":{"type":"string","format":"uuid"},"name":{"type":"string"},"documentCount":{"type":"integer","minimum":0,"description":"Ready documents filed in it."},"createdAt":{"type":"string"}},"required":["object","id","tripId","name","documentCount","createdAt"],"additionalProperties":false}}}},"default":{"description":"Error (RFC 9457)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":200,"description":"As travelers will see it, e.g. 'Flights', 'Hotels', 'Insurance'."}},"required":["name"],"additionalProperties":false}}}}},"delete":{"operationId":"documents.folders.delete","summary":"Delete a document folder","description":"Deletes a document folder, as Delete folder does. Its documents are NOT deleted: they become loose (in no folder) and keep their visibility. Undo with POST /changes/{changeId}/revert: it re-creates the folder and files back the documents that are still loose.\n\n**Permissions:** `documents:write`.\n\n**Undo:** the response carries `Bymundi-Change-Id`; `POST /changes/{changeId}/revert` undoes it.","tags":["Documents"],"x-scopes":["documents:write"],"x-undo":"change","parameters":[{"name":"folderId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"$ref":"#/components/parameters/IdempotencyKey"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"object":{"type":"string","const":"document_folder"},"id":{"type":"string","format":"uuid"},"deleted":{"type":"boolean","const":true},"documentsMoved":{"type":"integer","minimum":0,"description":"Documents that were in it and are now loose — none is ever deleted with a folder."}},"required":["object","id","deleted","documentsMoved"],"additionalProperties":false}}}},"default":{"description":"Error (RFC 9457)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/trips/{tripId}/travelers":{"get":{"operationId":"travelers.roster.get","summary":"Get a trip's travelers","description":"The trip's passengers in booking order (`position` 0 first) with every field the Travelers card shows — names, birth date, nationality, identity document, contact details — plus each one's `missing` ticketing fields and app `access`; the booking contact; the contracted `headcount` and a summary. Personal data: every call is recorded in the audit log.\n\n**Permissions:** `travelers:read`.","tags":["Travelers"],"x-scopes":["travelers:read"],"x-undo":"none","parameters":[{"name":"tripId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"object":{"type":"string","const":"traveler_roster"},"tripId":{"type":"string","format":"uuid"},"commercialState":{"type":"string"},"headcount":{"type":"integer"},"accessOpen":{"type":"boolean"},"summary":{"type":"object","properties":{"total":{"type":"integer"},"complete":{"type":"integer"},"emptySlots":{"type":"integer"},"pax":{"type":"object","properties":{"adult":{"type":"integer"},"child":{"type":"integer"},"infant":{"type":"integer"},"unknown":{"type":"integer"}},"required":["adult","child","infant","unknown"],"additionalProperties":false}},"required":["total","complete","emptySlots","pax"],"additionalProperties":false},"passengers":{"type":"array","items":{"type":"object","properties":{"object":{"type":"string","const":"traveler"},"id":{"type":"string","format":"uuid"},"tripId":{"type":"string","format":"uuid"},"position":{"type":"integer"},"title":{"anyOf":[{"type":"string","enum":["mr","mrs","ms","mstr","miss"]},{"type":"null"}]},"firstName":{"type":["string","null"]},"lastName1":{"type":["string","null"]},"lastName2":{"type":["string","null"]},"birthDate":{"type":["string","null"]},"sex":{"anyOf":[{"type":"string","enum":["m","f"]},{"type":"null"}]},"nationality":{"type":["string","null"]},"docType":{"anyOf":[{"type":"string","enum":["dni","nie","passport","other"]},{"type":"null"}]},"docNumber":{"type":["string","null"]},"docExpiry":{"type":["string","null"]},"docCountry":{"type":["string","null"]},"email":{"type":["string","null"]},"phone":{"type":["string","null"]},"address":{"anyOf":[{"type":"object","properties":{"line1":{"anyOf":[{"type":"string","maxLength":120},{"type":"null"}]},"line2":{"anyOf":[{"type":"string","maxLength":120},{"type":"null"}]},"postalCode":{"anyOf":[{"type":"string","maxLength":20},{"type":"null"}]},"city":{"anyOf":[{"type":"string","maxLength":80},{"type":"null"}]},"region":{"anyOf":[{"type":"string","maxLength":80},{"type":"null"}]},"country":{"anyOf":[{"type":"string","pattern":"^[A-Z]{2}$"},{"type":"null"}]}},"required":["line1","line2","postalCode","city","region","country"],"additionalProperties":false},{"type":"null"}]},"taxId":{"type":["string","null"]},"paxType":{"type":"string","enum":["adult","child","infant","unknown"]},"missing":{"type":"array","items":{"type":"string"}},"access":{"anyOf":[{"type":"string","enum":["invited","queued","failed","no_email","not_yet"]},{"type":"null"}]},"source":{"type":"string"},"consentAt":{"type":["string","null"]},"docsPurgedAt":{"type":["string","null"]},"createdAt":{"type":"string"},"updatedAt":{"type":"string"}},"required":["object","id","tripId","position","title","firstName","lastName1","lastName2","birthDate","sex","nationality","docType","docNumber","docExpiry","docCountry","email","phone","address","taxId","paxType","missing","access","source","consentAt","docsPurgedAt","createdAt","updatedAt"],"additionalProperties":false}},"contact":{"anyOf":[{"type":"object","properties":{"object":{"type":"string","const":"trip_contact"},"tripId":{"type":"string","format":"uuid"},"name":{"type":["string","null"]},"email":{"type":["string","null"]},"phone":{"type":["string","null"]},"address":{"anyOf":[{"type":"object","properties":{"line1":{"anyOf":[{"type":"string","maxLength":120},{"type":"null"}]},"line2":{"anyOf":[{"type":"string","maxLength":120},{"type":"null"}]},"postalCode":{"anyOf":[{"type":"string","maxLength":20},{"type":"null"}]},"city":{"anyOf":[{"type":"string","maxLength":80},{"type":"null"}]},"region":{"anyOf":[{"type":"string","maxLength":80},{"type":"null"}]},"country":{"anyOf":[{"type":"string","pattern":"^[A-Z]{2}$"},{"type":"null"}]}},"required":["line1","line2","postalCode","city","region","country"],"additionalProperties":false},{"type":"null"}]},"docType":{"anyOf":[{"type":"string","enum":["dni","nie","passport","other"]},{"type":"null"}]},"docNumber":{"type":["string","null"]},"docCountry":{"type":["string","null"]},"taxId":{"type":["string","null"]},"account":{"type":"object","properties":{"userId":{"type":"string","format":"uuid"},"email":{"type":["string","null"]},"name":{"type":["string","null"]}},"required":["userId","email","name"],"additionalProperties":false},"access":{"anyOf":[{"type":"string","enum":["invited","queued","failed","no_email","not_yet"]},{"type":"null"}]},"accessOpenedAt":{"type":["string","null"]}},"required":["object","tripId","name","email","phone","address","docType","docNumber","docCountry","taxId","account","access","accessOpenedAt"],"additionalProperties":false},{"type":"null"}]},"mailQueueStaleMinutes":{"anyOf":[{"type":"integer"},{"type":"null"}]}},"required":["object","tripId","commercialState","headcount","accessOpen","summary","passengers","contact","mailQueueStaleMinutes"],"additionalProperties":false}}}},"default":{"description":"Error (RFC 9457)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"post":{"operationId":"travelers.add","summary":"Add a traveler","description":"Adds one passenger to the trip, last unless `position` says otherwise (0 = first). Any field may be sent; the whole passenger is validated as the Travelers drawer does. The trip's `travelers` headcount caps the roster (422 `pax_exceeded`: raise it with PATCH /trips/{tripId} first). A trip still `nueva`, `propuesta_enviada` or `rechazada` with no passengers takes none (422 `roster_locked`). On a `reservada` trip a passenger with a new email gets the app-access email. Undo with POST /changes/{changeId}/revert within 30 days, while nobody has edited the passenger since. An access email the write queued is not recalled.\n\n**Permissions:** `travelers:write`.\n\n**Undo:** the response carries `Bymundi-Change-Id`; `POST /changes/{changeId}/revert` undoes it.","tags":["Travelers"],"x-scopes":["travelers:write"],"x-undo":"change","parameters":[{"name":"tripId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"$ref":"#/components/parameters/IdempotencyKey"}],"responses":{"201":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"object":{"type":"string","const":"traveler"},"id":{"type":"string","format":"uuid"},"tripId":{"type":"string","format":"uuid"},"position":{"type":"integer"},"title":{"anyOf":[{"type":"string","enum":["mr","mrs","ms","mstr","miss"]},{"type":"null"}]},"firstName":{"type":["string","null"]},"lastName1":{"type":["string","null"]},"lastName2":{"type":["string","null"]},"birthDate":{"type":["string","null"]},"sex":{"anyOf":[{"type":"string","enum":["m","f"]},{"type":"null"}]},"nationality":{"type":["string","null"]},"docType":{"anyOf":[{"type":"string","enum":["dni","nie","passport","other"]},{"type":"null"}]},"docNumber":{"type":["string","null"]},"docExpiry":{"type":["string","null"]},"docCountry":{"type":["string","null"]},"email":{"type":["string","null"]},"phone":{"type":["string","null"]},"address":{"anyOf":[{"type":"object","properties":{"line1":{"anyOf":[{"type":"string","maxLength":120},{"type":"null"}]},"line2":{"anyOf":[{"type":"string","maxLength":120},{"type":"null"}]},"postalCode":{"anyOf":[{"type":"string","maxLength":20},{"type":"null"}]},"city":{"anyOf":[{"type":"string","maxLength":80},{"type":"null"}]},"region":{"anyOf":[{"type":"string","maxLength":80},{"type":"null"}]},"country":{"anyOf":[{"type":"string","pattern":"^[A-Z]{2}$"},{"type":"null"}]}},"required":["line1","line2","postalCode","city","region","country"],"additionalProperties":false},{"type":"null"}]},"taxId":{"type":["string","null"]},"paxType":{"type":"string","enum":["adult","child","infant","unknown"]},"missing":{"type":"array","items":{"type":"string"}},"access":{"anyOf":[{"type":"string","enum":["invited","queued","failed","no_email","not_yet"]},{"type":"null"}]},"source":{"type":"string"},"consentAt":{"type":["string","null"]},"docsPurgedAt":{"type":["string","null"]},"createdAt":{"type":"string"},"updatedAt":{"type":"string"}},"required":["object","id","tripId","position","title","firstName","lastName1","lastName2","birthDate","sex","nationality","docType","docNumber","docExpiry","docCountry","email","phone","address","taxId","paxType","missing","access","source","consentAt","docsPurgedAt","createdAt","updatedAt"],"additionalProperties":false}}}},"default":{"description":"Error (RFC 9457)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"position":{"type":"integer","minimum":0,"maximum":39,"description":"0 = first on the booking. Past the end = last."},"title":{"anyOf":[{"type":"string","enum":["mr","mrs","ms","mstr","miss"]},{"type":"null"}],"description":"Form of address; the app derives one from sex and age when empty."},"firstName":{"anyOf":[{"type":"string","maxLength":80},{"type":"null"}]},"lastName1":{"anyOf":[{"type":"string","maxLength":80},{"type":"null"}],"description":"Surname(s) as on the passport — the app asks for both surnames here."},"lastName2":{"anyOf":[{"type":"string","maxLength":80},{"type":"null"}],"description":"A second surname stored separately (older passengers); usually null."},"birthDate":{"anyOf":[{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$"},{"type":"null"}]},"sex":{"anyOf":[{"type":"string","enum":["m","f"]},{"type":"null"}]},"nationality":{"anyOf":[{"type":"string","pattern":"^[A-Z]{2}$"},{"type":"null"}]},"docType":{"anyOf":[{"type":"string","enum":["dni","nie","passport","other"]},{"type":"null"}]},"docNumber":{"anyOf":[{"type":"string","maxLength":40},{"type":"null"}]},"docExpiry":{"anyOf":[{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$"},{"type":"null"}]},"docCountry":{"anyOf":[{"type":"string","pattern":"^[A-Z]{2}$"},{"type":"null"}],"description":"The country that issued the document."},"email":{"anyOf":[{"type":"string","format":"email","maxLength":200},{"type":"null"}]},"phone":{"anyOf":[{"type":"string","maxLength":40},{"type":"null"}]},"address":{"anyOf":[{"type":"object","properties":{"line1":{"anyOf":[{"type":"string","maxLength":120},{"type":"null"}]},"line2":{"anyOf":[{"type":"string","maxLength":120},{"type":"null"}]},"postalCode":{"anyOf":[{"type":"string","maxLength":20},{"type":"null"}]},"city":{"anyOf":[{"type":"string","maxLength":80},{"type":"null"}]},"region":{"anyOf":[{"type":"string","maxLength":80},{"type":"null"}]},"country":{"anyOf":[{"type":"string","pattern":"^[A-Z]{2}$"},{"type":"null"}]}},"required":["line1","line2","postalCode","city","region","country"],"additionalProperties":false},{"type":"null"}]},"taxId":{"anyOf":[{"type":"string","maxLength":20},{"type":"null"}]}},"required":[],"additionalProperties":false}}}}}},"/travelers/{travelerId}":{"get":{"operationId":"travelers.get","summary":"Get a traveler","description":"One passenger, with every field the Travelers drawer shows, `missing`, `paxType` and app `access`. Send its `updatedAt` as `expectedUpdatedAt` on a PATCH or DELETE to refuse a stale write. Personal data: audited.\n\n**Permissions:** `travelers:read`.","tags":["Travelers"],"x-scopes":["travelers:read"],"x-undo":"none","parameters":[{"name":"travelerId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"object":{"type":"string","const":"traveler"},"id":{"type":"string","format":"uuid"},"tripId":{"type":"string","format":"uuid"},"position":{"type":"integer"},"title":{"anyOf":[{"type":"string","enum":["mr","mrs","ms","mstr","miss"]},{"type":"null"}]},"firstName":{"type":["string","null"]},"lastName1":{"type":["string","null"]},"lastName2":{"type":["string","null"]},"birthDate":{"type":["string","null"]},"sex":{"anyOf":[{"type":"string","enum":["m","f"]},{"type":"null"}]},"nationality":{"type":["string","null"]},"docType":{"anyOf":[{"type":"string","enum":["dni","nie","passport","other"]},{"type":"null"}]},"docNumber":{"type":["string","null"]},"docExpiry":{"type":["string","null"]},"docCountry":{"type":["string","null"]},"email":{"type":["string","null"]},"phone":{"type":["string","null"]},"address":{"anyOf":[{"type":"object","properties":{"line1":{"anyOf":[{"type":"string","maxLength":120},{"type":"null"}]},"line2":{"anyOf":[{"type":"string","maxLength":120},{"type":"null"}]},"postalCode":{"anyOf":[{"type":"string","maxLength":20},{"type":"null"}]},"city":{"anyOf":[{"type":"string","maxLength":80},{"type":"null"}]},"region":{"anyOf":[{"type":"string","maxLength":80},{"type":"null"}]},"country":{"anyOf":[{"type":"string","pattern":"^[A-Z]{2}$"},{"type":"null"}]}},"required":["line1","line2","postalCode","city","region","country"],"additionalProperties":false},{"type":"null"}]},"taxId":{"type":["string","null"]},"paxType":{"type":"string","enum":["adult","child","infant","unknown"]},"missing":{"type":"array","items":{"type":"string"}},"access":{"anyOf":[{"type":"string","enum":["invited","queued","failed","no_email","not_yet"]},{"type":"null"}]},"source":{"type":"string"},"consentAt":{"type":["string","null"]},"docsPurgedAt":{"type":["string","null"]},"createdAt":{"type":"string"},"updatedAt":{"type":"string"}},"required":["object","id","tripId","position","title","firstName","lastName1","lastName2","birthDate","sex","nationality","docType","docNumber","docExpiry","docCountry","email","phone","address","taxId","paxType","missing","access","source","consentAt","docsPurgedAt","createdAt","updatedAt"],"additionalProperties":false}}}},"default":{"description":"Error (RFC 9457)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"patch":{"operationId":"travelers.update","summary":"Update a traveler","description":"Changes a passenger's fields — an absent field is unchanged, `null` clears it — and/or moves it (`position`). The resulting passenger is validated as the drawer does. Send `expectedUpdatedAt` (the `updatedAt` you read) to refuse with 409 if someone changed it since. Staff may correct any field in any state. On a `reservada` trip a new email gets the app-access email. Undo with POST /changes/{changeId}/revert within 30 days, while nobody has edited the passenger since. An access email the write queued is not recalled.\n\n**Permissions:** `travelers:write`.\n\n**Undo:** the response carries `Bymundi-Change-Id`; `POST /changes/{changeId}/revert` undoes it.","tags":["Travelers"],"x-scopes":["travelers:write"],"x-undo":"change","parameters":[{"name":"travelerId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"$ref":"#/components/parameters/IdempotencyKey"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"object":{"type":"string","const":"traveler"},"id":{"type":"string","format":"uuid"},"tripId":{"type":"string","format":"uuid"},"position":{"type":"integer"},"title":{"anyOf":[{"type":"string","enum":["mr","mrs","ms","mstr","miss"]},{"type":"null"}]},"firstName":{"type":["string","null"]},"lastName1":{"type":["string","null"]},"lastName2":{"type":["string","null"]},"birthDate":{"type":["string","null"]},"sex":{"anyOf":[{"type":"string","enum":["m","f"]},{"type":"null"}]},"nationality":{"type":["string","null"]},"docType":{"anyOf":[{"type":"string","enum":["dni","nie","passport","other"]},{"type":"null"}]},"docNumber":{"type":["string","null"]},"docExpiry":{"type":["string","null"]},"docCountry":{"type":["string","null"]},"email":{"type":["string","null"]},"phone":{"type":["string","null"]},"address":{"anyOf":[{"type":"object","properties":{"line1":{"anyOf":[{"type":"string","maxLength":120},{"type":"null"}]},"line2":{"anyOf":[{"type":"string","maxLength":120},{"type":"null"}]},"postalCode":{"anyOf":[{"type":"string","maxLength":20},{"type":"null"}]},"city":{"anyOf":[{"type":"string","maxLength":80},{"type":"null"}]},"region":{"anyOf":[{"type":"string","maxLength":80},{"type":"null"}]},"country":{"anyOf":[{"type":"string","pattern":"^[A-Z]{2}$"},{"type":"null"}]}},"required":["line1","line2","postalCode","city","region","country"],"additionalProperties":false},{"type":"null"}]},"taxId":{"type":["string","null"]},"paxType":{"type":"string","enum":["adult","child","infant","unknown"]},"missing":{"type":"array","items":{"type":"string"}},"access":{"anyOf":[{"type":"string","enum":["invited","queued","failed","no_email","not_yet"]},{"type":"null"}]},"source":{"type":"string"},"consentAt":{"type":["string","null"]},"docsPurgedAt":{"type":["string","null"]},"createdAt":{"type":"string"},"updatedAt":{"type":"string"}},"required":["object","id","tripId","position","title","firstName","lastName1","lastName2","birthDate","sex","nationality","docType","docNumber","docExpiry","docCountry","email","phone","address","taxId","paxType","missing","access","source","consentAt","docsPurgedAt","createdAt","updatedAt"],"additionalProperties":false}}}},"default":{"description":"Error (RFC 9457)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"position":{"type":"integer","minimum":0,"maximum":39,"description":"0 = first on the booking. Past the end = last."},"expectedUpdatedAt":{"type":"string","format":"date-time","description":"Refuse (409) unless the passenger still carries this `updatedAt`."},"title":{"anyOf":[{"type":"string","enum":["mr","mrs","ms","mstr","miss"]},{"type":"null"}],"description":"Form of address; the app derives one from sex and age when empty."},"firstName":{"anyOf":[{"type":"string","maxLength":80},{"type":"null"}]},"lastName1":{"anyOf":[{"type":"string","maxLength":80},{"type":"null"}],"description":"Surname(s) as on the passport — the app asks for both surnames here."},"lastName2":{"anyOf":[{"type":"string","maxLength":80},{"type":"null"}],"description":"A second surname stored separately (older passengers); usually null."},"birthDate":{"anyOf":[{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$"},{"type":"null"}]},"sex":{"anyOf":[{"type":"string","enum":["m","f"]},{"type":"null"}]},"nationality":{"anyOf":[{"type":"string","pattern":"^[A-Z]{2}$"},{"type":"null"}]},"docType":{"anyOf":[{"type":"string","enum":["dni","nie","passport","other"]},{"type":"null"}]},"docNumber":{"anyOf":[{"type":"string","maxLength":40},{"type":"null"}]},"docExpiry":{"anyOf":[{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$"},{"type":"null"}]},"docCountry":{"anyOf":[{"type":"string","pattern":"^[A-Z]{2}$"},{"type":"null"}],"description":"The country that issued the document."},"email":{"anyOf":[{"type":"string","format":"email","maxLength":200},{"type":"null"}]},"phone":{"anyOf":[{"type":"string","maxLength":40},{"type":"null"}]},"address":{"anyOf":[{"type":"object","properties":{"line1":{"anyOf":[{"type":"string","maxLength":120},{"type":"null"}]},"line2":{"anyOf":[{"type":"string","maxLength":120},{"type":"null"}]},"postalCode":{"anyOf":[{"type":"string","maxLength":20},{"type":"null"}]},"city":{"anyOf":[{"type":"string","maxLength":80},{"type":"null"}]},"region":{"anyOf":[{"type":"string","maxLength":80},{"type":"null"}]},"country":{"anyOf":[{"type":"string","pattern":"^[A-Z]{2}$"},{"type":"null"}]}},"required":["line1","line2","postalCode","city","region","country"],"additionalProperties":false},{"type":"null"}]},"taxId":{"anyOf":[{"type":"string","maxLength":20},{"type":"null"}]}},"required":[],"additionalProperties":false}}}}},"delete":{"operationId":"travelers.remove","summary":"Remove a traveler","description":"Removes a passenger from the trip, as the drawer's Delete does; the others close up the gap. Their app access, if any, is not revoked here — remove the booking contact for that. Undo with POST /changes/{changeId}/revert within 30 days, while its id is free and the headcount allows. An access email the write queued is not recalled.\n\n**Permissions:** `travelers:write`.\n\n**Undo:** the response carries `Bymundi-Change-Id`; `POST /changes/{changeId}/revert` undoes it.","tags":["Travelers"],"x-scopes":["travelers:write"],"x-undo":"change","parameters":[{"name":"travelerId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"expectedUpdatedAt","in":"query","required":false,"schema":{"type":"string","format":"date-time","description":"Refuse (409) unless the passenger still carries this `updatedAt`."}},{"$ref":"#/components/parameters/IdempotencyKey"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"object":{"type":"string","const":"traveler"},"id":{"type":"string","format":"uuid"},"tripId":{"type":"string","format":"uuid"},"deleted":{"type":"boolean","const":true}},"required":["object","id","tripId","deleted"],"additionalProperties":false}}}},"default":{"description":"Error (RFC 9457)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/travelers":{"get":{"operationId":"travelers.list","summary":"List travelers","description":"The agency's passengers across live trips, for polling (n8n, Zapier): pass the last `updatedAt` you saw as `updatedSince` with `sort=updatedAt`, and follow `nextCursor` until it is null. Filter by `tripId`. `access` is null here — read a trip's roster for it. Reordering passengers does not move `updatedAt`. Personal data: audited.\n\n**Permissions:** `travelers:read`.","tags":["Travelers"],"x-scopes":["travelers:read"],"x-undo":"none","parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":100,"default":25}},{"name":"cursor","in":"query","required":false,"schema":{"type":"string","minLength":1,"maxLength":500}},{"name":"sort","in":"query","required":false,"schema":{"type":"string","enum":["updatedAt","-updatedAt","createdAt","-createdAt"],"default":"-updatedAt"}},{"name":"updatedSince","in":"query","required":false,"schema":{"type":"string","format":"date-time"}},{"name":"tripId","in":"query","required":false,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"object":{"type":"string","const":"list"},"data":{"type":"array","items":{"type":"object","properties":{"object":{"type":"string","const":"traveler"},"id":{"type":"string","format":"uuid"},"tripId":{"type":"string","format":"uuid"},"position":{"type":"integer"},"title":{"anyOf":[{"type":"string","enum":["mr","mrs","ms","mstr","miss"]},{"type":"null"}]},"firstName":{"type":["string","null"]},"lastName1":{"type":["string","null"]},"lastName2":{"type":["string","null"]},"birthDate":{"type":["string","null"]},"sex":{"anyOf":[{"type":"string","enum":["m","f"]},{"type":"null"}]},"nationality":{"type":["string","null"]},"docType":{"anyOf":[{"type":"string","enum":["dni","nie","passport","other"]},{"type":"null"}]},"docNumber":{"type":["string","null"]},"docExpiry":{"type":["string","null"]},"docCountry":{"type":["string","null"]},"email":{"type":["string","null"]},"phone":{"type":["string","null"]},"address":{"anyOf":[{"type":"object","properties":{"line1":{"anyOf":[{"type":"string","maxLength":120},{"type":"null"}]},"line2":{"anyOf":[{"type":"string","maxLength":120},{"type":"null"}]},"postalCode":{"anyOf":[{"type":"string","maxLength":20},{"type":"null"}]},"city":{"anyOf":[{"type":"string","maxLength":80},{"type":"null"}]},"region":{"anyOf":[{"type":"string","maxLength":80},{"type":"null"}]},"country":{"anyOf":[{"type":"string","pattern":"^[A-Z]{2}$"},{"type":"null"}]}},"required":["line1","line2","postalCode","city","region","country"],"additionalProperties":false},{"type":"null"}]},"taxId":{"type":["string","null"]},"paxType":{"type":"string","enum":["adult","child","infant","unknown"]},"missing":{"type":"array","items":{"type":"string"}},"access":{"anyOf":[{"type":"string","enum":["invited","queued","failed","no_email","not_yet"]},{"type":"null"}]},"source":{"type":"string"},"consentAt":{"type":["string","null"]},"docsPurgedAt":{"type":["string","null"]},"createdAt":{"type":"string"},"updatedAt":{"type":"string"}},"required":["object","id","tripId","position","title","firstName","lastName1","lastName2","birthDate","sex","nationality","docType","docNumber","docExpiry","docCountry","email","phone","address","taxId","paxType","missing","access","source","consentAt","docsPurgedAt","createdAt","updatedAt"],"additionalProperties":false}},"nextCursor":{"type":["string","null"]}},"required":["object","data","nextCursor"],"additionalProperties":false}}}},"default":{"description":"Error (RFC 9457)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/trips/{tripId}/contact":{"get":{"operationId":"travelers.contact.get","summary":"Get a trip's booking contact","description":"The trip's booking contact — the person who books and pays, who need not travel — as the contact panel shows it, with the traveler `account` that holds the booking and its app `access`. 404 `not_found` when the trip has no contact yet. Personal data: audited.\n\n**Permissions:** `travelers:read`.","tags":["Travelers"],"x-scopes":["travelers:read"],"x-undo":"none","parameters":[{"name":"tripId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"object":{"type":"string","const":"trip_contact"},"tripId":{"type":"string","format":"uuid"},"name":{"type":["string","null"]},"email":{"type":["string","null"]},"phone":{"type":["string","null"]},"address":{"anyOf":[{"type":"object","properties":{"line1":{"anyOf":[{"type":"string","maxLength":120},{"type":"null"}]},"line2":{"anyOf":[{"type":"string","maxLength":120},{"type":"null"}]},"postalCode":{"anyOf":[{"type":"string","maxLength":20},{"type":"null"}]},"city":{"anyOf":[{"type":"string","maxLength":80},{"type":"null"}]},"region":{"anyOf":[{"type":"string","maxLength":80},{"type":"null"}]},"country":{"anyOf":[{"type":"string","pattern":"^[A-Z]{2}$"},{"type":"null"}]}},"required":["line1","line2","postalCode","city","region","country"],"additionalProperties":false},{"type":"null"}]},"docType":{"anyOf":[{"type":"string","enum":["dni","nie","passport","other"]},{"type":"null"}]},"docNumber":{"type":["string","null"]},"docCountry":{"type":["string","null"]},"taxId":{"type":["string","null"]},"account":{"type":"object","properties":{"userId":{"type":"string","format":"uuid"},"email":{"type":["string","null"]},"name":{"type":["string","null"]}},"required":["userId","email","name"],"additionalProperties":false},"access":{"anyOf":[{"type":"string","enum":["invited","queued","failed","no_email","not_yet"]},{"type":"null"}]},"accessOpenedAt":{"type":["string","null"]}},"required":["object","tripId","name","email","phone","address","docType","docNumber","docCountry","taxId","account","access","accessOpenedAt"],"additionalProperties":false}}}},"default":{"description":"Error (RFC 9457)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"post":{"operationId":"travelers.contact.create","summary":"Add the booking contact","description":"Makes a person the trip's booking contact (the one who books and pays; they need not travel), as the contact panel's Invite does: finds or creates their traveler account, makes them the booking's holder and stores the contact details you send. If the trip is already `reservada` they are emailed their app access; otherwise they are told when it gets there. 409 `contact_exists` if the trip has a contact — change it with PATCH. Undo with DELETE /trips/{tripId}/contact.\n\n**Permissions:** `travelers:write`.\n\n**Undo:** call `travelers.contact.remove`.","tags":["Travelers"],"x-scopes":["travelers:write"],"x-undo":{"restore":"travelers.contact.remove"},"parameters":[{"name":"tripId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"$ref":"#/components/parameters/IdempotencyKey"}],"responses":{"201":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"object":{"type":"string","const":"trip_contact"},"tripId":{"type":"string","format":"uuid"},"name":{"type":["string","null"]},"email":{"type":["string","null"]},"phone":{"type":["string","null"]},"address":{"anyOf":[{"type":"object","properties":{"line1":{"anyOf":[{"type":"string","maxLength":120},{"type":"null"}]},"line2":{"anyOf":[{"type":"string","maxLength":120},{"type":"null"}]},"postalCode":{"anyOf":[{"type":"string","maxLength":20},{"type":"null"}]},"city":{"anyOf":[{"type":"string","maxLength":80},{"type":"null"}]},"region":{"anyOf":[{"type":"string","maxLength":80},{"type":"null"}]},"country":{"anyOf":[{"type":"string","pattern":"^[A-Z]{2}$"},{"type":"null"}]}},"required":["line1","line2","postalCode","city","region","country"],"additionalProperties":false},{"type":"null"}]},"docType":{"anyOf":[{"type":"string","enum":["dni","nie","passport","other"]},{"type":"null"}]},"docNumber":{"type":["string","null"]},"docCountry":{"type":["string","null"]},"taxId":{"type":["string","null"]},"account":{"type":"object","properties":{"userId":{"type":"string","format":"uuid"},"email":{"type":["string","null"]},"name":{"type":["string","null"]}},"required":["userId","email","name"],"additionalProperties":false},"access":{"anyOf":[{"type":"string","enum":["invited","queued","failed","no_email","not_yet"]},{"type":"null"}]},"accessOpenedAt":{"type":["string","null"]}},"required":["object","tripId","name","email","phone","address","docType","docNumber","docCountry","taxId","account","access","accessOpenedAt"],"additionalProperties":false}}}},"default":{"description":"Error (RFC 9457)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"anyOf":[{"type":"string","maxLength":160},{"type":"null"}]},"email":{"type":"string","format":"email","maxLength":200,"description":"The contact's email — their app access goes here."},"phone":{"anyOf":[{"type":"string","maxLength":40},{"type":"null"}]},"address":{"anyOf":[{"type":"object","properties":{"line1":{"anyOf":[{"type":"string","maxLength":120},{"type":"null"}]},"line2":{"anyOf":[{"type":"string","maxLength":120},{"type":"null"}]},"postalCode":{"anyOf":[{"type":"string","maxLength":20},{"type":"null"}]},"city":{"anyOf":[{"type":"string","maxLength":80},{"type":"null"}]},"region":{"anyOf":[{"type":"string","maxLength":80},{"type":"null"}]},"country":{"anyOf":[{"type":"string","pattern":"^[A-Z]{2}$"},{"type":"null"}]}},"required":["line1","line2","postalCode","city","region","country"],"additionalProperties":false},{"type":"null"}]},"docType":{"anyOf":[{"type":"string","enum":["dni","nie","passport","other"]},{"type":"null"}]},"docNumber":{"anyOf":[{"type":"string","maxLength":40},{"type":"null"}]},"docCountry":{"anyOf":[{"type":"string","pattern":"^[A-Z]{2}$"},{"type":"null"}]},"taxId":{"anyOf":[{"type":"string","maxLength":40},{"type":"null"}]}},"required":["email"],"additionalProperties":false}}}}},"patch":{"operationId":"travelers.contact.update","summary":"Update the booking contact","description":"Changes the booking contact's details, field by field (`null` clears one), as the contact panel does. ⚠️ Changing the email on a `reservada` trip MOVES app access to the new address and emails it; the old address loses access once the new one is in. `?dryRun=true` answers `movesAccess` and `emailsTo` without writing. No undo. 409 `no_contact` if the trip has none yet.\n\n**Permissions:** `travelers:write`.","tags":["Travelers"],"x-scopes":["travelers:write"],"x-undo":"none","parameters":[{"name":"tripId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"$ref":"#/components/parameters/DryRun"},{"$ref":"#/components/parameters/IdempotencyKey"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"anyOf":[{"type":"object","properties":{"object":{"type":"string","const":"trip_contact"},"tripId":{"type":"string","format":"uuid"},"name":{"type":["string","null"]},"email":{"type":["string","null"]},"phone":{"type":["string","null"]},"address":{"anyOf":[{"type":"object","properties":{"line1":{"anyOf":[{"type":"string","maxLength":120},{"type":"null"}]},"line2":{"anyOf":[{"type":"string","maxLength":120},{"type":"null"}]},"postalCode":{"anyOf":[{"type":"string","maxLength":20},{"type":"null"}]},"city":{"anyOf":[{"type":"string","maxLength":80},{"type":"null"}]},"region":{"anyOf":[{"type":"string","maxLength":80},{"type":"null"}]},"country":{"anyOf":[{"type":"string","pattern":"^[A-Z]{2}$"},{"type":"null"}]}},"required":["line1","line2","postalCode","city","region","country"],"additionalProperties":false},{"type":"null"}]},"docType":{"anyOf":[{"type":"string","enum":["dni","nie","passport","other"]},{"type":"null"}]},"docNumber":{"type":["string","null"]},"docCountry":{"type":["string","null"]},"taxId":{"type":["string","null"]},"account":{"type":"object","properties":{"userId":{"type":"string","format":"uuid"},"email":{"type":["string","null"]},"name":{"type":["string","null"]}},"required":["userId","email","name"],"additionalProperties":false},"access":{"anyOf":[{"type":"string","enum":["invited","queued","failed","no_email","not_yet"]},{"type":"null"}]},"accessOpenedAt":{"type":["string","null"]},"accessMoved":{"type":"boolean"}},"required":["object","tripId","name","email","phone","address","docType","docNumber","docCountry","taxId","account","access","accessOpenedAt","accessMoved"],"additionalProperties":false},{"type":"object","properties":{"object":{"type":"string","const":"contact_change_preview"},"movesAccess":{"type":"boolean"},"emailsTo":{"type":["string","null"]}},"required":["object","movesAccess","emailsTo"],"additionalProperties":false}]}}}},"default":{"description":"Error (RFC 9457)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"anyOf":[{"type":"string","maxLength":160},{"type":"null"}]},"email":{"anyOf":[{"type":"string","format":"email","maxLength":200},{"type":"null"}]},"phone":{"anyOf":[{"type":"string","maxLength":40},{"type":"null"}]},"address":{"anyOf":[{"type":"object","properties":{"line1":{"anyOf":[{"type":"string","maxLength":120},{"type":"null"}]},"line2":{"anyOf":[{"type":"string","maxLength":120},{"type":"null"}]},"postalCode":{"anyOf":[{"type":"string","maxLength":20},{"type":"null"}]},"city":{"anyOf":[{"type":"string","maxLength":80},{"type":"null"}]},"region":{"anyOf":[{"type":"string","maxLength":80},{"type":"null"}]},"country":{"anyOf":[{"type":"string","pattern":"^[A-Z]{2}$"},{"type":"null"}]}},"required":["line1","line2","postalCode","city","region","country"],"additionalProperties":false},{"type":"null"}]},"docType":{"anyOf":[{"type":"string","enum":["dni","nie","passport","other"]},{"type":"null"}]},"docNumber":{"anyOf":[{"type":"string","maxLength":40},{"type":"null"}]},"docCountry":{"anyOf":[{"type":"string","pattern":"^[A-Z]{2}$"},{"type":"null"}]},"taxId":{"anyOf":[{"type":"string","maxLength":40},{"type":"null"}]}},"required":[],"additionalProperties":false}}}}},"delete":{"operationId":"travelers.contact.remove","summary":"Remove the booking contact","description":"Removes the booking contact from the trip, as the contact panel's Remove does: their access to this trip and the contact details stored with it go; their account and their other trips stay. No undo, so `confirm` (a query parameter) must be the contact's email — the contact block's, or the account's when the block has none. Add a contact again with POST.\n\n**Permissions:** `travelers:write`.","tags":["Travelers"],"x-scopes":["travelers:write"],"x-undo":"none","parameters":[{"name":"tripId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"confirm","in":"query","required":true,"schema":{"type":"string","minLength":1,"maxLength":200,"description":"The contact's email."}},{"$ref":"#/components/parameters/IdempotencyKey"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"object":{"type":"string","const":"trip_contact"},"tripId":{"type":"string","format":"uuid"},"deleted":{"type":"boolean","const":true}},"required":["object","tripId","deleted"],"additionalProperties":false}}}},"default":{"description":"Error (RFC 9457)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/trips/{tripId}/access/resend":{"post":{"operationId":"travelers.access.resend","summary":"Resend an access email","description":"Queues the app-access email again for one address of the trip — a passenger's or the contact's — as the Travelers card's Resend does. Only on a `reservada` trip (409 `access_not_open` before it: nobody is invited yet); 409 `already_queued` while one is waiting. No undo.\n\n**Permissions:** `travelers:write`.","tags":["Travelers"],"x-scopes":["travelers:write"],"x-undo":"none","parameters":[{"name":"tripId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"$ref":"#/components/parameters/IdempotencyKey"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"object":{"type":"string","const":"access_email"},"tripId":{"type":"string","format":"uuid"},"queued":{"type":"boolean","const":true}},"required":["object","tripId","queued"],"additionalProperties":false}}}},"default":{"description":"Error (RFC 9457)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"email":{"type":"string","format":"email","maxLength":200}},"required":["email"],"additionalProperties":false}}}}}},"/webhook-endpoints":{"get":{"operationId":"webhooks.endpoints.list","summary":"List webhook endpoints","description":"Lists the webhook endpoints that belong to this key, newest first.\n\n**Permissions:** any valid key.","tags":["Webhooks"],"x-scopes":[],"x-undo":"none","parameters":[],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"object":{"type":"string","const":"list"},"data":{"type":"array","items":{"type":"object","properties":{"object":{"type":"string","const":"webhook_endpoint"},"id":{"type":"string","format":"uuid"},"url":{"type":"string"},"description":{"type":"string"},"eventTypes":{"type":"array","items":{"type":"string","enum":["trip.created","trip.updated","trip.archived","trip.restored","trip.published","trip.unpublished","trip.deleted","trip.itinerary.updated","quote.created","quote.updated","quote.sent","quote.accepted","quote.rejected","quote.deleted","traveler.added","traveler.updated","traveler.removed","trip.contact.updated","document.created","document.updated","document.deleted"]}},"enabled":{"type":"boolean"},"disabledReason":{"anyOf":[{"type":"string","enum":["manual","failing","key_invalid"]},{"type":"null"}],"description":"Why it is off: switched off by a person, failing for 3 days, or its key is no longer usable."},"keyId":{"type":"string","format":"uuid","description":"The API key it belongs to; its events are read with this key's permissions."},"previousSecretExpiresAt":{"type":["string","null"],"description":"After a rotation, the old secret keeps signing until this moment."},"lastSuccessAt":{"type":["string","null"]},"failingSince":{"type":["string","null"]},"createdAt":{"type":"string"},"updatedAt":{"type":"string"}},"required":["object","id","url","description","eventTypes","enabled","disabledReason","keyId","previousSecretExpiresAt","lastSuccessAt","failingSince","createdAt","updatedAt"],"additionalProperties":false}},"nextCursor":{"type":["string","null"]}},"required":["object","data","nextCursor"],"additionalProperties":false}}}},"default":{"description":"Error (RFC 9457)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"post":{"operationId":"webhooks.endpoints.create","summary":"Create a webhook endpoint","description":"Subscribes an HTTPS url to events. The endpoint belongs to THIS key: its events are read with this key's permissions, and it stops if the key is revoked or expires. The url must resolve to a public address. The response carries the signing secret (`whsec_…`) ONCE — so this request is never replayed for an Idempotency-Key; a retry of a request that did land answers 409 `endpoint_exists`. At most 10 endpoints per key, one per url. Every delivery is an HTTPS POST signed with Standard Webhooks: headers `webhook-id` (the event id — identical on every retry; drop duplicates by it), `webhook-timestamp` and `webhook-signature` (`v1,<base64 HMAC-SHA256 of \"{id}.{timestamp}.{raw body}\">`). See the Webhooks section of these docs.\n\n**Permissions:** any valid key.","tags":["Webhooks"],"x-scopes":[],"x-undo":"none","parameters":[],"responses":{"201":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"object":{"type":"string","const":"webhook_endpoint"},"id":{"type":"string","format":"uuid"},"url":{"type":"string"},"description":{"type":"string"},"eventTypes":{"type":"array","items":{"type":"string","enum":["trip.created","trip.updated","trip.archived","trip.restored","trip.published","trip.unpublished","trip.deleted","trip.itinerary.updated","quote.created","quote.updated","quote.sent","quote.accepted","quote.rejected","quote.deleted","traveler.added","traveler.updated","traveler.removed","trip.contact.updated","document.created","document.updated","document.deleted"]}},"enabled":{"type":"boolean"},"disabledReason":{"anyOf":[{"type":"string","enum":["manual","failing","key_invalid"]},{"type":"null"}],"description":"Why it is off: switched off by a person, failing for 3 days, or its key is no longer usable."},"keyId":{"type":"string","format":"uuid","description":"The API key it belongs to; its events are read with this key's permissions."},"previousSecretExpiresAt":{"type":["string","null"],"description":"After a rotation, the old secret keeps signing until this moment."},"lastSuccessAt":{"type":["string","null"]},"failingSince":{"type":["string","null"]},"createdAt":{"type":"string"},"updatedAt":{"type":"string"},"secret":{"type":"string","description":"The signing secret (`whsec_…`). Shown ONLY in this response — store it now."}},"required":["object","id","url","description","eventTypes","enabled","disabledReason","keyId","previousSecretExpiresAt","lastSuccessAt","failingSince","createdAt","updatedAt","secret"],"additionalProperties":false}}}},"default":{"description":"Error (RFC 9457)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"url":{"type":"string","minLength":1,"maxLength":2048},"description":{"type":"string","maxLength":200},"eventTypes":{"type":"array","items":{"type":"string","enum":["trip.created","trip.updated","trip.archived","trip.restored","trip.published","trip.unpublished","trip.deleted","trip.itinerary.updated","quote.created","quote.updated","quote.sent","quote.accepted","quote.rejected","quote.deleted","traveler.added","traveler.updated","traveler.removed","trip.contact.updated","document.created","document.updated","document.deleted"]},"minItems":1,"maxItems":21,"description":"The event types to receive. Only types this key can READ are accepted (e.g. traveler.* needs travelers:read)."}},"required":["url","eventTypes"],"additionalProperties":false}}}}}},"/webhook-endpoints/{endpointId}":{"get":{"operationId":"webhooks.endpoints.get","summary":"Get a webhook endpoint","description":"Returns one of this key's endpoints: its url, event types, whether it is on, and why it was switched off.\n\n**Permissions:** any valid key.","tags":["Webhooks"],"x-scopes":[],"x-undo":"none","parameters":[{"name":"endpointId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"object":{"type":"string","const":"webhook_endpoint"},"id":{"type":"string","format":"uuid"},"url":{"type":"string"},"description":{"type":"string"},"eventTypes":{"type":"array","items":{"type":"string","enum":["trip.created","trip.updated","trip.archived","trip.restored","trip.published","trip.unpublished","trip.deleted","trip.itinerary.updated","quote.created","quote.updated","quote.sent","quote.accepted","quote.rejected","quote.deleted","traveler.added","traveler.updated","traveler.removed","trip.contact.updated","document.created","document.updated","document.deleted"]}},"enabled":{"type":"boolean"},"disabledReason":{"anyOf":[{"type":"string","enum":["manual","failing","key_invalid"]},{"type":"null"}],"description":"Why it is off: switched off by a person, failing for 3 days, or its key is no longer usable."},"keyId":{"type":"string","format":"uuid","description":"The API key it belongs to; its events are read with this key's permissions."},"previousSecretExpiresAt":{"type":["string","null"],"description":"After a rotation, the old secret keeps signing until this moment."},"lastSuccessAt":{"type":["string","null"]},"failingSince":{"type":["string","null"]},"createdAt":{"type":"string"},"updatedAt":{"type":"string"}},"required":["object","id","url","description","eventTypes","enabled","disabledReason","keyId","previousSecretExpiresAt","lastSuccessAt","failingSince","createdAt","updatedAt"],"additionalProperties":false}}}},"default":{"description":"Error (RFC 9457)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"patch":{"operationId":"webhooks.endpoints.update","summary":"Update a webhook endpoint","description":"Changes the url, description or event types, or turns the endpoint off and on (`enabled`). Turning it on clears a 'failing' switch-off; it is refused (409 `key_invalid`) while the key is revoked or expired.\n\n**Permissions:** any valid key.","tags":["Webhooks"],"x-scopes":[],"x-undo":"none","parameters":[{"name":"endpointId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"$ref":"#/components/parameters/IdempotencyKey"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"object":{"type":"string","const":"webhook_endpoint"},"id":{"type":"string","format":"uuid"},"url":{"type":"string"},"description":{"type":"string"},"eventTypes":{"type":"array","items":{"type":"string","enum":["trip.created","trip.updated","trip.archived","trip.restored","trip.published","trip.unpublished","trip.deleted","trip.itinerary.updated","quote.created","quote.updated","quote.sent","quote.accepted","quote.rejected","quote.deleted","traveler.added","traveler.updated","traveler.removed","trip.contact.updated","document.created","document.updated","document.deleted"]}},"enabled":{"type":"boolean"},"disabledReason":{"anyOf":[{"type":"string","enum":["manual","failing","key_invalid"]},{"type":"null"}],"description":"Why it is off: switched off by a person, failing for 3 days, or its key is no longer usable."},"keyId":{"type":"string","format":"uuid","description":"The API key it belongs to; its events are read with this key's permissions."},"previousSecretExpiresAt":{"type":["string","null"],"description":"After a rotation, the old secret keeps signing until this moment."},"lastSuccessAt":{"type":["string","null"]},"failingSince":{"type":["string","null"]},"createdAt":{"type":"string"},"updatedAt":{"type":"string"}},"required":["object","id","url","description","eventTypes","enabled","disabledReason","keyId","previousSecretExpiresAt","lastSuccessAt","failingSince","createdAt","updatedAt"],"additionalProperties":false}}}},"default":{"description":"Error (RFC 9457)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"url":{"type":"string","minLength":1,"maxLength":2048},"description":{"type":"string","maxLength":200},"eventTypes":{"type":"array","items":{"type":"string","enum":["trip.created","trip.updated","trip.archived","trip.restored","trip.published","trip.unpublished","trip.deleted","trip.itinerary.updated","quote.created","quote.updated","quote.sent","quote.accepted","quote.rejected","quote.deleted","traveler.added","traveler.updated","traveler.removed","trip.contact.updated","document.created","document.updated","document.deleted"]},"minItems":1,"maxItems":21,"description":"The event types to receive. Only types this key can READ are accepted (e.g. traveler.* needs travelers:read)."},"enabled":{"type":"boolean"}},"required":[],"additionalProperties":false}}}}},"delete":{"operationId":"webhooks.endpoints.delete","summary":"Delete a webhook endpoint","description":"Stops and removes the endpoint and its delivery history. The events themselves stay in GET /events for 30 days.\n\n**Permissions:** any valid key.","tags":["Webhooks"],"x-scopes":[],"x-undo":"none","parameters":[{"name":"endpointId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"$ref":"#/components/parameters/IdempotencyKey"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"object":{"type":"string","const":"webhook_endpoint"},"id":{"type":"string","format":"uuid"},"deleted":{"type":"boolean","const":true}},"required":["object","id","deleted"],"additionalProperties":false}}}},"default":{"description":"Error (RFC 9457)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/webhook-endpoints/{endpointId}/rotate-secret":{"post":{"operationId":"webhooks.endpoints.rotateSecret","summary":"Rotate a webhook endpoint's secret","description":"Issues a new signing secret, returned ONCE. For the next 24 hours deliveries carry two signatures — the new secret's and the old one's — so the receiver can switch without dropping an event.\n\n**Permissions:** any valid key.","tags":["Webhooks"],"x-scopes":[],"x-undo":"none","parameters":[{"name":"endpointId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"object":{"type":"string","const":"webhook_endpoint_secret"},"endpointId":{"type":"string","format":"uuid"},"secret":{"type":"string","description":"The new signing secret. Shown ONLY in this response."},"previousSecretExpiresAt":{"type":["string","null"],"description":"Until then deliveries carry two signatures, one per secret."}},"required":["object","endpointId","secret","previousSecretExpiresAt"],"additionalProperties":false}}}},"default":{"description":"Error (RFC 9457)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{},"required":[],"additionalProperties":false}}}}}},"/webhook-endpoints/{endpointId}/test":{"post":{"operationId":"webhooks.endpoints.test","summary":"Send a test event","description":"Queues a `ping` event to this endpoint alone; it is sent within about 30 seconds. The response is the queued delivery — read its outcome with GET …/deliveries.\n\n**Permissions:** any valid key.","tags":["Webhooks"],"x-scopes":[],"x-undo":"none","parameters":[{"name":"endpointId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"$ref":"#/components/parameters/IdempotencyKey"}],"responses":{"201":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"object":{"type":"string","const":"webhook_delivery"},"id":{"type":"string","format":"uuid"},"endpointId":{"type":"string","format":"uuid"},"eventId":{"type":"string","format":"uuid","description":"Also the `webhook-id` header the receiver got."},"eventType":{"type":"string"},"status":{"type":"string","enum":["pending","sending","succeeded","failed","skipped"]},"attempts":{"type":"integer"},"nextAttemptAt":{"type":["string","null"],"description":"When it is tried again; null unless pending."},"lastStatusCode":{"anyOf":[{"type":"integer"},{"type":"null"}]},"lastError":{"type":["string","null"]},"lastDurationMs":{"anyOf":[{"type":"integer"},{"type":"null"}]},"createdAt":{"type":"string"},"updatedAt":{"type":"string"}},"required":["object","id","endpointId","eventId","eventType","status","attempts","nextAttemptAt","lastStatusCode","lastError","lastDurationMs","createdAt","updatedAt"],"additionalProperties":false}}}},"default":{"description":"Error (RFC 9457)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{},"required":[],"additionalProperties":false}}}}}},"/webhook-endpoints/{endpointId}/deliveries":{"get":{"operationId":"webhooks.deliveries.list","summary":"List an endpoint's deliveries","description":"The endpoint's deliveries, newest first, for 30 days: status, attempts, the receiver's last status code and error, and when a pending one is tried again. No payload is stored.\n\n**Permissions:** any valid key.","tags":["Webhooks"],"x-scopes":[],"x-undo":"none","parameters":[{"name":"endpointId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"status","in":"query","required":false,"schema":{"type":"string","enum":["pending","sending","succeeded","failed","skipped"]}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":100,"default":25}},{"name":"cursor","in":"query","required":false,"schema":{"type":"string","minLength":1,"maxLength":500}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"object":{"type":"string","const":"list"},"data":{"type":"array","items":{"type":"object","properties":{"object":{"type":"string","const":"webhook_delivery"},"id":{"type":"string","format":"uuid"},"endpointId":{"type":"string","format":"uuid"},"eventId":{"type":"string","format":"uuid","description":"Also the `webhook-id` header the receiver got."},"eventType":{"type":"string"},"status":{"type":"string","enum":["pending","sending","succeeded","failed","skipped"]},"attempts":{"type":"integer"},"nextAttemptAt":{"type":["string","null"],"description":"When it is tried again; null unless pending."},"lastStatusCode":{"anyOf":[{"type":"integer"},{"type":"null"}]},"lastError":{"type":["string","null"]},"lastDurationMs":{"anyOf":[{"type":"integer"},{"type":"null"}]},"createdAt":{"type":"string"},"updatedAt":{"type":"string"}},"required":["object","id","endpointId","eventId","eventType","status","attempts","nextAttemptAt","lastStatusCode","lastError","lastDurationMs","createdAt","updatedAt"],"additionalProperties":false}},"nextCursor":{"type":["string","null"]}},"required":["object","data","nextCursor"],"additionalProperties":false}}}},"default":{"description":"Error (RFC 9457)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/webhook-endpoints/{endpointId}/deliveries/{deliveryId}/resend":{"post":{"operationId":"webhooks.deliveries.resend","summary":"Resend a delivery","description":"Queues the delivery again (same `webhook-id`), with the object's CURRENT state. Refused while it is still queued or being sent (409 `delivery_busy`).\n\n**Permissions:** any valid key.","tags":["Webhooks"],"x-scopes":[],"x-undo":"none","parameters":[{"name":"endpointId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"deliveryId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"$ref":"#/components/parameters/IdempotencyKey"}],"responses":{"201":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"object":{"type":"string","const":"webhook_delivery"},"id":{"type":"string","format":"uuid"},"endpointId":{"type":"string","format":"uuid"},"eventId":{"type":"string","format":"uuid","description":"Also the `webhook-id` header the receiver got."},"eventType":{"type":"string"},"status":{"type":"string","enum":["pending","sending","succeeded","failed","skipped"]},"attempts":{"type":"integer"},"nextAttemptAt":{"type":["string","null"],"description":"When it is tried again; null unless pending."},"lastStatusCode":{"anyOf":[{"type":"integer"},{"type":"null"}]},"lastError":{"type":["string","null"]},"lastDurationMs":{"anyOf":[{"type":"integer"},{"type":"null"}]},"createdAt":{"type":"string"},"updatedAt":{"type":"string"}},"required":["object","id","endpointId","eventId","eventType","status","attempts","nextAttemptAt","lastStatusCode","lastError","lastDurationMs","createdAt","updatedAt"],"additionalProperties":false}}}},"default":{"description":"Error (RFC 9457)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{},"required":[],"additionalProperties":false}}}}}},"/events":{"get":{"operationId":"events.list","summary":"List events","description":"Events of the last 30 days, OLDEST first, limited to the types this key can read — the same events webhooks deliver, without `data`. Catch up after downtime with `createdSince` and `nextCursor`, then GET the objects you need.\n\n**Permissions:** any valid key.","tags":["Webhooks"],"x-scopes":[],"x-undo":"none","parameters":[{"name":"type","in":"query","required":false,"schema":{"type":"string","enum":["trip.created","trip.updated","trip.archived","trip.restored","trip.published","trip.unpublished","trip.deleted","trip.itinerary.updated","quote.created","quote.updated","quote.sent","quote.accepted","quote.rejected","quote.deleted","traveler.added","traveler.updated","traveler.removed","trip.contact.updated","document.created","document.updated","document.deleted"]}},{"name":"createdSince","in":"query","required":false,"schema":{"type":"string","format":"date-time"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":100,"default":25}},{"name":"cursor","in":"query","required":false,"schema":{"type":"string","minLength":1,"maxLength":500}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"object":{"type":"string","const":"list"},"data":{"type":"array","items":{"type":"object","properties":{"object":{"type":"string","const":"event"},"id":{"type":"string","format":"uuid"},"type":{"type":"string","enum":["trip.created","trip.updated","trip.archived","trip.restored","trip.published","trip.unpublished","trip.deleted","trip.itinerary.updated","quote.created","quote.updated","quote.sent","quote.accepted","quote.rejected","quote.deleted","traveler.added","traveler.updated","traveler.removed","trip.contact.updated","document.created","document.updated","document.deleted","ping"]},"createdAt":{"type":"string"},"subject":{"type":"object","properties":{"object":{"type":"string","enum":["trip","quote","traveler","contact","document","endpoint"]},"id":{"type":"string","format":"uuid"},"tripId":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}]}},"required":["object","id","tripId"],"additionalProperties":false},"changed":{"type":"array","items":{"type":"string"},"description":"The API fields that changed (names only)."}},"required":["object","id","type","createdAt","subject","changed"],"additionalProperties":false}},"nextCursor":{"type":["string","null"]}},"required":["object","data","nextCursor"],"additionalProperties":false}}}},"default":{"description":"Error (RFC 9457)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/events/{eventId}":{"get":{"operationId":"events.get","summary":"Get an event","description":"One event, thin. A 404 for a type this key cannot read.\n\n**Permissions:** any valid key.","tags":["Webhooks"],"x-scopes":[],"x-undo":"none","parameters":[{"name":"eventId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"object":{"type":"string","const":"event"},"id":{"type":"string","format":"uuid"},"type":{"type":"string","enum":["trip.created","trip.updated","trip.archived","trip.restored","trip.published","trip.unpublished","trip.deleted","trip.itinerary.updated","quote.created","quote.updated","quote.sent","quote.accepted","quote.rejected","quote.deleted","traveler.added","traveler.updated","traveler.removed","trip.contact.updated","document.created","document.updated","document.deleted","ping"]},"createdAt":{"type":"string"},"subject":{"type":"object","properties":{"object":{"type":"string","enum":["trip","quote","traveler","contact","document","endpoint"]},"id":{"type":"string","format":"uuid"},"tripId":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}]}},"required":["object","id","tripId"],"additionalProperties":false},"changed":{"type":"array","items":{"type":"string"},"description":"The API fields that changed (names only)."}},"required":["object","id","type","createdAt","subject","changed"],"additionalProperties":false}}}},"default":{"description":"Error (RFC 9457)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}}},"tags":[{"name":"Webhooks","description":"bymundi POSTs an event to each subscribed endpoint within about 30 seconds of the change — whoever made it: the app, the assistant or this API.\n\n**Signature (Standard Webhooks).** Headers `webhook-id` (the event id), `webhook-timestamp` (Unix seconds) and `webhook-signature` (`v1,<sig>`, space-separated while a rotated secret is still live). `sig` is the base64 HMAC-SHA256 of `{webhook-id}.{webhook-timestamp}.{raw body}` under the base64-decoded part of your `whsec_` secret. Verify against the RAW body, before parsing; reject timestamps more than 5 minutes off. Any Standard Webhooks library does all of this.\n\n```js\nconst crypto = require('crypto');\nfunction verify(secret, id, timestamp, rawBody, header) {\n  const key = Buffer.from(secret.slice('whsec_'.length), 'base64');\n  const sig = 'v1,' + crypto.createHmac('sha256', key).update(`${id}.${timestamp}.${rawBody}`).digest('base64');\n  return Math.abs(Date.now() / 1000 - Number(timestamp)) <= 300 && header.split(' ').includes(sig);\n}\n```\n\nIn n8n: turn on the Webhook node's **Raw Body** option and verify in a Code node (the instance needs `NODE_FUNCTION_ALLOW_BUILTIN=crypto`).\n\n**Delivery.** Answer 2xx within 10 seconds. Anything else is retried after about 5 s, 5 min, 30 min, 2 h, 5 h, 10 h and 10 h; an endpoint with no success for 3 days is switched off. At-least-once: drop duplicates by `webhook-id`. No ordering is promised — compare `timestamp` or the object's `updatedAt`. Missed something? GET /events lists the last 30 days."}],"webhooks":{"trip.created":{"post":{"summary":"trip.created","description":"A trip was created.\n\n**Needs:** `trips:read` on the endpoint's key.","tags":["Webhooks"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["id","type","timestamp","subject","changed","data"],"additionalProperties":false,"properties":{"id":{"type":"string","format":"uuid","description":"The event id — also the `webhook-id` header, identical on every retry."},"type":{"const":"trip.created"},"timestamp":{"type":"string","format":"date-time","description":"When the change happened."},"subject":{"type":"object","required":["object","id","tripId"],"properties":{"object":{"type":"string"},"id":{"type":"string","format":"uuid"},"tripId":{"type":["string","null"]}}},"changed":{"type":"array","items":{"type":"string"},"description":"The API fields that changed (…updated events); empty otherwise."},"data":{"type":"object","properties":{"object":{"type":"string","const":"trip"},"id":{"type":"string","format":"uuid"},"code":{"type":"string"},"title":{"type":"string"},"startDate":{"type":["string","null"]},"endDate":{"type":["string","null"]},"publication":{"type":"string","enum":["draft","published"]},"commercialState":{"type":"string","enum":["nueva","propuesta_enviada","aceptada","reserva_provisional","reservada","rechazada","cancelada"]},"travelers":{"type":"integer"},"ownerId":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}]},"design":{"anyOf":[{"type":"object","properties":{"version":{"type":"number","const":1},"originCity":{"type":"string"},"stops":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"city":{"type":"string"},"nights":{"type":"integer","minimum":0,"maximum":365},"transferBefore":{"anyOf":[{"type":"object","properties":{"id":{"type":"string"},"departDate":{"type":["string","null"]},"arriveDate":{"type":["string","null"]},"days":{"type":"integer","minimum":0,"maximum":30,"default":0},"departTime":{"type":"string","default":""},"arriveTime":{"type":"string","default":""},"flight":{"type":"object","properties":{"flightNo":{"type":"string","default":""},"airline":{"type":"string","default":""},"fromAirport":{"type":"string","default":""},"toAirport":{"type":"string","default":""},"source":{"type":"string","default":""},"fetchedAt":{"type":"string","default":""},"scheduleValidFor":{"type":"string","default":""}},"additionalProperties":false,"default":{"flightNo":"","airline":"","fromAirport":"","toAirport":"","source":"","fetchedAt":"","scheduleValidFor":""}}},"required":["id","departDate","arriveDate"],"additionalProperties":false},{"type":"null"}]},"escala":{"type":"boolean","default":false},"place":{"type":"object","properties":{"placeId":{"type":"string","default":""},"lat":{"type":["number","null"],"default":null},"lng":{"type":["number","null"],"default":null},"formattedAddress":{"type":"string","default":""}},"additionalProperties":false,"default":{"placeId":"","lat":null,"lng":null,"formattedAddress":""}}},"required":["id","city","nights","transferBefore"],"additionalProperties":false},"maxItems":60},"returnCity":{"type":["string","null"]},"returnTransfer":{"anyOf":[{"type":"object","properties":{"id":{"type":"string"},"departDate":{"type":["string","null"]},"arriveDate":{"type":["string","null"]},"days":{"type":"integer","minimum":0,"maximum":30,"default":0},"departTime":{"type":"string","default":""},"arriveTime":{"type":"string","default":""},"flight":{"type":"object","properties":{"flightNo":{"type":"string","default":""},"airline":{"type":"string","default":""},"fromAirport":{"type":"string","default":""},"toAirport":{"type":"string","default":""},"source":{"type":"string","default":""},"fetchedAt":{"type":"string","default":""},"scheduleValidFor":{"type":"string","default":""}},"additionalProperties":false,"default":{"flightNo":"","airline":"","fromAirport":"","toAirport":"","source":"","fetchedAt":"","scheduleValidFor":""}}},"required":["id","departDate","arriveDate"],"additionalProperties":false},{"type":"null"}]},"originPlace":{"type":"object","properties":{"placeId":{"type":"string","default":""},"lat":{"type":["number","null"],"default":null},"lng":{"type":["number","null"],"default":null},"formattedAddress":{"type":"string","default":""}},"additionalProperties":false,"default":{"placeId":"","lat":null,"lng":null,"formattedAddress":""}},"returnPlace":{"type":"object","properties":{"placeId":{"type":"string","default":""},"lat":{"type":["number","null"],"default":null},"lng":{"type":["number","null"],"default":null},"formattedAddress":{"type":"string","default":""}},"additionalProperties":false,"default":{"placeId":"","lat":null,"lng":null,"formattedAddress":""}}},"required":["version","originCity","stops","returnCity","returnTransfer"],"additionalProperties":false},{"type":"null"}]},"presentation":{"type":"object","properties":{"logoUrl":{"anyOf":[{"type":"string","format":"uri"},{"type":"null"}]},"brandColor":{"anyOf":[{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},{"type":"null"}]},"fontFamily":{"anyOf":[{"type":"string","enum":["inter","montserrat","poppins","lora","playfair","source-sans"]},{"type":"null"}]},"headerMedia":{"anyOf":[{"type":"object","properties":{"type":{"type":"string","enum":["image","video"]},"url":{"type":"string","format":"uri"}},"required":["type","url"],"additionalProperties":false},{"type":"null"}]}},"additionalProperties":false},"profile":{"type":"object","properties":{"pace":{"anyOf":[{"type":"string","enum":["relajado","equilibrado","intenso"]},{"type":"null"}],"default":null},"profiles":{"type":"array","items":{"type":"string","enum":["primera_vez","repetidor","familia_ninos","pareja","grupo","senior","movilidad_reducida","cultural","gastronomico","naturaleza","fotografia","otaku","compras","presupuesto_ajustado","premium"]},"default":[]},"mobility":{"type":"string","enum":["normal","reducida"],"default":"normal"},"avoid":{"type":"array","items":{"type":"string"},"default":[]},"notes":{"type":"string","default":""}},"additionalProperties":false},"coverImageUrl":{"type":["string","null"]},"coverage":{"anyOf":[{"type":"object","properties":{"state":{"type":"string","enum":["sin_cobros","pago_parcial","pagado"]},"percent":{"type":"integer"},"overpaid":{"type":"boolean"}},"required":["state","percent","overpaid"],"additionalProperties":false},{"type":"null"}]},"metadata":{"type":"object","additionalProperties":{"type":"string","maxLength":500},"propertyNames":{"pattern":"^[A-Za-z0-9_.-]{1,40}$"}},"appUrl":{"type":["string","null"]},"publicUrl":{"type":["string","null"]},"createdAt":{"type":"string"},"updatedAt":{"type":"string"}},"required":["object","id","code","title","startDate","endDate","publication","commercialState","travelers","ownerId","design","presentation","profile","coverImageUrl","coverage","metadata","appUrl","publicUrl","createdAt","updatedAt"],"additionalProperties":false}}}}}},"responses":{"2XX":{"description":"Received. Anything else, or no answer within 10 s, is retried."}}}},"trip.updated":{"post":{"summary":"trip.updated","description":"A trip's fields or metadata changed. `changed` names the fields.\n\n**Needs:** `trips:read` on the endpoint's key.","tags":["Webhooks"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["id","type","timestamp","subject","changed","data"],"additionalProperties":false,"properties":{"id":{"type":"string","format":"uuid","description":"The event id — also the `webhook-id` header, identical on every retry."},"type":{"const":"trip.updated"},"timestamp":{"type":"string","format":"date-time","description":"When the change happened."},"subject":{"type":"object","required":["object","id","tripId"],"properties":{"object":{"type":"string"},"id":{"type":"string","format":"uuid"},"tripId":{"type":["string","null"]}}},"changed":{"type":"array","items":{"type":"string"},"description":"The API fields that changed (…updated events); empty otherwise."},"data":{"type":"object","properties":{"object":{"type":"string","const":"trip"},"id":{"type":"string","format":"uuid"},"code":{"type":"string"},"title":{"type":"string"},"startDate":{"type":["string","null"]},"endDate":{"type":["string","null"]},"publication":{"type":"string","enum":["draft","published"]},"commercialState":{"type":"string","enum":["nueva","propuesta_enviada","aceptada","reserva_provisional","reservada","rechazada","cancelada"]},"travelers":{"type":"integer"},"ownerId":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}]},"design":{"anyOf":[{"type":"object","properties":{"version":{"type":"number","const":1},"originCity":{"type":"string"},"stops":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"city":{"type":"string"},"nights":{"type":"integer","minimum":0,"maximum":365},"transferBefore":{"anyOf":[{"type":"object","properties":{"id":{"type":"string"},"departDate":{"type":["string","null"]},"arriveDate":{"type":["string","null"]},"days":{"type":"integer","minimum":0,"maximum":30,"default":0},"departTime":{"type":"string","default":""},"arriveTime":{"type":"string","default":""},"flight":{"type":"object","properties":{"flightNo":{"type":"string","default":""},"airline":{"type":"string","default":""},"fromAirport":{"type":"string","default":""},"toAirport":{"type":"string","default":""},"source":{"type":"string","default":""},"fetchedAt":{"type":"string","default":""},"scheduleValidFor":{"type":"string","default":""}},"additionalProperties":false,"default":{"flightNo":"","airline":"","fromAirport":"","toAirport":"","source":"","fetchedAt":"","scheduleValidFor":""}}},"required":["id","departDate","arriveDate"],"additionalProperties":false},{"type":"null"}]},"escala":{"type":"boolean","default":false},"place":{"type":"object","properties":{"placeId":{"type":"string","default":""},"lat":{"type":["number","null"],"default":null},"lng":{"type":["number","null"],"default":null},"formattedAddress":{"type":"string","default":""}},"additionalProperties":false,"default":{"placeId":"","lat":null,"lng":null,"formattedAddress":""}}},"required":["id","city","nights","transferBefore"],"additionalProperties":false},"maxItems":60},"returnCity":{"type":["string","null"]},"returnTransfer":{"anyOf":[{"type":"object","properties":{"id":{"type":"string"},"departDate":{"type":["string","null"]},"arriveDate":{"type":["string","null"]},"days":{"type":"integer","minimum":0,"maximum":30,"default":0},"departTime":{"type":"string","default":""},"arriveTime":{"type":"string","default":""},"flight":{"type":"object","properties":{"flightNo":{"type":"string","default":""},"airline":{"type":"string","default":""},"fromAirport":{"type":"string","default":""},"toAirport":{"type":"string","default":""},"source":{"type":"string","default":""},"fetchedAt":{"type":"string","default":""},"scheduleValidFor":{"type":"string","default":""}},"additionalProperties":false,"default":{"flightNo":"","airline":"","fromAirport":"","toAirport":"","source":"","fetchedAt":"","scheduleValidFor":""}}},"required":["id","departDate","arriveDate"],"additionalProperties":false},{"type":"null"}]},"originPlace":{"type":"object","properties":{"placeId":{"type":"string","default":""},"lat":{"type":["number","null"],"default":null},"lng":{"type":["number","null"],"default":null},"formattedAddress":{"type":"string","default":""}},"additionalProperties":false,"default":{"placeId":"","lat":null,"lng":null,"formattedAddress":""}},"returnPlace":{"type":"object","properties":{"placeId":{"type":"string","default":""},"lat":{"type":["number","null"],"default":null},"lng":{"type":["number","null"],"default":null},"formattedAddress":{"type":"string","default":""}},"additionalProperties":false,"default":{"placeId":"","lat":null,"lng":null,"formattedAddress":""}}},"required":["version","originCity","stops","returnCity","returnTransfer"],"additionalProperties":false},{"type":"null"}]},"presentation":{"type":"object","properties":{"logoUrl":{"anyOf":[{"type":"string","format":"uri"},{"type":"null"}]},"brandColor":{"anyOf":[{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},{"type":"null"}]},"fontFamily":{"anyOf":[{"type":"string","enum":["inter","montserrat","poppins","lora","playfair","source-sans"]},{"type":"null"}]},"headerMedia":{"anyOf":[{"type":"object","properties":{"type":{"type":"string","enum":["image","video"]},"url":{"type":"string","format":"uri"}},"required":["type","url"],"additionalProperties":false},{"type":"null"}]}},"additionalProperties":false},"profile":{"type":"object","properties":{"pace":{"anyOf":[{"type":"string","enum":["relajado","equilibrado","intenso"]},{"type":"null"}],"default":null},"profiles":{"type":"array","items":{"type":"string","enum":["primera_vez","repetidor","familia_ninos","pareja","grupo","senior","movilidad_reducida","cultural","gastronomico","naturaleza","fotografia","otaku","compras","presupuesto_ajustado","premium"]},"default":[]},"mobility":{"type":"string","enum":["normal","reducida"],"default":"normal"},"avoid":{"type":"array","items":{"type":"string"},"default":[]},"notes":{"type":"string","default":""}},"additionalProperties":false},"coverImageUrl":{"type":["string","null"]},"coverage":{"anyOf":[{"type":"object","properties":{"state":{"type":"string","enum":["sin_cobros","pago_parcial","pagado"]},"percent":{"type":"integer"},"overpaid":{"type":"boolean"}},"required":["state","percent","overpaid"],"additionalProperties":false},{"type":"null"}]},"metadata":{"type":"object","additionalProperties":{"type":"string","maxLength":500},"propertyNames":{"pattern":"^[A-Za-z0-9_.-]{1,40}$"}},"appUrl":{"type":["string","null"]},"publicUrl":{"type":["string","null"]},"createdAt":{"type":"string"},"updatedAt":{"type":"string"}},"required":["object","id","code","title","startDate","endDate","publication","commercialState","travelers","ownerId","design","presentation","profile","coverImageUrl","coverage","metadata","appUrl","publicUrl","createdAt","updatedAt"],"additionalProperties":false}}}}}},"responses":{"2XX":{"description":"Received. Anything else, or no answer within 10 s, is retried."}}}},"trip.archived":{"post":{"summary":"trip.archived","description":"A trip was archived. `data` is null: an archived trip is not readable (see GET /trips/archived).\n\n**Needs:** `trips:read` on the endpoint's key.","tags":["Webhooks"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["id","type","timestamp","subject","changed","data"],"additionalProperties":false,"properties":{"id":{"type":"string","format":"uuid","description":"The event id — also the `webhook-id` header, identical on every retry."},"type":{"const":"trip.archived"},"timestamp":{"type":"string","format":"date-time","description":"When the change happened."},"subject":{"type":"object","required":["object","id","tripId"],"properties":{"object":{"type":"string"},"id":{"type":"string","format":"uuid"},"tripId":{"type":["string","null"]}}},"changed":{"type":"array","items":{"type":"string"},"description":"The API fields that changed (…updated events); empty otherwise."},"data":{"anyOf":[{"type":"object","properties":{"object":{"type":"string","const":"trip"},"id":{"type":"string","format":"uuid"},"code":{"type":"string"},"title":{"type":"string"},"startDate":{"type":["string","null"]},"endDate":{"type":["string","null"]},"publication":{"type":"string","enum":["draft","published"]},"commercialState":{"type":"string","enum":["nueva","propuesta_enviada","aceptada","reserva_provisional","reservada","rechazada","cancelada"]},"travelers":{"type":"integer"},"ownerId":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}]},"design":{"anyOf":[{"type":"object","properties":{"version":{"type":"number","const":1},"originCity":{"type":"string"},"stops":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"city":{"type":"string"},"nights":{"type":"integer","minimum":0,"maximum":365},"transferBefore":{"anyOf":[{"type":"object","properties":{"id":{"type":"string"},"departDate":{"type":["string","null"]},"arriveDate":{"type":["string","null"]},"days":{"type":"integer","minimum":0,"maximum":30,"default":0},"departTime":{"type":"string","default":""},"arriveTime":{"type":"string","default":""},"flight":{"type":"object","properties":{"flightNo":{"type":"string","default":""},"airline":{"type":"string","default":""},"fromAirport":{"type":"string","default":""},"toAirport":{"type":"string","default":""},"source":{"type":"string","default":""},"fetchedAt":{"type":"string","default":""},"scheduleValidFor":{"type":"string","default":""}},"additionalProperties":false,"default":{"flightNo":"","airline":"","fromAirport":"","toAirport":"","source":"","fetchedAt":"","scheduleValidFor":""}}},"required":["id","departDate","arriveDate"],"additionalProperties":false},{"type":"null"}]},"escala":{"type":"boolean","default":false},"place":{"type":"object","properties":{"placeId":{"type":"string","default":""},"lat":{"type":["number","null"],"default":null},"lng":{"type":["number","null"],"default":null},"formattedAddress":{"type":"string","default":""}},"additionalProperties":false,"default":{"placeId":"","lat":null,"lng":null,"formattedAddress":""}}},"required":["id","city","nights","transferBefore"],"additionalProperties":false},"maxItems":60},"returnCity":{"type":["string","null"]},"returnTransfer":{"anyOf":[{"type":"object","properties":{"id":{"type":"string"},"departDate":{"type":["string","null"]},"arriveDate":{"type":["string","null"]},"days":{"type":"integer","minimum":0,"maximum":30,"default":0},"departTime":{"type":"string","default":""},"arriveTime":{"type":"string","default":""},"flight":{"type":"object","properties":{"flightNo":{"type":"string","default":""},"airline":{"type":"string","default":""},"fromAirport":{"type":"string","default":""},"toAirport":{"type":"string","default":""},"source":{"type":"string","default":""},"fetchedAt":{"type":"string","default":""},"scheduleValidFor":{"type":"string","default":""}},"additionalProperties":false,"default":{"flightNo":"","airline":"","fromAirport":"","toAirport":"","source":"","fetchedAt":"","scheduleValidFor":""}}},"required":["id","departDate","arriveDate"],"additionalProperties":false},{"type":"null"}]},"originPlace":{"type":"object","properties":{"placeId":{"type":"string","default":""},"lat":{"type":["number","null"],"default":null},"lng":{"type":["number","null"],"default":null},"formattedAddress":{"type":"string","default":""}},"additionalProperties":false,"default":{"placeId":"","lat":null,"lng":null,"formattedAddress":""}},"returnPlace":{"type":"object","properties":{"placeId":{"type":"string","default":""},"lat":{"type":["number","null"],"default":null},"lng":{"type":["number","null"],"default":null},"formattedAddress":{"type":"string","default":""}},"additionalProperties":false,"default":{"placeId":"","lat":null,"lng":null,"formattedAddress":""}}},"required":["version","originCity","stops","returnCity","returnTransfer"],"additionalProperties":false},{"type":"null"}]},"presentation":{"type":"object","properties":{"logoUrl":{"anyOf":[{"type":"string","format":"uri"},{"type":"null"}]},"brandColor":{"anyOf":[{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},{"type":"null"}]},"fontFamily":{"anyOf":[{"type":"string","enum":["inter","montserrat","poppins","lora","playfair","source-sans"]},{"type":"null"}]},"headerMedia":{"anyOf":[{"type":"object","properties":{"type":{"type":"string","enum":["image","video"]},"url":{"type":"string","format":"uri"}},"required":["type","url"],"additionalProperties":false},{"type":"null"}]}},"additionalProperties":false},"profile":{"type":"object","properties":{"pace":{"anyOf":[{"type":"string","enum":["relajado","equilibrado","intenso"]},{"type":"null"}],"default":null},"profiles":{"type":"array","items":{"type":"string","enum":["primera_vez","repetidor","familia_ninos","pareja","grupo","senior","movilidad_reducida","cultural","gastronomico","naturaleza","fotografia","otaku","compras","presupuesto_ajustado","premium"]},"default":[]},"mobility":{"type":"string","enum":["normal","reducida"],"default":"normal"},"avoid":{"type":"array","items":{"type":"string"},"default":[]},"notes":{"type":"string","default":""}},"additionalProperties":false},"coverImageUrl":{"type":["string","null"]},"coverage":{"anyOf":[{"type":"object","properties":{"state":{"type":"string","enum":["sin_cobros","pago_parcial","pagado"]},"percent":{"type":"integer"},"overpaid":{"type":"boolean"}},"required":["state","percent","overpaid"],"additionalProperties":false},{"type":"null"}]},"metadata":{"type":"object","additionalProperties":{"type":"string","maxLength":500},"propertyNames":{"pattern":"^[A-Za-z0-9_.-]{1,40}$"}},"appUrl":{"type":["string","null"]},"publicUrl":{"type":["string","null"]},"createdAt":{"type":"string"},"updatedAt":{"type":"string"}},"required":["object","id","code","title","startDate","endDate","publication","commercialState","travelers","ownerId","design","presentation","profile","coverImageUrl","coverage","metadata","appUrl","publicUrl","createdAt","updatedAt"],"additionalProperties":false},{"type":"null"}]}}}}}},"responses":{"2XX":{"description":"Received. Anything else, or no answer within 10 s, is retried."}}}},"trip.restored":{"post":{"summary":"trip.restored","description":"An archived trip was restored.\n\n**Needs:** `trips:read` on the endpoint's key.","tags":["Webhooks"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["id","type","timestamp","subject","changed","data"],"additionalProperties":false,"properties":{"id":{"type":"string","format":"uuid","description":"The event id — also the `webhook-id` header, identical on every retry."},"type":{"const":"trip.restored"},"timestamp":{"type":"string","format":"date-time","description":"When the change happened."},"subject":{"type":"object","required":["object","id","tripId"],"properties":{"object":{"type":"string"},"id":{"type":"string","format":"uuid"},"tripId":{"type":["string","null"]}}},"changed":{"type":"array","items":{"type":"string"},"description":"The API fields that changed (…updated events); empty otherwise."},"data":{"type":"object","properties":{"object":{"type":"string","const":"trip"},"id":{"type":"string","format":"uuid"},"code":{"type":"string"},"title":{"type":"string"},"startDate":{"type":["string","null"]},"endDate":{"type":["string","null"]},"publication":{"type":"string","enum":["draft","published"]},"commercialState":{"type":"string","enum":["nueva","propuesta_enviada","aceptada","reserva_provisional","reservada","rechazada","cancelada"]},"travelers":{"type":"integer"},"ownerId":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}]},"design":{"anyOf":[{"type":"object","properties":{"version":{"type":"number","const":1},"originCity":{"type":"string"},"stops":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"city":{"type":"string"},"nights":{"type":"integer","minimum":0,"maximum":365},"transferBefore":{"anyOf":[{"type":"object","properties":{"id":{"type":"string"},"departDate":{"type":["string","null"]},"arriveDate":{"type":["string","null"]},"days":{"type":"integer","minimum":0,"maximum":30,"default":0},"departTime":{"type":"string","default":""},"arriveTime":{"type":"string","default":""},"flight":{"type":"object","properties":{"flightNo":{"type":"string","default":""},"airline":{"type":"string","default":""},"fromAirport":{"type":"string","default":""},"toAirport":{"type":"string","default":""},"source":{"type":"string","default":""},"fetchedAt":{"type":"string","default":""},"scheduleValidFor":{"type":"string","default":""}},"additionalProperties":false,"default":{"flightNo":"","airline":"","fromAirport":"","toAirport":"","source":"","fetchedAt":"","scheduleValidFor":""}}},"required":["id","departDate","arriveDate"],"additionalProperties":false},{"type":"null"}]},"escala":{"type":"boolean","default":false},"place":{"type":"object","properties":{"placeId":{"type":"string","default":""},"lat":{"type":["number","null"],"default":null},"lng":{"type":["number","null"],"default":null},"formattedAddress":{"type":"string","default":""}},"additionalProperties":false,"default":{"placeId":"","lat":null,"lng":null,"formattedAddress":""}}},"required":["id","city","nights","transferBefore"],"additionalProperties":false},"maxItems":60},"returnCity":{"type":["string","null"]},"returnTransfer":{"anyOf":[{"type":"object","properties":{"id":{"type":"string"},"departDate":{"type":["string","null"]},"arriveDate":{"type":["string","null"]},"days":{"type":"integer","minimum":0,"maximum":30,"default":0},"departTime":{"type":"string","default":""},"arriveTime":{"type":"string","default":""},"flight":{"type":"object","properties":{"flightNo":{"type":"string","default":""},"airline":{"type":"string","default":""},"fromAirport":{"type":"string","default":""},"toAirport":{"type":"string","default":""},"source":{"type":"string","default":""},"fetchedAt":{"type":"string","default":""},"scheduleValidFor":{"type":"string","default":""}},"additionalProperties":false,"default":{"flightNo":"","airline":"","fromAirport":"","toAirport":"","source":"","fetchedAt":"","scheduleValidFor":""}}},"required":["id","departDate","arriveDate"],"additionalProperties":false},{"type":"null"}]},"originPlace":{"type":"object","properties":{"placeId":{"type":"string","default":""},"lat":{"type":["number","null"],"default":null},"lng":{"type":["number","null"],"default":null},"formattedAddress":{"type":"string","default":""}},"additionalProperties":false,"default":{"placeId":"","lat":null,"lng":null,"formattedAddress":""}},"returnPlace":{"type":"object","properties":{"placeId":{"type":"string","default":""},"lat":{"type":["number","null"],"default":null},"lng":{"type":["number","null"],"default":null},"formattedAddress":{"type":"string","default":""}},"additionalProperties":false,"default":{"placeId":"","lat":null,"lng":null,"formattedAddress":""}}},"required":["version","originCity","stops","returnCity","returnTransfer"],"additionalProperties":false},{"type":"null"}]},"presentation":{"type":"object","properties":{"logoUrl":{"anyOf":[{"type":"string","format":"uri"},{"type":"null"}]},"brandColor":{"anyOf":[{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},{"type":"null"}]},"fontFamily":{"anyOf":[{"type":"string","enum":["inter","montserrat","poppins","lora","playfair","source-sans"]},{"type":"null"}]},"headerMedia":{"anyOf":[{"type":"object","properties":{"type":{"type":"string","enum":["image","video"]},"url":{"type":"string","format":"uri"}},"required":["type","url"],"additionalProperties":false},{"type":"null"}]}},"additionalProperties":false},"profile":{"type":"object","properties":{"pace":{"anyOf":[{"type":"string","enum":["relajado","equilibrado","intenso"]},{"type":"null"}],"default":null},"profiles":{"type":"array","items":{"type":"string","enum":["primera_vez","repetidor","familia_ninos","pareja","grupo","senior","movilidad_reducida","cultural","gastronomico","naturaleza","fotografia","otaku","compras","presupuesto_ajustado","premium"]},"default":[]},"mobility":{"type":"string","enum":["normal","reducida"],"default":"normal"},"avoid":{"type":"array","items":{"type":"string"},"default":[]},"notes":{"type":"string","default":""}},"additionalProperties":false},"coverImageUrl":{"type":["string","null"]},"coverage":{"anyOf":[{"type":"object","properties":{"state":{"type":"string","enum":["sin_cobros","pago_parcial","pagado"]},"percent":{"type":"integer"},"overpaid":{"type":"boolean"}},"required":["state","percent","overpaid"],"additionalProperties":false},{"type":"null"}]},"metadata":{"type":"object","additionalProperties":{"type":"string","maxLength":500},"propertyNames":{"pattern":"^[A-Za-z0-9_.-]{1,40}$"}},"appUrl":{"type":["string","null"]},"publicUrl":{"type":["string","null"]},"createdAt":{"type":"string"},"updatedAt":{"type":"string"}},"required":["object","id","code","title","startDate","endDate","publication","commercialState","travelers","ownerId","design","presentation","profile","coverImageUrl","coverage","metadata","appUrl","publicUrl","createdAt","updatedAt"],"additionalProperties":false}}}}}},"responses":{"2XX":{"description":"Received. Anything else, or no answer within 10 s, is retried."}}}},"trip.published":{"post":{"summary":"trip.published","description":"A trip was published to its travelers.\n\n**Needs:** `trips:read` on the endpoint's key.","tags":["Webhooks"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["id","type","timestamp","subject","changed","data"],"additionalProperties":false,"properties":{"id":{"type":"string","format":"uuid","description":"The event id — also the `webhook-id` header, identical on every retry."},"type":{"const":"trip.published"},"timestamp":{"type":"string","format":"date-time","description":"When the change happened."},"subject":{"type":"object","required":["object","id","tripId"],"properties":{"object":{"type":"string"},"id":{"type":"string","format":"uuid"},"tripId":{"type":["string","null"]}}},"changed":{"type":"array","items":{"type":"string"},"description":"The API fields that changed (…updated events); empty otherwise."},"data":{"type":"object","properties":{"object":{"type":"string","const":"trip"},"id":{"type":"string","format":"uuid"},"code":{"type":"string"},"title":{"type":"string"},"startDate":{"type":["string","null"]},"endDate":{"type":["string","null"]},"publication":{"type":"string","enum":["draft","published"]},"commercialState":{"type":"string","enum":["nueva","propuesta_enviada","aceptada","reserva_provisional","reservada","rechazada","cancelada"]},"travelers":{"type":"integer"},"ownerId":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}]},"design":{"anyOf":[{"type":"object","properties":{"version":{"type":"number","const":1},"originCity":{"type":"string"},"stops":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"city":{"type":"string"},"nights":{"type":"integer","minimum":0,"maximum":365},"transferBefore":{"anyOf":[{"type":"object","properties":{"id":{"type":"string"},"departDate":{"type":["string","null"]},"arriveDate":{"type":["string","null"]},"days":{"type":"integer","minimum":0,"maximum":30,"default":0},"departTime":{"type":"string","default":""},"arriveTime":{"type":"string","default":""},"flight":{"type":"object","properties":{"flightNo":{"type":"string","default":""},"airline":{"type":"string","default":""},"fromAirport":{"type":"string","default":""},"toAirport":{"type":"string","default":""},"source":{"type":"string","default":""},"fetchedAt":{"type":"string","default":""},"scheduleValidFor":{"type":"string","default":""}},"additionalProperties":false,"default":{"flightNo":"","airline":"","fromAirport":"","toAirport":"","source":"","fetchedAt":"","scheduleValidFor":""}}},"required":["id","departDate","arriveDate"],"additionalProperties":false},{"type":"null"}]},"escala":{"type":"boolean","default":false},"place":{"type":"object","properties":{"placeId":{"type":"string","default":""},"lat":{"type":["number","null"],"default":null},"lng":{"type":["number","null"],"default":null},"formattedAddress":{"type":"string","default":""}},"additionalProperties":false,"default":{"placeId":"","lat":null,"lng":null,"formattedAddress":""}}},"required":["id","city","nights","transferBefore"],"additionalProperties":false},"maxItems":60},"returnCity":{"type":["string","null"]},"returnTransfer":{"anyOf":[{"type":"object","properties":{"id":{"type":"string"},"departDate":{"type":["string","null"]},"arriveDate":{"type":["string","null"]},"days":{"type":"integer","minimum":0,"maximum":30,"default":0},"departTime":{"type":"string","default":""},"arriveTime":{"type":"string","default":""},"flight":{"type":"object","properties":{"flightNo":{"type":"string","default":""},"airline":{"type":"string","default":""},"fromAirport":{"type":"string","default":""},"toAirport":{"type":"string","default":""},"source":{"type":"string","default":""},"fetchedAt":{"type":"string","default":""},"scheduleValidFor":{"type":"string","default":""}},"additionalProperties":false,"default":{"flightNo":"","airline":"","fromAirport":"","toAirport":"","source":"","fetchedAt":"","scheduleValidFor":""}}},"required":["id","departDate","arriveDate"],"additionalProperties":false},{"type":"null"}]},"originPlace":{"type":"object","properties":{"placeId":{"type":"string","default":""},"lat":{"type":["number","null"],"default":null},"lng":{"type":["number","null"],"default":null},"formattedAddress":{"type":"string","default":""}},"additionalProperties":false,"default":{"placeId":"","lat":null,"lng":null,"formattedAddress":""}},"returnPlace":{"type":"object","properties":{"placeId":{"type":"string","default":""},"lat":{"type":["number","null"],"default":null},"lng":{"type":["number","null"],"default":null},"formattedAddress":{"type":"string","default":""}},"additionalProperties":false,"default":{"placeId":"","lat":null,"lng":null,"formattedAddress":""}}},"required":["version","originCity","stops","returnCity","returnTransfer"],"additionalProperties":false},{"type":"null"}]},"presentation":{"type":"object","properties":{"logoUrl":{"anyOf":[{"type":"string","format":"uri"},{"type":"null"}]},"brandColor":{"anyOf":[{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},{"type":"null"}]},"fontFamily":{"anyOf":[{"type":"string","enum":["inter","montserrat","poppins","lora","playfair","source-sans"]},{"type":"null"}]},"headerMedia":{"anyOf":[{"type":"object","properties":{"type":{"type":"string","enum":["image","video"]},"url":{"type":"string","format":"uri"}},"required":["type","url"],"additionalProperties":false},{"type":"null"}]}},"additionalProperties":false},"profile":{"type":"object","properties":{"pace":{"anyOf":[{"type":"string","enum":["relajado","equilibrado","intenso"]},{"type":"null"}],"default":null},"profiles":{"type":"array","items":{"type":"string","enum":["primera_vez","repetidor","familia_ninos","pareja","grupo","senior","movilidad_reducida","cultural","gastronomico","naturaleza","fotografia","otaku","compras","presupuesto_ajustado","premium"]},"default":[]},"mobility":{"type":"string","enum":["normal","reducida"],"default":"normal"},"avoid":{"type":"array","items":{"type":"string"},"default":[]},"notes":{"type":"string","default":""}},"additionalProperties":false},"coverImageUrl":{"type":["string","null"]},"coverage":{"anyOf":[{"type":"object","properties":{"state":{"type":"string","enum":["sin_cobros","pago_parcial","pagado"]},"percent":{"type":"integer"},"overpaid":{"type":"boolean"}},"required":["state","percent","overpaid"],"additionalProperties":false},{"type":"null"}]},"metadata":{"type":"object","additionalProperties":{"type":"string","maxLength":500},"propertyNames":{"pattern":"^[A-Za-z0-9_.-]{1,40}$"}},"appUrl":{"type":["string","null"]},"publicUrl":{"type":["string","null"]},"createdAt":{"type":"string"},"updatedAt":{"type":"string"}},"required":["object","id","code","title","startDate","endDate","publication","commercialState","travelers","ownerId","design","presentation","profile","coverImageUrl","coverage","metadata","appUrl","publicUrl","createdAt","updatedAt"],"additionalProperties":false}}}}}},"responses":{"2XX":{"description":"Received. Anything else, or no answer within 10 s, is retried."}}}},"trip.unpublished":{"post":{"summary":"trip.unpublished","description":"A trip was unpublished.\n\n**Needs:** `trips:read` on the endpoint's key.","tags":["Webhooks"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["id","type","timestamp","subject","changed","data"],"additionalProperties":false,"properties":{"id":{"type":"string","format":"uuid","description":"The event id — also the `webhook-id` header, identical on every retry."},"type":{"const":"trip.unpublished"},"timestamp":{"type":"string","format":"date-time","description":"When the change happened."},"subject":{"type":"object","required":["object","id","tripId"],"properties":{"object":{"type":"string"},"id":{"type":"string","format":"uuid"},"tripId":{"type":["string","null"]}}},"changed":{"type":"array","items":{"type":"string"},"description":"The API fields that changed (…updated events); empty otherwise."},"data":{"type":"object","properties":{"object":{"type":"string","const":"trip"},"id":{"type":"string","format":"uuid"},"code":{"type":"string"},"title":{"type":"string"},"startDate":{"type":["string","null"]},"endDate":{"type":["string","null"]},"publication":{"type":"string","enum":["draft","published"]},"commercialState":{"type":"string","enum":["nueva","propuesta_enviada","aceptada","reserva_provisional","reservada","rechazada","cancelada"]},"travelers":{"type":"integer"},"ownerId":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}]},"design":{"anyOf":[{"type":"object","properties":{"version":{"type":"number","const":1},"originCity":{"type":"string"},"stops":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"city":{"type":"string"},"nights":{"type":"integer","minimum":0,"maximum":365},"transferBefore":{"anyOf":[{"type":"object","properties":{"id":{"type":"string"},"departDate":{"type":["string","null"]},"arriveDate":{"type":["string","null"]},"days":{"type":"integer","minimum":0,"maximum":30,"default":0},"departTime":{"type":"string","default":""},"arriveTime":{"type":"string","default":""},"flight":{"type":"object","properties":{"flightNo":{"type":"string","default":""},"airline":{"type":"string","default":""},"fromAirport":{"type":"string","default":""},"toAirport":{"type":"string","default":""},"source":{"type":"string","default":""},"fetchedAt":{"type":"string","default":""},"scheduleValidFor":{"type":"string","default":""}},"additionalProperties":false,"default":{"flightNo":"","airline":"","fromAirport":"","toAirport":"","source":"","fetchedAt":"","scheduleValidFor":""}}},"required":["id","departDate","arriveDate"],"additionalProperties":false},{"type":"null"}]},"escala":{"type":"boolean","default":false},"place":{"type":"object","properties":{"placeId":{"type":"string","default":""},"lat":{"type":["number","null"],"default":null},"lng":{"type":["number","null"],"default":null},"formattedAddress":{"type":"string","default":""}},"additionalProperties":false,"default":{"placeId":"","lat":null,"lng":null,"formattedAddress":""}}},"required":["id","city","nights","transferBefore"],"additionalProperties":false},"maxItems":60},"returnCity":{"type":["string","null"]},"returnTransfer":{"anyOf":[{"type":"object","properties":{"id":{"type":"string"},"departDate":{"type":["string","null"]},"arriveDate":{"type":["string","null"]},"days":{"type":"integer","minimum":0,"maximum":30,"default":0},"departTime":{"type":"string","default":""},"arriveTime":{"type":"string","default":""},"flight":{"type":"object","properties":{"flightNo":{"type":"string","default":""},"airline":{"type":"string","default":""},"fromAirport":{"type":"string","default":""},"toAirport":{"type":"string","default":""},"source":{"type":"string","default":""},"fetchedAt":{"type":"string","default":""},"scheduleValidFor":{"type":"string","default":""}},"additionalProperties":false,"default":{"flightNo":"","airline":"","fromAirport":"","toAirport":"","source":"","fetchedAt":"","scheduleValidFor":""}}},"required":["id","departDate","arriveDate"],"additionalProperties":false},{"type":"null"}]},"originPlace":{"type":"object","properties":{"placeId":{"type":"string","default":""},"lat":{"type":["number","null"],"default":null},"lng":{"type":["number","null"],"default":null},"formattedAddress":{"type":"string","default":""}},"additionalProperties":false,"default":{"placeId":"","lat":null,"lng":null,"formattedAddress":""}},"returnPlace":{"type":"object","properties":{"placeId":{"type":"string","default":""},"lat":{"type":["number","null"],"default":null},"lng":{"type":["number","null"],"default":null},"formattedAddress":{"type":"string","default":""}},"additionalProperties":false,"default":{"placeId":"","lat":null,"lng":null,"formattedAddress":""}}},"required":["version","originCity","stops","returnCity","returnTransfer"],"additionalProperties":false},{"type":"null"}]},"presentation":{"type":"object","properties":{"logoUrl":{"anyOf":[{"type":"string","format":"uri"},{"type":"null"}]},"brandColor":{"anyOf":[{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},{"type":"null"}]},"fontFamily":{"anyOf":[{"type":"string","enum":["inter","montserrat","poppins","lora","playfair","source-sans"]},{"type":"null"}]},"headerMedia":{"anyOf":[{"type":"object","properties":{"type":{"type":"string","enum":["image","video"]},"url":{"type":"string","format":"uri"}},"required":["type","url"],"additionalProperties":false},{"type":"null"}]}},"additionalProperties":false},"profile":{"type":"object","properties":{"pace":{"anyOf":[{"type":"string","enum":["relajado","equilibrado","intenso"]},{"type":"null"}],"default":null},"profiles":{"type":"array","items":{"type":"string","enum":["primera_vez","repetidor","familia_ninos","pareja","grupo","senior","movilidad_reducida","cultural","gastronomico","naturaleza","fotografia","otaku","compras","presupuesto_ajustado","premium"]},"default":[]},"mobility":{"type":"string","enum":["normal","reducida"],"default":"normal"},"avoid":{"type":"array","items":{"type":"string"},"default":[]},"notes":{"type":"string","default":""}},"additionalProperties":false},"coverImageUrl":{"type":["string","null"]},"coverage":{"anyOf":[{"type":"object","properties":{"state":{"type":"string","enum":["sin_cobros","pago_parcial","pagado"]},"percent":{"type":"integer"},"overpaid":{"type":"boolean"}},"required":["state","percent","overpaid"],"additionalProperties":false},{"type":"null"}]},"metadata":{"type":"object","additionalProperties":{"type":"string","maxLength":500},"propertyNames":{"pattern":"^[A-Za-z0-9_.-]{1,40}$"}},"appUrl":{"type":["string","null"]},"publicUrl":{"type":["string","null"]},"createdAt":{"type":"string"},"updatedAt":{"type":"string"}},"required":["object","id","code","title","startDate","endDate","publication","commercialState","travelers","ownerId","design","presentation","profile","coverImageUrl","coverage","metadata","appUrl","publicUrl","createdAt","updatedAt"],"additionalProperties":false}}}}}},"responses":{"2XX":{"description":"Received. Anything else, or no answer within 10 s, is retried."}}}},"trip.deleted":{"post":{"summary":"trip.deleted","description":"A trip was erased for good. `data` is null.\n\n**Needs:** `trips:read` on the endpoint's key.","tags":["Webhooks"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["id","type","timestamp","subject","changed","data"],"additionalProperties":false,"properties":{"id":{"type":"string","format":"uuid","description":"The event id — also the `webhook-id` header, identical on every retry."},"type":{"const":"trip.deleted"},"timestamp":{"type":"string","format":"date-time","description":"When the change happened."},"subject":{"type":"object","required":["object","id","tripId"],"properties":{"object":{"type":"string"},"id":{"type":"string","format":"uuid"},"tripId":{"type":["string","null"]}}},"changed":{"type":"array","items":{"type":"string"},"description":"The API fields that changed (…updated events); empty otherwise."},"data":{"type":"null"}}}}}},"responses":{"2XX":{"description":"Received. Anything else, or no answer within 10 s, is retried."}}}},"trip.itinerary.updated":{"post":{"summary":"trip.itinerary.updated","description":"A trip's itinerary changed — one event per burst of edits. `data` is the TRIP; read the tree with GET /trips/{tripId}/itinerary.\n\n**Needs:** `trips:read` on the endpoint's key.","tags":["Webhooks"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["id","type","timestamp","subject","changed","data"],"additionalProperties":false,"properties":{"id":{"type":"string","format":"uuid","description":"The event id — also the `webhook-id` header, identical on every retry."},"type":{"const":"trip.itinerary.updated"},"timestamp":{"type":"string","format":"date-time","description":"When the change happened."},"subject":{"type":"object","required":["object","id","tripId"],"properties":{"object":{"type":"string"},"id":{"type":"string","format":"uuid"},"tripId":{"type":["string","null"]}}},"changed":{"type":"array","items":{"type":"string"},"description":"The API fields that changed (…updated events); empty otherwise."},"data":{"type":"object","properties":{"object":{"type":"string","const":"trip"},"id":{"type":"string","format":"uuid"},"code":{"type":"string"},"title":{"type":"string"},"startDate":{"type":["string","null"]},"endDate":{"type":["string","null"]},"publication":{"type":"string","enum":["draft","published"]},"commercialState":{"type":"string","enum":["nueva","propuesta_enviada","aceptada","reserva_provisional","reservada","rechazada","cancelada"]},"travelers":{"type":"integer"},"ownerId":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}]},"design":{"anyOf":[{"type":"object","properties":{"version":{"type":"number","const":1},"originCity":{"type":"string"},"stops":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"city":{"type":"string"},"nights":{"type":"integer","minimum":0,"maximum":365},"transferBefore":{"anyOf":[{"type":"object","properties":{"id":{"type":"string"},"departDate":{"type":["string","null"]},"arriveDate":{"type":["string","null"]},"days":{"type":"integer","minimum":0,"maximum":30,"default":0},"departTime":{"type":"string","default":""},"arriveTime":{"type":"string","default":""},"flight":{"type":"object","properties":{"flightNo":{"type":"string","default":""},"airline":{"type":"string","default":""},"fromAirport":{"type":"string","default":""},"toAirport":{"type":"string","default":""},"source":{"type":"string","default":""},"fetchedAt":{"type":"string","default":""},"scheduleValidFor":{"type":"string","default":""}},"additionalProperties":false,"default":{"flightNo":"","airline":"","fromAirport":"","toAirport":"","source":"","fetchedAt":"","scheduleValidFor":""}}},"required":["id","departDate","arriveDate"],"additionalProperties":false},{"type":"null"}]},"escala":{"type":"boolean","default":false},"place":{"type":"object","properties":{"placeId":{"type":"string","default":""},"lat":{"type":["number","null"],"default":null},"lng":{"type":["number","null"],"default":null},"formattedAddress":{"type":"string","default":""}},"additionalProperties":false,"default":{"placeId":"","lat":null,"lng":null,"formattedAddress":""}}},"required":["id","city","nights","transferBefore"],"additionalProperties":false},"maxItems":60},"returnCity":{"type":["string","null"]},"returnTransfer":{"anyOf":[{"type":"object","properties":{"id":{"type":"string"},"departDate":{"type":["string","null"]},"arriveDate":{"type":["string","null"]},"days":{"type":"integer","minimum":0,"maximum":30,"default":0},"departTime":{"type":"string","default":""},"arriveTime":{"type":"string","default":""},"flight":{"type":"object","properties":{"flightNo":{"type":"string","default":""},"airline":{"type":"string","default":""},"fromAirport":{"type":"string","default":""},"toAirport":{"type":"string","default":""},"source":{"type":"string","default":""},"fetchedAt":{"type":"string","default":""},"scheduleValidFor":{"type":"string","default":""}},"additionalProperties":false,"default":{"flightNo":"","airline":"","fromAirport":"","toAirport":"","source":"","fetchedAt":"","scheduleValidFor":""}}},"required":["id","departDate","arriveDate"],"additionalProperties":false},{"type":"null"}]},"originPlace":{"type":"object","properties":{"placeId":{"type":"string","default":""},"lat":{"type":["number","null"],"default":null},"lng":{"type":["number","null"],"default":null},"formattedAddress":{"type":"string","default":""}},"additionalProperties":false,"default":{"placeId":"","lat":null,"lng":null,"formattedAddress":""}},"returnPlace":{"type":"object","properties":{"placeId":{"type":"string","default":""},"lat":{"type":["number","null"],"default":null},"lng":{"type":["number","null"],"default":null},"formattedAddress":{"type":"string","default":""}},"additionalProperties":false,"default":{"placeId":"","lat":null,"lng":null,"formattedAddress":""}}},"required":["version","originCity","stops","returnCity","returnTransfer"],"additionalProperties":false},{"type":"null"}]},"presentation":{"type":"object","properties":{"logoUrl":{"anyOf":[{"type":"string","format":"uri"},{"type":"null"}]},"brandColor":{"anyOf":[{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},{"type":"null"}]},"fontFamily":{"anyOf":[{"type":"string","enum":["inter","montserrat","poppins","lora","playfair","source-sans"]},{"type":"null"}]},"headerMedia":{"anyOf":[{"type":"object","properties":{"type":{"type":"string","enum":["image","video"]},"url":{"type":"string","format":"uri"}},"required":["type","url"],"additionalProperties":false},{"type":"null"}]}},"additionalProperties":false},"profile":{"type":"object","properties":{"pace":{"anyOf":[{"type":"string","enum":["relajado","equilibrado","intenso"]},{"type":"null"}],"default":null},"profiles":{"type":"array","items":{"type":"string","enum":["primera_vez","repetidor","familia_ninos","pareja","grupo","senior","movilidad_reducida","cultural","gastronomico","naturaleza","fotografia","otaku","compras","presupuesto_ajustado","premium"]},"default":[]},"mobility":{"type":"string","enum":["normal","reducida"],"default":"normal"},"avoid":{"type":"array","items":{"type":"string"},"default":[]},"notes":{"type":"string","default":""}},"additionalProperties":false},"coverImageUrl":{"type":["string","null"]},"coverage":{"anyOf":[{"type":"object","properties":{"state":{"type":"string","enum":["sin_cobros","pago_parcial","pagado"]},"percent":{"type":"integer"},"overpaid":{"type":"boolean"}},"required":["state","percent","overpaid"],"additionalProperties":false},{"type":"null"}]},"metadata":{"type":"object","additionalProperties":{"type":"string","maxLength":500},"propertyNames":{"pattern":"^[A-Za-z0-9_.-]{1,40}$"}},"appUrl":{"type":["string","null"]},"publicUrl":{"type":["string","null"]},"createdAt":{"type":"string"},"updatedAt":{"type":"string"}},"required":["object","id","code","title","startDate","endDate","publication","commercialState","travelers","ownerId","design","presentation","profile","coverImageUrl","coverage","metadata","appUrl","publicUrl","createdAt","updatedAt"],"additionalProperties":false}}}}}},"responses":{"2XX":{"description":"Received. Anything else, or no answer within 10 s, is retried."}}}},"quote.created":{"post":{"summary":"quote.created","description":"A quote was created.\n\n**Needs:** `quotes:read` on the endpoint's key.","tags":["Webhooks"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["id","type","timestamp","subject","changed","data"],"additionalProperties":false,"properties":{"id":{"type":"string","format":"uuid","description":"The event id — also the `webhook-id` header, identical on every retry."},"type":{"const":"quote.created"},"timestamp":{"type":"string","format":"date-time","description":"When the change happened."},"subject":{"type":"object","required":["object","id","tripId"],"properties":{"object":{"type":"string"},"id":{"type":"string","format":"uuid"},"tripId":{"type":["string","null"]}}},"changed":{"type":"array","items":{"type":"string"},"description":"The API fields that changed (…updated events); empty otherwise."},"data":{"type":"object","properties":{"object":{"type":"string","const":"quote"},"id":{"type":"string","format":"uuid"},"tripId":{"type":"string","format":"uuid"},"code":{"type":"string"},"name":{"type":"string"},"mode":{"type":"string","enum":["package","per_item"]},"status":{"type":"string","enum":["draft","sent","accepted","rejected","expired","superseded"]},"travelers":{"type":"integer"},"marginPct":{"type":"number"},"finalPriceOverride":{"anyOf":[{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},{"type":"null"}]},"validUntil":{"type":["string","null"]},"ctaUrl":{"type":["string","null"]},"templateId":{"type":["string","null"]},"packages":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false}},"lines":{"type":"array","items":{"anyOf":[{"type":"object","properties":{"kind":{"type":"string","const":"flight"},"id":{"type":"string"},"name":{"type":"string"},"packageId":{"type":["string","null"]},"replacesItemId":{"type":["string","null"]},"marginable":{"type":"boolean"},"bookingRef":{"type":"string"},"comments":{"type":"string"},"catalogRef":{"anyOf":[{"type":"object","properties":{"kind":{"type":"string"},"id":{"type":"string"}},"required":["kind","id"],"additionalProperties":false},{"type":"null"}]},"amount":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"pvp":{"anyOf":[{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},{"type":"null"}]},"role":{"type":"string","enum":["ida","interno","vuelta"]},"mode":{"type":"string","enum":["avion","tren","ferry","autobus","coche"]},"from":{"type":"string"},"to":{"type":"string"},"date":{"type":["string","null"]},"departTime":{"type":"string"},"arriveTime":{"type":"string"},"arriveDayOffset":{"type":"integer"},"stopovers":{"type":"array","items":{"type":"object","properties":{"place":{"type":"string"},"arriveTime":{"type":"string"},"departTime":{"type":"string"},"arriveDayOffset":{"type":"integer"},"flight":{"type":"object","properties":{"flightNo":{"type":"string"},"airline":{"type":"string"},"fromAirport":{"type":"string"},"toAirport":{"type":"string"}},"required":["flightNo","airline","fromAirport","toAirport"],"additionalProperties":false}},"required":["place","arriveTime","departTime","arriveDayOffset","flight"],"additionalProperties":false}},"flight":{"type":"object","properties":{"flightNo":{"type":"string"},"airline":{"type":"string"},"fromAirport":{"type":"string"},"toAirport":{"type":"string"}},"required":["flightNo","airline","fromAirport","toAirport"],"additionalProperties":false},"transferId":{"type":["string","null"]},"price":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"perPax":{"type":"boolean"},"pairedWithId":{"type":["string","null"]}},"required":["kind","id","name","packageId","replacesItemId","marginable","bookingRef","comments","catalogRef","amount","pvp","role","mode","from","to","date","departTime","arriveTime","arriveDayOffset","stopovers","flight","transferId","price","perPax","pairedWithId"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","const":"hotel"},"id":{"type":"string"},"name":{"type":"string"},"packageId":{"type":["string","null"]},"replacesItemId":{"type":["string","null"]},"marginable":{"type":"boolean"},"bookingRef":{"type":"string"},"comments":{"type":"string"},"catalogRef":{"anyOf":[{"type":"object","properties":{"kind":{"type":"string"},"id":{"type":"string"}},"required":["kind","id"],"additionalProperties":false},{"type":"null"}]},"amount":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"pvp":{"anyOf":[{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},{"type":"null"}]},"stopId":{"type":["string","null"]},"city":{"type":"string"},"nights":{"type":"integer"},"board":{"type":"string"},"rooms":{"type":"array","items":{"type":"object","properties":{"type":{"type":"string"},"qty":{"type":"integer"},"price":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"}},"required":["type","qty","price"],"additionalProperties":false}},"optionKind":{"type":"string","enum":["line","hotel"]},"place":{"type":"object","properties":{"placeId":{"type":"string"},"lat":{"type":["number","null"]},"lng":{"type":["number","null"]},"formattedAddress":{"type":"string"}},"required":["placeId","lat","lng","formattedAddress"],"additionalProperties":false}},"required":["kind","id","name","packageId","replacesItemId","marginable","bookingRef","comments","catalogRef","amount","pvp","stopId","city","nights","board","rooms","optionKind","place"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","const":"other"},"id":{"type":"string"},"name":{"type":"string"},"packageId":{"type":["string","null"]},"replacesItemId":{"type":["string","null"]},"marginable":{"type":"boolean"},"bookingRef":{"type":"string"},"comments":{"type":"string"},"catalogRef":{"anyOf":[{"type":"object","properties":{"kind":{"type":"string"},"id":{"type":"string"}},"required":["kind","id"],"additionalProperties":false},{"type":"null"}]},"amount":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"pvp":{"anyOf":[{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},{"type":"null"}]},"tag":{"anyOf":[{"type":"string","enum":["actividad","traslado","seguro"]},{"type":"null"}]},"qty":{"type":"number"},"price":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"perPax":{"type":"boolean"},"range":{"anyOf":[{"type":"object","properties":{"start":{"type":"object","properties":{"offset":{"type":"integer"},"time":{"type":"string"}},"required":["offset","time"],"additionalProperties":false},"end":{"type":"object","properties":{"offset":{"type":"integer"},"time":{"type":"string"}},"required":["offset","time"],"additionalProperties":false}},"required":["start","end"],"additionalProperties":false},{"type":"null"}]},"place":{"type":"object","properties":{"placeId":{"type":"string"},"lat":{"type":["number","null"]},"lng":{"type":["number","null"]},"formattedAddress":{"type":"string"}},"required":["placeId","lat","lng","formattedAddress"],"additionalProperties":false}},"required":["kind","id","name","packageId","replacesItemId","marginable","bookingRef","comments","catalogRef","amount","pvp","tag","qty","price","perPax","range","place"],"additionalProperties":false}]}},"totals":{"type":"object","properties":{"currency":{"type":"string","const":"EUR"},"net":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"marginAmount":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"total":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"finalPrice":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"perPax":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"finalMargin":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"packages":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"deltaNet":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"deltaPvp":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"lineIds":{"type":"array","items":{"type":"string"}}},"required":["id","name","deltaNet","deltaPvp","lineIds"],"additionalProperties":false}}},"required":["currency","net","marginAmount","total","finalPrice","perPax","finalMargin","packages"],"additionalProperties":false},"textOverrides":{"type":"object","additionalProperties":{"type":"string"}},"imageOverrides":{"type":"object","additionalProperties":{"type":"string"}},"sentAt":{"type":["string","null"]},"modifiedSinceSent":{"type":"boolean"},"acceptedAt":{"type":["string","null"]},"acceptedVia":{"anyOf":[{"type":"string","enum":["prospect_link","agent"]},{"type":"null"}]},"acceptedPackageId":{"type":["string","null"]},"acceptedLineIds":{"type":"array","items":{"type":"string"}},"acceptance":{"anyOf":[{"type":"object","properties":{"name":{"type":["string","null"]},"email":{"type":["string","null"]},"phone":{"type":["string","null"]},"message":{"type":["string","null"]}},"required":["name","email","phone","message"],"additionalProperties":false},{"type":"null"}],"description":"What the customer typed when accepting on the quote page — personal data: present only for a key holding `travelers:read`, only on quote reads (a write's response carries null; read the quote), and every such read is audited."},"engagement":{"type":"object","properties":{"views":{"type":"integer"},"uniqueSessions":{"type":"integer"},"activeSeconds":{"type":"integer"},"ctaClicks":{"type":"integer"},"maxScrollPct":{"type":"number"},"sectionsSeen":{"type":"integer"},"interactions":{"type":"integer"},"lastSeenAt":{"type":["string","null"]},"lastCtaAt":{"type":["string","null"]}},"required":["views","uniqueSessions","activeSeconds","ctaClicks","maxScrollPct","sectionsSeen","interactions","lastSeenAt","lastCtaAt"],"additionalProperties":false},"metadata":{"type":"object","additionalProperties":{"type":"string","maxLength":500},"propertyNames":{"pattern":"^[A-Za-z0-9_.-]{1,40}$"}},"appUrl":{"type":["string","null"]},"publicUrl":{"type":["string","null"]},"createdAt":{"type":"string"},"updatedAt":{"type":"string"}},"required":["object","id","tripId","code","name","mode","status","travelers","marginPct","finalPriceOverride","validUntil","ctaUrl","templateId","packages","lines","totals","textOverrides","imageOverrides","sentAt","modifiedSinceSent","acceptedAt","acceptedVia","acceptedPackageId","acceptedLineIds","acceptance","engagement","metadata","appUrl","publicUrl","createdAt","updatedAt"],"additionalProperties":false}}}}}},"responses":{"2XX":{"description":"Received. Anything else, or no answer within 10 s, is retried."}}}},"quote.updated":{"post":{"summary":"quote.updated","description":"A quote changed. `changed` names the fields.\n\n**Needs:** `quotes:read` on the endpoint's key.","tags":["Webhooks"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["id","type","timestamp","subject","changed","data"],"additionalProperties":false,"properties":{"id":{"type":"string","format":"uuid","description":"The event id — also the `webhook-id` header, identical on every retry."},"type":{"const":"quote.updated"},"timestamp":{"type":"string","format":"date-time","description":"When the change happened."},"subject":{"type":"object","required":["object","id","tripId"],"properties":{"object":{"type":"string"},"id":{"type":"string","format":"uuid"},"tripId":{"type":["string","null"]}}},"changed":{"type":"array","items":{"type":"string"},"description":"The API fields that changed (…updated events); empty otherwise."},"data":{"type":"object","properties":{"object":{"type":"string","const":"quote"},"id":{"type":"string","format":"uuid"},"tripId":{"type":"string","format":"uuid"},"code":{"type":"string"},"name":{"type":"string"},"mode":{"type":"string","enum":["package","per_item"]},"status":{"type":"string","enum":["draft","sent","accepted","rejected","expired","superseded"]},"travelers":{"type":"integer"},"marginPct":{"type":"number"},"finalPriceOverride":{"anyOf":[{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},{"type":"null"}]},"validUntil":{"type":["string","null"]},"ctaUrl":{"type":["string","null"]},"templateId":{"type":["string","null"]},"packages":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false}},"lines":{"type":"array","items":{"anyOf":[{"type":"object","properties":{"kind":{"type":"string","const":"flight"},"id":{"type":"string"},"name":{"type":"string"},"packageId":{"type":["string","null"]},"replacesItemId":{"type":["string","null"]},"marginable":{"type":"boolean"},"bookingRef":{"type":"string"},"comments":{"type":"string"},"catalogRef":{"anyOf":[{"type":"object","properties":{"kind":{"type":"string"},"id":{"type":"string"}},"required":["kind","id"],"additionalProperties":false},{"type":"null"}]},"amount":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"pvp":{"anyOf":[{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},{"type":"null"}]},"role":{"type":"string","enum":["ida","interno","vuelta"]},"mode":{"type":"string","enum":["avion","tren","ferry","autobus","coche"]},"from":{"type":"string"},"to":{"type":"string"},"date":{"type":["string","null"]},"departTime":{"type":"string"},"arriveTime":{"type":"string"},"arriveDayOffset":{"type":"integer"},"stopovers":{"type":"array","items":{"type":"object","properties":{"place":{"type":"string"},"arriveTime":{"type":"string"},"departTime":{"type":"string"},"arriveDayOffset":{"type":"integer"},"flight":{"type":"object","properties":{"flightNo":{"type":"string"},"airline":{"type":"string"},"fromAirport":{"type":"string"},"toAirport":{"type":"string"}},"required":["flightNo","airline","fromAirport","toAirport"],"additionalProperties":false}},"required":["place","arriveTime","departTime","arriveDayOffset","flight"],"additionalProperties":false}},"flight":{"type":"object","properties":{"flightNo":{"type":"string"},"airline":{"type":"string"},"fromAirport":{"type":"string"},"toAirport":{"type":"string"}},"required":["flightNo","airline","fromAirport","toAirport"],"additionalProperties":false},"transferId":{"type":["string","null"]},"price":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"perPax":{"type":"boolean"},"pairedWithId":{"type":["string","null"]}},"required":["kind","id","name","packageId","replacesItemId","marginable","bookingRef","comments","catalogRef","amount","pvp","role","mode","from","to","date","departTime","arriveTime","arriveDayOffset","stopovers","flight","transferId","price","perPax","pairedWithId"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","const":"hotel"},"id":{"type":"string"},"name":{"type":"string"},"packageId":{"type":["string","null"]},"replacesItemId":{"type":["string","null"]},"marginable":{"type":"boolean"},"bookingRef":{"type":"string"},"comments":{"type":"string"},"catalogRef":{"anyOf":[{"type":"object","properties":{"kind":{"type":"string"},"id":{"type":"string"}},"required":["kind","id"],"additionalProperties":false},{"type":"null"}]},"amount":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"pvp":{"anyOf":[{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},{"type":"null"}]},"stopId":{"type":["string","null"]},"city":{"type":"string"},"nights":{"type":"integer"},"board":{"type":"string"},"rooms":{"type":"array","items":{"type":"object","properties":{"type":{"type":"string"},"qty":{"type":"integer"},"price":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"}},"required":["type","qty","price"],"additionalProperties":false}},"optionKind":{"type":"string","enum":["line","hotel"]},"place":{"type":"object","properties":{"placeId":{"type":"string"},"lat":{"type":["number","null"]},"lng":{"type":["number","null"]},"formattedAddress":{"type":"string"}},"required":["placeId","lat","lng","formattedAddress"],"additionalProperties":false}},"required":["kind","id","name","packageId","replacesItemId","marginable","bookingRef","comments","catalogRef","amount","pvp","stopId","city","nights","board","rooms","optionKind","place"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","const":"other"},"id":{"type":"string"},"name":{"type":"string"},"packageId":{"type":["string","null"]},"replacesItemId":{"type":["string","null"]},"marginable":{"type":"boolean"},"bookingRef":{"type":"string"},"comments":{"type":"string"},"catalogRef":{"anyOf":[{"type":"object","properties":{"kind":{"type":"string"},"id":{"type":"string"}},"required":["kind","id"],"additionalProperties":false},{"type":"null"}]},"amount":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"pvp":{"anyOf":[{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},{"type":"null"}]},"tag":{"anyOf":[{"type":"string","enum":["actividad","traslado","seguro"]},{"type":"null"}]},"qty":{"type":"number"},"price":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"perPax":{"type":"boolean"},"range":{"anyOf":[{"type":"object","properties":{"start":{"type":"object","properties":{"offset":{"type":"integer"},"time":{"type":"string"}},"required":["offset","time"],"additionalProperties":false},"end":{"type":"object","properties":{"offset":{"type":"integer"},"time":{"type":"string"}},"required":["offset","time"],"additionalProperties":false}},"required":["start","end"],"additionalProperties":false},{"type":"null"}]},"place":{"type":"object","properties":{"placeId":{"type":"string"},"lat":{"type":["number","null"]},"lng":{"type":["number","null"]},"formattedAddress":{"type":"string"}},"required":["placeId","lat","lng","formattedAddress"],"additionalProperties":false}},"required":["kind","id","name","packageId","replacesItemId","marginable","bookingRef","comments","catalogRef","amount","pvp","tag","qty","price","perPax","range","place"],"additionalProperties":false}]}},"totals":{"type":"object","properties":{"currency":{"type":"string","const":"EUR"},"net":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"marginAmount":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"total":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"finalPrice":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"perPax":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"finalMargin":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"packages":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"deltaNet":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"deltaPvp":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"lineIds":{"type":"array","items":{"type":"string"}}},"required":["id","name","deltaNet","deltaPvp","lineIds"],"additionalProperties":false}}},"required":["currency","net","marginAmount","total","finalPrice","perPax","finalMargin","packages"],"additionalProperties":false},"textOverrides":{"type":"object","additionalProperties":{"type":"string"}},"imageOverrides":{"type":"object","additionalProperties":{"type":"string"}},"sentAt":{"type":["string","null"]},"modifiedSinceSent":{"type":"boolean"},"acceptedAt":{"type":["string","null"]},"acceptedVia":{"anyOf":[{"type":"string","enum":["prospect_link","agent"]},{"type":"null"}]},"acceptedPackageId":{"type":["string","null"]},"acceptedLineIds":{"type":"array","items":{"type":"string"}},"acceptance":{"anyOf":[{"type":"object","properties":{"name":{"type":["string","null"]},"email":{"type":["string","null"]},"phone":{"type":["string","null"]},"message":{"type":["string","null"]}},"required":["name","email","phone","message"],"additionalProperties":false},{"type":"null"}],"description":"What the customer typed when accepting on the quote page — personal data: present only for a key holding `travelers:read`, only on quote reads (a write's response carries null; read the quote), and every such read is audited."},"engagement":{"type":"object","properties":{"views":{"type":"integer"},"uniqueSessions":{"type":"integer"},"activeSeconds":{"type":"integer"},"ctaClicks":{"type":"integer"},"maxScrollPct":{"type":"number"},"sectionsSeen":{"type":"integer"},"interactions":{"type":"integer"},"lastSeenAt":{"type":["string","null"]},"lastCtaAt":{"type":["string","null"]}},"required":["views","uniqueSessions","activeSeconds","ctaClicks","maxScrollPct","sectionsSeen","interactions","lastSeenAt","lastCtaAt"],"additionalProperties":false},"metadata":{"type":"object","additionalProperties":{"type":"string","maxLength":500},"propertyNames":{"pattern":"^[A-Za-z0-9_.-]{1,40}$"}},"appUrl":{"type":["string","null"]},"publicUrl":{"type":["string","null"]},"createdAt":{"type":"string"},"updatedAt":{"type":"string"}},"required":["object","id","tripId","code","name","mode","status","travelers","marginPct","finalPriceOverride","validUntil","ctaUrl","templateId","packages","lines","totals","textOverrides","imageOverrides","sentAt","modifiedSinceSent","acceptedAt","acceptedVia","acceptedPackageId","acceptedLineIds","acceptance","engagement","metadata","appUrl","publicUrl","createdAt","updatedAt"],"additionalProperties":false}}}}}},"responses":{"2XX":{"description":"Received. Anything else, or no answer within 10 s, is retried."}}}},"quote.sent":{"post":{"summary":"quote.sent","description":"A quote was sent (or sent again).\n\n**Needs:** `quotes:read` on the endpoint's key.","tags":["Webhooks"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["id","type","timestamp","subject","changed","data"],"additionalProperties":false,"properties":{"id":{"type":"string","format":"uuid","description":"The event id — also the `webhook-id` header, identical on every retry."},"type":{"const":"quote.sent"},"timestamp":{"type":"string","format":"date-time","description":"When the change happened."},"subject":{"type":"object","required":["object","id","tripId"],"properties":{"object":{"type":"string"},"id":{"type":"string","format":"uuid"},"tripId":{"type":["string","null"]}}},"changed":{"type":"array","items":{"type":"string"},"description":"The API fields that changed (…updated events); empty otherwise."},"data":{"type":"object","properties":{"object":{"type":"string","const":"quote"},"id":{"type":"string","format":"uuid"},"tripId":{"type":"string","format":"uuid"},"code":{"type":"string"},"name":{"type":"string"},"mode":{"type":"string","enum":["package","per_item"]},"status":{"type":"string","enum":["draft","sent","accepted","rejected","expired","superseded"]},"travelers":{"type":"integer"},"marginPct":{"type":"number"},"finalPriceOverride":{"anyOf":[{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},{"type":"null"}]},"validUntil":{"type":["string","null"]},"ctaUrl":{"type":["string","null"]},"templateId":{"type":["string","null"]},"packages":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false}},"lines":{"type":"array","items":{"anyOf":[{"type":"object","properties":{"kind":{"type":"string","const":"flight"},"id":{"type":"string"},"name":{"type":"string"},"packageId":{"type":["string","null"]},"replacesItemId":{"type":["string","null"]},"marginable":{"type":"boolean"},"bookingRef":{"type":"string"},"comments":{"type":"string"},"catalogRef":{"anyOf":[{"type":"object","properties":{"kind":{"type":"string"},"id":{"type":"string"}},"required":["kind","id"],"additionalProperties":false},{"type":"null"}]},"amount":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"pvp":{"anyOf":[{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},{"type":"null"}]},"role":{"type":"string","enum":["ida","interno","vuelta"]},"mode":{"type":"string","enum":["avion","tren","ferry","autobus","coche"]},"from":{"type":"string"},"to":{"type":"string"},"date":{"type":["string","null"]},"departTime":{"type":"string"},"arriveTime":{"type":"string"},"arriveDayOffset":{"type":"integer"},"stopovers":{"type":"array","items":{"type":"object","properties":{"place":{"type":"string"},"arriveTime":{"type":"string"},"departTime":{"type":"string"},"arriveDayOffset":{"type":"integer"},"flight":{"type":"object","properties":{"flightNo":{"type":"string"},"airline":{"type":"string"},"fromAirport":{"type":"string"},"toAirport":{"type":"string"}},"required":["flightNo","airline","fromAirport","toAirport"],"additionalProperties":false}},"required":["place","arriveTime","departTime","arriveDayOffset","flight"],"additionalProperties":false}},"flight":{"type":"object","properties":{"flightNo":{"type":"string"},"airline":{"type":"string"},"fromAirport":{"type":"string"},"toAirport":{"type":"string"}},"required":["flightNo","airline","fromAirport","toAirport"],"additionalProperties":false},"transferId":{"type":["string","null"]},"price":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"perPax":{"type":"boolean"},"pairedWithId":{"type":["string","null"]}},"required":["kind","id","name","packageId","replacesItemId","marginable","bookingRef","comments","catalogRef","amount","pvp","role","mode","from","to","date","departTime","arriveTime","arriveDayOffset","stopovers","flight","transferId","price","perPax","pairedWithId"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","const":"hotel"},"id":{"type":"string"},"name":{"type":"string"},"packageId":{"type":["string","null"]},"replacesItemId":{"type":["string","null"]},"marginable":{"type":"boolean"},"bookingRef":{"type":"string"},"comments":{"type":"string"},"catalogRef":{"anyOf":[{"type":"object","properties":{"kind":{"type":"string"},"id":{"type":"string"}},"required":["kind","id"],"additionalProperties":false},{"type":"null"}]},"amount":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"pvp":{"anyOf":[{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},{"type":"null"}]},"stopId":{"type":["string","null"]},"city":{"type":"string"},"nights":{"type":"integer"},"board":{"type":"string"},"rooms":{"type":"array","items":{"type":"object","properties":{"type":{"type":"string"},"qty":{"type":"integer"},"price":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"}},"required":["type","qty","price"],"additionalProperties":false}},"optionKind":{"type":"string","enum":["line","hotel"]},"place":{"type":"object","properties":{"placeId":{"type":"string"},"lat":{"type":["number","null"]},"lng":{"type":["number","null"]},"formattedAddress":{"type":"string"}},"required":["placeId","lat","lng","formattedAddress"],"additionalProperties":false}},"required":["kind","id","name","packageId","replacesItemId","marginable","bookingRef","comments","catalogRef","amount","pvp","stopId","city","nights","board","rooms","optionKind","place"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","const":"other"},"id":{"type":"string"},"name":{"type":"string"},"packageId":{"type":["string","null"]},"replacesItemId":{"type":["string","null"]},"marginable":{"type":"boolean"},"bookingRef":{"type":"string"},"comments":{"type":"string"},"catalogRef":{"anyOf":[{"type":"object","properties":{"kind":{"type":"string"},"id":{"type":"string"}},"required":["kind","id"],"additionalProperties":false},{"type":"null"}]},"amount":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"pvp":{"anyOf":[{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},{"type":"null"}]},"tag":{"anyOf":[{"type":"string","enum":["actividad","traslado","seguro"]},{"type":"null"}]},"qty":{"type":"number"},"price":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"perPax":{"type":"boolean"},"range":{"anyOf":[{"type":"object","properties":{"start":{"type":"object","properties":{"offset":{"type":"integer"},"time":{"type":"string"}},"required":["offset","time"],"additionalProperties":false},"end":{"type":"object","properties":{"offset":{"type":"integer"},"time":{"type":"string"}},"required":["offset","time"],"additionalProperties":false}},"required":["start","end"],"additionalProperties":false},{"type":"null"}]},"place":{"type":"object","properties":{"placeId":{"type":"string"},"lat":{"type":["number","null"]},"lng":{"type":["number","null"]},"formattedAddress":{"type":"string"}},"required":["placeId","lat","lng","formattedAddress"],"additionalProperties":false}},"required":["kind","id","name","packageId","replacesItemId","marginable","bookingRef","comments","catalogRef","amount","pvp","tag","qty","price","perPax","range","place"],"additionalProperties":false}]}},"totals":{"type":"object","properties":{"currency":{"type":"string","const":"EUR"},"net":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"marginAmount":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"total":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"finalPrice":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"perPax":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"finalMargin":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"packages":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"deltaNet":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"deltaPvp":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"lineIds":{"type":"array","items":{"type":"string"}}},"required":["id","name","deltaNet","deltaPvp","lineIds"],"additionalProperties":false}}},"required":["currency","net","marginAmount","total","finalPrice","perPax","finalMargin","packages"],"additionalProperties":false},"textOverrides":{"type":"object","additionalProperties":{"type":"string"}},"imageOverrides":{"type":"object","additionalProperties":{"type":"string"}},"sentAt":{"type":["string","null"]},"modifiedSinceSent":{"type":"boolean"},"acceptedAt":{"type":["string","null"]},"acceptedVia":{"anyOf":[{"type":"string","enum":["prospect_link","agent"]},{"type":"null"}]},"acceptedPackageId":{"type":["string","null"]},"acceptedLineIds":{"type":"array","items":{"type":"string"}},"acceptance":{"anyOf":[{"type":"object","properties":{"name":{"type":["string","null"]},"email":{"type":["string","null"]},"phone":{"type":["string","null"]},"message":{"type":["string","null"]}},"required":["name","email","phone","message"],"additionalProperties":false},{"type":"null"}],"description":"What the customer typed when accepting on the quote page — personal data: present only for a key holding `travelers:read`, only on quote reads (a write's response carries null; read the quote), and every such read is audited."},"engagement":{"type":"object","properties":{"views":{"type":"integer"},"uniqueSessions":{"type":"integer"},"activeSeconds":{"type":"integer"},"ctaClicks":{"type":"integer"},"maxScrollPct":{"type":"number"},"sectionsSeen":{"type":"integer"},"interactions":{"type":"integer"},"lastSeenAt":{"type":["string","null"]},"lastCtaAt":{"type":["string","null"]}},"required":["views","uniqueSessions","activeSeconds","ctaClicks","maxScrollPct","sectionsSeen","interactions","lastSeenAt","lastCtaAt"],"additionalProperties":false},"metadata":{"type":"object","additionalProperties":{"type":"string","maxLength":500},"propertyNames":{"pattern":"^[A-Za-z0-9_.-]{1,40}$"}},"appUrl":{"type":["string","null"]},"publicUrl":{"type":["string","null"]},"createdAt":{"type":"string"},"updatedAt":{"type":"string"}},"required":["object","id","tripId","code","name","mode","status","travelers","marginPct","finalPriceOverride","validUntil","ctaUrl","templateId","packages","lines","totals","textOverrides","imageOverrides","sentAt","modifiedSinceSent","acceptedAt","acceptedVia","acceptedPackageId","acceptedLineIds","acceptance","engagement","metadata","appUrl","publicUrl","createdAt","updatedAt"],"additionalProperties":false}}}}}},"responses":{"2XX":{"description":"Received. Anything else, or no answer within 10 s, is retried."}}}},"quote.accepted":{"post":{"summary":"quote.accepted","description":"A quote was accepted.\n\n**Needs:** `quotes:read` on the endpoint's key.","tags":["Webhooks"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["id","type","timestamp","subject","changed","data"],"additionalProperties":false,"properties":{"id":{"type":"string","format":"uuid","description":"The event id — also the `webhook-id` header, identical on every retry."},"type":{"const":"quote.accepted"},"timestamp":{"type":"string","format":"date-time","description":"When the change happened."},"subject":{"type":"object","required":["object","id","tripId"],"properties":{"object":{"type":"string"},"id":{"type":"string","format":"uuid"},"tripId":{"type":["string","null"]}}},"changed":{"type":"array","items":{"type":"string"},"description":"The API fields that changed (…updated events); empty otherwise."},"data":{"type":"object","properties":{"object":{"type":"string","const":"quote"},"id":{"type":"string","format":"uuid"},"tripId":{"type":"string","format":"uuid"},"code":{"type":"string"},"name":{"type":"string"},"mode":{"type":"string","enum":["package","per_item"]},"status":{"type":"string","enum":["draft","sent","accepted","rejected","expired","superseded"]},"travelers":{"type":"integer"},"marginPct":{"type":"number"},"finalPriceOverride":{"anyOf":[{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},{"type":"null"}]},"validUntil":{"type":["string","null"]},"ctaUrl":{"type":["string","null"]},"templateId":{"type":["string","null"]},"packages":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false}},"lines":{"type":"array","items":{"anyOf":[{"type":"object","properties":{"kind":{"type":"string","const":"flight"},"id":{"type":"string"},"name":{"type":"string"},"packageId":{"type":["string","null"]},"replacesItemId":{"type":["string","null"]},"marginable":{"type":"boolean"},"bookingRef":{"type":"string"},"comments":{"type":"string"},"catalogRef":{"anyOf":[{"type":"object","properties":{"kind":{"type":"string"},"id":{"type":"string"}},"required":["kind","id"],"additionalProperties":false},{"type":"null"}]},"amount":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"pvp":{"anyOf":[{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},{"type":"null"}]},"role":{"type":"string","enum":["ida","interno","vuelta"]},"mode":{"type":"string","enum":["avion","tren","ferry","autobus","coche"]},"from":{"type":"string"},"to":{"type":"string"},"date":{"type":["string","null"]},"departTime":{"type":"string"},"arriveTime":{"type":"string"},"arriveDayOffset":{"type":"integer"},"stopovers":{"type":"array","items":{"type":"object","properties":{"place":{"type":"string"},"arriveTime":{"type":"string"},"departTime":{"type":"string"},"arriveDayOffset":{"type":"integer"},"flight":{"type":"object","properties":{"flightNo":{"type":"string"},"airline":{"type":"string"},"fromAirport":{"type":"string"},"toAirport":{"type":"string"}},"required":["flightNo","airline","fromAirport","toAirport"],"additionalProperties":false}},"required":["place","arriveTime","departTime","arriveDayOffset","flight"],"additionalProperties":false}},"flight":{"type":"object","properties":{"flightNo":{"type":"string"},"airline":{"type":"string"},"fromAirport":{"type":"string"},"toAirport":{"type":"string"}},"required":["flightNo","airline","fromAirport","toAirport"],"additionalProperties":false},"transferId":{"type":["string","null"]},"price":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"perPax":{"type":"boolean"},"pairedWithId":{"type":["string","null"]}},"required":["kind","id","name","packageId","replacesItemId","marginable","bookingRef","comments","catalogRef","amount","pvp","role","mode","from","to","date","departTime","arriveTime","arriveDayOffset","stopovers","flight","transferId","price","perPax","pairedWithId"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","const":"hotel"},"id":{"type":"string"},"name":{"type":"string"},"packageId":{"type":["string","null"]},"replacesItemId":{"type":["string","null"]},"marginable":{"type":"boolean"},"bookingRef":{"type":"string"},"comments":{"type":"string"},"catalogRef":{"anyOf":[{"type":"object","properties":{"kind":{"type":"string"},"id":{"type":"string"}},"required":["kind","id"],"additionalProperties":false},{"type":"null"}]},"amount":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"pvp":{"anyOf":[{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},{"type":"null"}]},"stopId":{"type":["string","null"]},"city":{"type":"string"},"nights":{"type":"integer"},"board":{"type":"string"},"rooms":{"type":"array","items":{"type":"object","properties":{"type":{"type":"string"},"qty":{"type":"integer"},"price":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"}},"required":["type","qty","price"],"additionalProperties":false}},"optionKind":{"type":"string","enum":["line","hotel"]},"place":{"type":"object","properties":{"placeId":{"type":"string"},"lat":{"type":["number","null"]},"lng":{"type":["number","null"]},"formattedAddress":{"type":"string"}},"required":["placeId","lat","lng","formattedAddress"],"additionalProperties":false}},"required":["kind","id","name","packageId","replacesItemId","marginable","bookingRef","comments","catalogRef","amount","pvp","stopId","city","nights","board","rooms","optionKind","place"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","const":"other"},"id":{"type":"string"},"name":{"type":"string"},"packageId":{"type":["string","null"]},"replacesItemId":{"type":["string","null"]},"marginable":{"type":"boolean"},"bookingRef":{"type":"string"},"comments":{"type":"string"},"catalogRef":{"anyOf":[{"type":"object","properties":{"kind":{"type":"string"},"id":{"type":"string"}},"required":["kind","id"],"additionalProperties":false},{"type":"null"}]},"amount":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"pvp":{"anyOf":[{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},{"type":"null"}]},"tag":{"anyOf":[{"type":"string","enum":["actividad","traslado","seguro"]},{"type":"null"}]},"qty":{"type":"number"},"price":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"perPax":{"type":"boolean"},"range":{"anyOf":[{"type":"object","properties":{"start":{"type":"object","properties":{"offset":{"type":"integer"},"time":{"type":"string"}},"required":["offset","time"],"additionalProperties":false},"end":{"type":"object","properties":{"offset":{"type":"integer"},"time":{"type":"string"}},"required":["offset","time"],"additionalProperties":false}},"required":["start","end"],"additionalProperties":false},{"type":"null"}]},"place":{"type":"object","properties":{"placeId":{"type":"string"},"lat":{"type":["number","null"]},"lng":{"type":["number","null"]},"formattedAddress":{"type":"string"}},"required":["placeId","lat","lng","formattedAddress"],"additionalProperties":false}},"required":["kind","id","name","packageId","replacesItemId","marginable","bookingRef","comments","catalogRef","amount","pvp","tag","qty","price","perPax","range","place"],"additionalProperties":false}]}},"totals":{"type":"object","properties":{"currency":{"type":"string","const":"EUR"},"net":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"marginAmount":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"total":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"finalPrice":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"perPax":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"finalMargin":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"packages":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"deltaNet":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"deltaPvp":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"lineIds":{"type":"array","items":{"type":"string"}}},"required":["id","name","deltaNet","deltaPvp","lineIds"],"additionalProperties":false}}},"required":["currency","net","marginAmount","total","finalPrice","perPax","finalMargin","packages"],"additionalProperties":false},"textOverrides":{"type":"object","additionalProperties":{"type":"string"}},"imageOverrides":{"type":"object","additionalProperties":{"type":"string"}},"sentAt":{"type":["string","null"]},"modifiedSinceSent":{"type":"boolean"},"acceptedAt":{"type":["string","null"]},"acceptedVia":{"anyOf":[{"type":"string","enum":["prospect_link","agent"]},{"type":"null"}]},"acceptedPackageId":{"type":["string","null"]},"acceptedLineIds":{"type":"array","items":{"type":"string"}},"acceptance":{"anyOf":[{"type":"object","properties":{"name":{"type":["string","null"]},"email":{"type":["string","null"]},"phone":{"type":["string","null"]},"message":{"type":["string","null"]}},"required":["name","email","phone","message"],"additionalProperties":false},{"type":"null"}],"description":"What the customer typed when accepting on the quote page — personal data: present only for a key holding `travelers:read`, only on quote reads (a write's response carries null; read the quote), and every such read is audited."},"engagement":{"type":"object","properties":{"views":{"type":"integer"},"uniqueSessions":{"type":"integer"},"activeSeconds":{"type":"integer"},"ctaClicks":{"type":"integer"},"maxScrollPct":{"type":"number"},"sectionsSeen":{"type":"integer"},"interactions":{"type":"integer"},"lastSeenAt":{"type":["string","null"]},"lastCtaAt":{"type":["string","null"]}},"required":["views","uniqueSessions","activeSeconds","ctaClicks","maxScrollPct","sectionsSeen","interactions","lastSeenAt","lastCtaAt"],"additionalProperties":false},"metadata":{"type":"object","additionalProperties":{"type":"string","maxLength":500},"propertyNames":{"pattern":"^[A-Za-z0-9_.-]{1,40}$"}},"appUrl":{"type":["string","null"]},"publicUrl":{"type":["string","null"]},"createdAt":{"type":"string"},"updatedAt":{"type":"string"}},"required":["object","id","tripId","code","name","mode","status","travelers","marginPct","finalPriceOverride","validUntil","ctaUrl","templateId","packages","lines","totals","textOverrides","imageOverrides","sentAt","modifiedSinceSent","acceptedAt","acceptedVia","acceptedPackageId","acceptedLineIds","acceptance","engagement","metadata","appUrl","publicUrl","createdAt","updatedAt"],"additionalProperties":false}}}}}},"responses":{"2XX":{"description":"Received. Anything else, or no answer within 10 s, is retried."}}}},"quote.rejected":{"post":{"summary":"quote.rejected","description":"A quote was rejected.\n\n**Needs:** `quotes:read` on the endpoint's key.","tags":["Webhooks"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["id","type","timestamp","subject","changed","data"],"additionalProperties":false,"properties":{"id":{"type":"string","format":"uuid","description":"The event id — also the `webhook-id` header, identical on every retry."},"type":{"const":"quote.rejected"},"timestamp":{"type":"string","format":"date-time","description":"When the change happened."},"subject":{"type":"object","required":["object","id","tripId"],"properties":{"object":{"type":"string"},"id":{"type":"string","format":"uuid"},"tripId":{"type":["string","null"]}}},"changed":{"type":"array","items":{"type":"string"},"description":"The API fields that changed (…updated events); empty otherwise."},"data":{"type":"object","properties":{"object":{"type":"string","const":"quote"},"id":{"type":"string","format":"uuid"},"tripId":{"type":"string","format":"uuid"},"code":{"type":"string"},"name":{"type":"string"},"mode":{"type":"string","enum":["package","per_item"]},"status":{"type":"string","enum":["draft","sent","accepted","rejected","expired","superseded"]},"travelers":{"type":"integer"},"marginPct":{"type":"number"},"finalPriceOverride":{"anyOf":[{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},{"type":"null"}]},"validUntil":{"type":["string","null"]},"ctaUrl":{"type":["string","null"]},"templateId":{"type":["string","null"]},"packages":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false}},"lines":{"type":"array","items":{"anyOf":[{"type":"object","properties":{"kind":{"type":"string","const":"flight"},"id":{"type":"string"},"name":{"type":"string"},"packageId":{"type":["string","null"]},"replacesItemId":{"type":["string","null"]},"marginable":{"type":"boolean"},"bookingRef":{"type":"string"},"comments":{"type":"string"},"catalogRef":{"anyOf":[{"type":"object","properties":{"kind":{"type":"string"},"id":{"type":"string"}},"required":["kind","id"],"additionalProperties":false},{"type":"null"}]},"amount":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"pvp":{"anyOf":[{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},{"type":"null"}]},"role":{"type":"string","enum":["ida","interno","vuelta"]},"mode":{"type":"string","enum":["avion","tren","ferry","autobus","coche"]},"from":{"type":"string"},"to":{"type":"string"},"date":{"type":["string","null"]},"departTime":{"type":"string"},"arriveTime":{"type":"string"},"arriveDayOffset":{"type":"integer"},"stopovers":{"type":"array","items":{"type":"object","properties":{"place":{"type":"string"},"arriveTime":{"type":"string"},"departTime":{"type":"string"},"arriveDayOffset":{"type":"integer"},"flight":{"type":"object","properties":{"flightNo":{"type":"string"},"airline":{"type":"string"},"fromAirport":{"type":"string"},"toAirport":{"type":"string"}},"required":["flightNo","airline","fromAirport","toAirport"],"additionalProperties":false}},"required":["place","arriveTime","departTime","arriveDayOffset","flight"],"additionalProperties":false}},"flight":{"type":"object","properties":{"flightNo":{"type":"string"},"airline":{"type":"string"},"fromAirport":{"type":"string"},"toAirport":{"type":"string"}},"required":["flightNo","airline","fromAirport","toAirport"],"additionalProperties":false},"transferId":{"type":["string","null"]},"price":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"perPax":{"type":"boolean"},"pairedWithId":{"type":["string","null"]}},"required":["kind","id","name","packageId","replacesItemId","marginable","bookingRef","comments","catalogRef","amount","pvp","role","mode","from","to","date","departTime","arriveTime","arriveDayOffset","stopovers","flight","transferId","price","perPax","pairedWithId"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","const":"hotel"},"id":{"type":"string"},"name":{"type":"string"},"packageId":{"type":["string","null"]},"replacesItemId":{"type":["string","null"]},"marginable":{"type":"boolean"},"bookingRef":{"type":"string"},"comments":{"type":"string"},"catalogRef":{"anyOf":[{"type":"object","properties":{"kind":{"type":"string"},"id":{"type":"string"}},"required":["kind","id"],"additionalProperties":false},{"type":"null"}]},"amount":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"pvp":{"anyOf":[{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},{"type":"null"}]},"stopId":{"type":["string","null"]},"city":{"type":"string"},"nights":{"type":"integer"},"board":{"type":"string"},"rooms":{"type":"array","items":{"type":"object","properties":{"type":{"type":"string"},"qty":{"type":"integer"},"price":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"}},"required":["type","qty","price"],"additionalProperties":false}},"optionKind":{"type":"string","enum":["line","hotel"]},"place":{"type":"object","properties":{"placeId":{"type":"string"},"lat":{"type":["number","null"]},"lng":{"type":["number","null"]},"formattedAddress":{"type":"string"}},"required":["placeId","lat","lng","formattedAddress"],"additionalProperties":false}},"required":["kind","id","name","packageId","replacesItemId","marginable","bookingRef","comments","catalogRef","amount","pvp","stopId","city","nights","board","rooms","optionKind","place"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","const":"other"},"id":{"type":"string"},"name":{"type":"string"},"packageId":{"type":["string","null"]},"replacesItemId":{"type":["string","null"]},"marginable":{"type":"boolean"},"bookingRef":{"type":"string"},"comments":{"type":"string"},"catalogRef":{"anyOf":[{"type":"object","properties":{"kind":{"type":"string"},"id":{"type":"string"}},"required":["kind","id"],"additionalProperties":false},{"type":"null"}]},"amount":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"pvp":{"anyOf":[{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},{"type":"null"}]},"tag":{"anyOf":[{"type":"string","enum":["actividad","traslado","seguro"]},{"type":"null"}]},"qty":{"type":"number"},"price":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"perPax":{"type":"boolean"},"range":{"anyOf":[{"type":"object","properties":{"start":{"type":"object","properties":{"offset":{"type":"integer"},"time":{"type":"string"}},"required":["offset","time"],"additionalProperties":false},"end":{"type":"object","properties":{"offset":{"type":"integer"},"time":{"type":"string"}},"required":["offset","time"],"additionalProperties":false}},"required":["start","end"],"additionalProperties":false},{"type":"null"}]},"place":{"type":"object","properties":{"placeId":{"type":"string"},"lat":{"type":["number","null"]},"lng":{"type":["number","null"]},"formattedAddress":{"type":"string"}},"required":["placeId","lat","lng","formattedAddress"],"additionalProperties":false}},"required":["kind","id","name","packageId","replacesItemId","marginable","bookingRef","comments","catalogRef","amount","pvp","tag","qty","price","perPax","range","place"],"additionalProperties":false}]}},"totals":{"type":"object","properties":{"currency":{"type":"string","const":"EUR"},"net":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"marginAmount":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"total":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"finalPrice":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"perPax":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"finalMargin":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"packages":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"deltaNet":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"deltaPvp":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"lineIds":{"type":"array","items":{"type":"string"}}},"required":["id","name","deltaNet","deltaPvp","lineIds"],"additionalProperties":false}}},"required":["currency","net","marginAmount","total","finalPrice","perPax","finalMargin","packages"],"additionalProperties":false},"textOverrides":{"type":"object","additionalProperties":{"type":"string"}},"imageOverrides":{"type":"object","additionalProperties":{"type":"string"}},"sentAt":{"type":["string","null"]},"modifiedSinceSent":{"type":"boolean"},"acceptedAt":{"type":["string","null"]},"acceptedVia":{"anyOf":[{"type":"string","enum":["prospect_link","agent"]},{"type":"null"}]},"acceptedPackageId":{"type":["string","null"]},"acceptedLineIds":{"type":"array","items":{"type":"string"}},"acceptance":{"anyOf":[{"type":"object","properties":{"name":{"type":["string","null"]},"email":{"type":["string","null"]},"phone":{"type":["string","null"]},"message":{"type":["string","null"]}},"required":["name","email","phone","message"],"additionalProperties":false},{"type":"null"}],"description":"What the customer typed when accepting on the quote page — personal data: present only for a key holding `travelers:read`, only on quote reads (a write's response carries null; read the quote), and every such read is audited."},"engagement":{"type":"object","properties":{"views":{"type":"integer"},"uniqueSessions":{"type":"integer"},"activeSeconds":{"type":"integer"},"ctaClicks":{"type":"integer"},"maxScrollPct":{"type":"number"},"sectionsSeen":{"type":"integer"},"interactions":{"type":"integer"},"lastSeenAt":{"type":["string","null"]},"lastCtaAt":{"type":["string","null"]}},"required":["views","uniqueSessions","activeSeconds","ctaClicks","maxScrollPct","sectionsSeen","interactions","lastSeenAt","lastCtaAt"],"additionalProperties":false},"metadata":{"type":"object","additionalProperties":{"type":"string","maxLength":500},"propertyNames":{"pattern":"^[A-Za-z0-9_.-]{1,40}$"}},"appUrl":{"type":["string","null"]},"publicUrl":{"type":["string","null"]},"createdAt":{"type":"string"},"updatedAt":{"type":"string"}},"required":["object","id","tripId","code","name","mode","status","travelers","marginPct","finalPriceOverride","validUntil","ctaUrl","templateId","packages","lines","totals","textOverrides","imageOverrides","sentAt","modifiedSinceSent","acceptedAt","acceptedVia","acceptedPackageId","acceptedLineIds","acceptance","engagement","metadata","appUrl","publicUrl","createdAt","updatedAt"],"additionalProperties":false}}}}}},"responses":{"2XX":{"description":"Received. Anything else, or no answer within 10 s, is retried."}}}},"quote.deleted":{"post":{"summary":"quote.deleted","description":"A quote was deleted. `data` is null.\n\n**Needs:** `quotes:read` on the endpoint's key.","tags":["Webhooks"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["id","type","timestamp","subject","changed","data"],"additionalProperties":false,"properties":{"id":{"type":"string","format":"uuid","description":"The event id — also the `webhook-id` header, identical on every retry."},"type":{"const":"quote.deleted"},"timestamp":{"type":"string","format":"date-time","description":"When the change happened."},"subject":{"type":"object","required":["object","id","tripId"],"properties":{"object":{"type":"string"},"id":{"type":"string","format":"uuid"},"tripId":{"type":["string","null"]}}},"changed":{"type":"array","items":{"type":"string"},"description":"The API fields that changed (…updated events); empty otherwise."},"data":{"type":"null"}}}}}},"responses":{"2XX":{"description":"Received. Anything else, or no answer within 10 s, is retried."}}}},"traveler.added":{"post":{"summary":"traveler.added","description":"A passenger was added to a trip. Personal data.\n\n**Needs:** `travelers:read` on the endpoint's key.","tags":["Webhooks"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["id","type","timestamp","subject","changed","data"],"additionalProperties":false,"properties":{"id":{"type":"string","format":"uuid","description":"The event id — also the `webhook-id` header, identical on every retry."},"type":{"const":"traveler.added"},"timestamp":{"type":"string","format":"date-time","description":"When the change happened."},"subject":{"type":"object","required":["object","id","tripId"],"properties":{"object":{"type":"string"},"id":{"type":"string","format":"uuid"},"tripId":{"type":["string","null"]}}},"changed":{"type":"array","items":{"type":"string"},"description":"The API fields that changed (…updated events); empty otherwise."},"data":{"type":"object","properties":{"object":{"type":"string","const":"traveler"},"id":{"type":"string","format":"uuid"},"tripId":{"type":"string","format":"uuid"},"position":{"type":"integer"},"title":{"anyOf":[{"type":"string","enum":["mr","mrs","ms","mstr","miss"]},{"type":"null"}]},"firstName":{"type":["string","null"]},"lastName1":{"type":["string","null"]},"lastName2":{"type":["string","null"]},"birthDate":{"type":["string","null"]},"sex":{"anyOf":[{"type":"string","enum":["m","f"]},{"type":"null"}]},"nationality":{"type":["string","null"]},"docType":{"anyOf":[{"type":"string","enum":["dni","nie","passport","other"]},{"type":"null"}]},"docNumber":{"type":["string","null"]},"docExpiry":{"type":["string","null"]},"docCountry":{"type":["string","null"]},"email":{"type":["string","null"]},"phone":{"type":["string","null"]},"address":{"anyOf":[{"type":"object","properties":{"line1":{"anyOf":[{"type":"string","maxLength":120},{"type":"null"}]},"line2":{"anyOf":[{"type":"string","maxLength":120},{"type":"null"}]},"postalCode":{"anyOf":[{"type":"string","maxLength":20},{"type":"null"}]},"city":{"anyOf":[{"type":"string","maxLength":80},{"type":"null"}]},"region":{"anyOf":[{"type":"string","maxLength":80},{"type":"null"}]},"country":{"anyOf":[{"type":"string","pattern":"^[A-Z]{2}$"},{"type":"null"}]}},"required":["line1","line2","postalCode","city","region","country"],"additionalProperties":false},{"type":"null"}]},"taxId":{"type":["string","null"]},"paxType":{"type":"string","enum":["adult","child","infant","unknown"]},"missing":{"type":"array","items":{"type":"string"}},"access":{"anyOf":[{"type":"string","enum":["invited","queued","failed","no_email","not_yet"]},{"type":"null"}]},"source":{"type":"string"},"consentAt":{"type":["string","null"]},"docsPurgedAt":{"type":["string","null"]},"createdAt":{"type":"string"},"updatedAt":{"type":"string"}},"required":["object","id","tripId","position","title","firstName","lastName1","lastName2","birthDate","sex","nationality","docType","docNumber","docExpiry","docCountry","email","phone","address","taxId","paxType","missing","access","source","consentAt","docsPurgedAt","createdAt","updatedAt"],"additionalProperties":false}}}}}},"responses":{"2XX":{"description":"Received. Anything else, or no answer within 10 s, is retried."}}}},"traveler.updated":{"post":{"summary":"traveler.updated","description":"A passenger changed. `changed` names the fields. Personal data.\n\n**Needs:** `travelers:read` on the endpoint's key.","tags":["Webhooks"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["id","type","timestamp","subject","changed","data"],"additionalProperties":false,"properties":{"id":{"type":"string","format":"uuid","description":"The event id — also the `webhook-id` header, identical on every retry."},"type":{"const":"traveler.updated"},"timestamp":{"type":"string","format":"date-time","description":"When the change happened."},"subject":{"type":"object","required":["object","id","tripId"],"properties":{"object":{"type":"string"},"id":{"type":"string","format":"uuid"},"tripId":{"type":["string","null"]}}},"changed":{"type":"array","items":{"type":"string"},"description":"The API fields that changed (…updated events); empty otherwise."},"data":{"type":"object","properties":{"object":{"type":"string","const":"traveler"},"id":{"type":"string","format":"uuid"},"tripId":{"type":"string","format":"uuid"},"position":{"type":"integer"},"title":{"anyOf":[{"type":"string","enum":["mr","mrs","ms","mstr","miss"]},{"type":"null"}]},"firstName":{"type":["string","null"]},"lastName1":{"type":["string","null"]},"lastName2":{"type":["string","null"]},"birthDate":{"type":["string","null"]},"sex":{"anyOf":[{"type":"string","enum":["m","f"]},{"type":"null"}]},"nationality":{"type":["string","null"]},"docType":{"anyOf":[{"type":"string","enum":["dni","nie","passport","other"]},{"type":"null"}]},"docNumber":{"type":["string","null"]},"docExpiry":{"type":["string","null"]},"docCountry":{"type":["string","null"]},"email":{"type":["string","null"]},"phone":{"type":["string","null"]},"address":{"anyOf":[{"type":"object","properties":{"line1":{"anyOf":[{"type":"string","maxLength":120},{"type":"null"}]},"line2":{"anyOf":[{"type":"string","maxLength":120},{"type":"null"}]},"postalCode":{"anyOf":[{"type":"string","maxLength":20},{"type":"null"}]},"city":{"anyOf":[{"type":"string","maxLength":80},{"type":"null"}]},"region":{"anyOf":[{"type":"string","maxLength":80},{"type":"null"}]},"country":{"anyOf":[{"type":"string","pattern":"^[A-Z]{2}$"},{"type":"null"}]}},"required":["line1","line2","postalCode","city","region","country"],"additionalProperties":false},{"type":"null"}]},"taxId":{"type":["string","null"]},"paxType":{"type":"string","enum":["adult","child","infant","unknown"]},"missing":{"type":"array","items":{"type":"string"}},"access":{"anyOf":[{"type":"string","enum":["invited","queued","failed","no_email","not_yet"]},{"type":"null"}]},"source":{"type":"string"},"consentAt":{"type":["string","null"]},"docsPurgedAt":{"type":["string","null"]},"createdAt":{"type":"string"},"updatedAt":{"type":"string"}},"required":["object","id","tripId","position","title","firstName","lastName1","lastName2","birthDate","sex","nationality","docType","docNumber","docExpiry","docCountry","email","phone","address","taxId","paxType","missing","access","source","consentAt","docsPurgedAt","createdAt","updatedAt"],"additionalProperties":false}}}}}},"responses":{"2XX":{"description":"Received. Anything else, or no answer within 10 s, is retried."}}}},"traveler.removed":{"post":{"summary":"traveler.removed","description":"A passenger was removed. `data` is null.\n\n**Needs:** `travelers:read` on the endpoint's key.","tags":["Webhooks"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["id","type","timestamp","subject","changed","data"],"additionalProperties":false,"properties":{"id":{"type":"string","format":"uuid","description":"The event id — also the `webhook-id` header, identical on every retry."},"type":{"const":"traveler.removed"},"timestamp":{"type":"string","format":"date-time","description":"When the change happened."},"subject":{"type":"object","required":["object","id","tripId"],"properties":{"object":{"type":"string"},"id":{"type":"string","format":"uuid"},"tripId":{"type":["string","null"]}}},"changed":{"type":"array","items":{"type":"string"},"description":"The API fields that changed (…updated events); empty otherwise."},"data":{"type":"null"}}}}}},"responses":{"2XX":{"description":"Received. Anything else, or no answer within 10 s, is retried."}}}},"trip.contact.updated":{"post":{"summary":"trip.contact.updated","description":"A trip's booking contact was made, changed or removed (`data` null when there is none). Personal data.\n\n**Needs:** `travelers:read` on the endpoint's key.","tags":["Webhooks"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["id","type","timestamp","subject","changed","data"],"additionalProperties":false,"properties":{"id":{"type":"string","format":"uuid","description":"The event id — also the `webhook-id` header, identical on every retry."},"type":{"const":"trip.contact.updated"},"timestamp":{"type":"string","format":"date-time","description":"When the change happened."},"subject":{"type":"object","required":["object","id","tripId"],"properties":{"object":{"type":"string"},"id":{"type":"string","format":"uuid"},"tripId":{"type":["string","null"]}}},"changed":{"type":"array","items":{"type":"string"},"description":"The API fields that changed (…updated events); empty otherwise."},"data":{"anyOf":[{"type":"object","properties":{"object":{"type":"string","const":"trip_contact"},"tripId":{"type":"string","format":"uuid"},"name":{"type":["string","null"]},"email":{"type":["string","null"]},"phone":{"type":["string","null"]},"address":{"anyOf":[{"type":"object","properties":{"line1":{"anyOf":[{"type":"string","maxLength":120},{"type":"null"}]},"line2":{"anyOf":[{"type":"string","maxLength":120},{"type":"null"}]},"postalCode":{"anyOf":[{"type":"string","maxLength":20},{"type":"null"}]},"city":{"anyOf":[{"type":"string","maxLength":80},{"type":"null"}]},"region":{"anyOf":[{"type":"string","maxLength":80},{"type":"null"}]},"country":{"anyOf":[{"type":"string","pattern":"^[A-Z]{2}$"},{"type":"null"}]}},"required":["line1","line2","postalCode","city","region","country"],"additionalProperties":false},{"type":"null"}]},"docType":{"anyOf":[{"type":"string","enum":["dni","nie","passport","other"]},{"type":"null"}]},"docNumber":{"type":["string","null"]},"docCountry":{"type":["string","null"]},"taxId":{"type":["string","null"]},"account":{"type":"object","properties":{"userId":{"type":"string","format":"uuid"},"email":{"type":["string","null"]},"name":{"type":["string","null"]}},"required":["userId","email","name"],"additionalProperties":false},"access":{"anyOf":[{"type":"string","enum":["invited","queued","failed","no_email","not_yet"]},{"type":"null"}]},"accessOpenedAt":{"type":["string","null"]}},"required":["object","tripId","name","email","phone","address","docType","docNumber","docCountry","taxId","account","access","accessOpenedAt"],"additionalProperties":false},{"type":"null"}]}}}}}},"responses":{"2XX":{"description":"Received. Anything else, or no answer within 10 s, is retried."}}}},"document.created":{"post":{"summary":"document.created","description":"A document finished uploading.\n\n**Needs:** `documents:read` on the endpoint's key.","tags":["Webhooks"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["id","type","timestamp","subject","changed","data"],"additionalProperties":false,"properties":{"id":{"type":"string","format":"uuid","description":"The event id — also the `webhook-id` header, identical on every retry."},"type":{"const":"document.created"},"timestamp":{"type":"string","format":"date-time","description":"When the change happened."},"subject":{"type":"object","required":["object","id","tripId"],"properties":{"object":{"type":"string"},"id":{"type":"string","format":"uuid"},"tripId":{"type":["string","null"]}}},"changed":{"type":"array","items":{"type":"string"},"description":"The API fields that changed (…updated events); empty otherwise."},"data":{"type":"object","properties":{"object":{"type":"string","const":"document"},"id":{"type":"string","format":"uuid"},"tripId":{"type":"string","format":"uuid"},"folderId":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"description":"The folder it is filed in; null = loose (in no folder)."},"name":{"type":"string"},"mimeType":{"type":"string"},"byteSize":{"type":"integer","minimum":0},"status":{"type":"string","enum":["pending","ready"],"description":"`pending`: reserved, the upload is not complete — never listed. `ready`: a document."},"visibility":{"type":"string","enum":["staff","traveler"],"description":"`staff`: internal, only the agency sees it. `traveler`: released to the trip's travelers."},"visibleToTravelersNow":{"type":"boolean","description":"Released AND the trip is published: the traveler's app shows it right now."},"visibleAt":{"type":["string","null"],"description":"When it was last released to travelers; null while internal."},"visibleBy":{"anyOf":[{"type":"object","properties":{"id":{"type":"string"},"name":{"type":["string","null"]}},"required":["id","name"],"additionalProperties":false},{"type":"null"}]},"uploadedBy":{"anyOf":[{"type":"object","properties":{"id":{"type":"string"},"name":{"type":["string","null"]}},"required":["id","name"],"additionalProperties":false},{"type":"null"}]},"createdAt":{"type":"string"},"updatedAt":{"type":"string"},"appUrl":{"type":["string","null"],"description":"The trip's Documents tab in bymundi."}},"required":["object","id","tripId","folderId","name","mimeType","byteSize","status","visibility","visibleToTravelersNow","visibleAt","visibleBy","uploadedBy","createdAt","updatedAt","appUrl"],"additionalProperties":false}}}}}},"responses":{"2XX":{"description":"Received. Anything else, or no answer within 10 s, is retried."}}}},"document.updated":{"post":{"summary":"document.updated","description":"A document was renamed, moved or released. `changed` names the fields.\n\n**Needs:** `documents:read` on the endpoint's key.","tags":["Webhooks"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["id","type","timestamp","subject","changed","data"],"additionalProperties":false,"properties":{"id":{"type":"string","format":"uuid","description":"The event id — also the `webhook-id` header, identical on every retry."},"type":{"const":"document.updated"},"timestamp":{"type":"string","format":"date-time","description":"When the change happened."},"subject":{"type":"object","required":["object","id","tripId"],"properties":{"object":{"type":"string"},"id":{"type":"string","format":"uuid"},"tripId":{"type":["string","null"]}}},"changed":{"type":"array","items":{"type":"string"},"description":"The API fields that changed (…updated events); empty otherwise."},"data":{"type":"object","properties":{"object":{"type":"string","const":"document"},"id":{"type":"string","format":"uuid"},"tripId":{"type":"string","format":"uuid"},"folderId":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"description":"The folder it is filed in; null = loose (in no folder)."},"name":{"type":"string"},"mimeType":{"type":"string"},"byteSize":{"type":"integer","minimum":0},"status":{"type":"string","enum":["pending","ready"],"description":"`pending`: reserved, the upload is not complete — never listed. `ready`: a document."},"visibility":{"type":"string","enum":["staff","traveler"],"description":"`staff`: internal, only the agency sees it. `traveler`: released to the trip's travelers."},"visibleToTravelersNow":{"type":"boolean","description":"Released AND the trip is published: the traveler's app shows it right now."},"visibleAt":{"type":["string","null"],"description":"When it was last released to travelers; null while internal."},"visibleBy":{"anyOf":[{"type":"object","properties":{"id":{"type":"string"},"name":{"type":["string","null"]}},"required":["id","name"],"additionalProperties":false},{"type":"null"}]},"uploadedBy":{"anyOf":[{"type":"object","properties":{"id":{"type":"string"},"name":{"type":["string","null"]}},"required":["id","name"],"additionalProperties":false},{"type":"null"}]},"createdAt":{"type":"string"},"updatedAt":{"type":"string"},"appUrl":{"type":["string","null"],"description":"The trip's Documents tab in bymundi."}},"required":["object","id","tripId","folderId","name","mimeType","byteSize","status","visibility","visibleToTravelersNow","visibleAt","visibleBy","uploadedBy","createdAt","updatedAt","appUrl"],"additionalProperties":false}}}}}},"responses":{"2XX":{"description":"Received. Anything else, or no answer within 10 s, is retried."}}}},"document.deleted":{"post":{"summary":"document.deleted","description":"A document was deleted. `data` is null.\n\n**Needs:** `documents:read` on the endpoint's key.","tags":["Webhooks"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["id","type","timestamp","subject","changed","data"],"additionalProperties":false,"properties":{"id":{"type":"string","format":"uuid","description":"The event id — also the `webhook-id` header, identical on every retry."},"type":{"const":"document.deleted"},"timestamp":{"type":"string","format":"date-time","description":"When the change happened."},"subject":{"type":"object","required":["object","id","tripId"],"properties":{"object":{"type":"string"},"id":{"type":"string","format":"uuid"},"tripId":{"type":["string","null"]}}},"changed":{"type":"array","items":{"type":"string"},"description":"The API fields that changed (…updated events); empty otherwise."},"data":{"type":"null"}}}}}},"responses":{"2XX":{"description":"Received. Anything else, or no answer within 10 s, is retried."}}}},"ping":{"post":{"summary":"ping","description":"Sent only by POST /webhook-endpoints/{endpointId}/test, to that endpoint alone.","tags":["Webhooks"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["id","type","timestamp","subject","changed","data"],"additionalProperties":false,"properties":{"id":{"type":"string","format":"uuid","description":"The event id — also the `webhook-id` header, identical on every retry."},"type":{"const":"ping"},"timestamp":{"type":"string","format":"date-time","description":"When the change happened."},"subject":{"type":"object","required":["object","id","tripId"],"properties":{"object":{"type":"string"},"id":{"type":"string","format":"uuid"},"tripId":{"type":["string","null"]}}},"changed":{"type":"array","items":{"type":"string"},"description":"The API fields that changed (…updated events); empty otherwise."},"data":{"type":"null"}}}}}},"responses":{"2XX":{"description":"Received. Anything else, or no answer within 10 s, is retried."}}}}}}