changedInput schema / properties / ops / items / anyOf
Previous value: -[
- {
- "additionalProperties": false,
- "properties": {
- "op": {
- "const": "set_title"
- },
- "title": {
- "maxLength": 200,
- "minLength": 1,
- "type": "string"
- }
- },
- "required": [
- "op",
- "title"
- ],
- "type": "object"
- },
- {
- "additionalProperties": false,
- "properties": {
- "op": {
- "const": "set_start_date"
- },
- "startDate": {
- "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
- "type": "string"
- }
- },
- "required": [
- "op",
- "startDate"
- ],
- "type": "object"
- },
- {
- "additionalProperties": false,
- "properties": {
- "date": {
- "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
- "type": "string"
- },
- "op": {
- "const": "add_day"
- }
- },
- "required": [
- "op",
- "date"
- ],
- "type": "object"
- },
- {
- "additionalProperties": false,
- "properties": {
- "date": {
- "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
- "type": "string"
- },
- "force": {
- "description": "Required when the day holds stops or a booking starting that day: removes the day and its stops (bookings are kept). Without it such a day is refused, naming what it holds. Ask the traveller first.",
- "type": "boolean"
- },
- "op": {
- "const": "remove_day"
- }
- },
- "required": [
- "op",
- "date"
- ],
- "type": "object"
- },
- {
- "additionalProperties": false,
- "properties": {
- "date": {
- "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
- "type": "string"
- },
- "op": {
- "const": "set_day"
- },
- "summary": {
- "type": [
- "string",
- "null"
- ]
- },
- "town": {
- "type": [
- "string",
- "null"
- ]
- }
- },
- "required": [
- "op",
- "date"
- ],
- "type": "object"
- },
- {
- "additionalProperties": false,
- "properties": {
- "date": {
- "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
- "type": "string"
- },
- "op": {
- "const": "add_stop"
- },
- "position": {
- "minimum": 0,
- "type": "integer"
- },
- "stop": {
- "properties": {
- "booked": {
- "description": "For a restaurant, a tour or a ticketed sight: true once the traveller holds the table or ticket, false while it still needs booking (it then shows in the app's Still to book, with BOOK opening ticketsURL). Leave it out for a place that needs nothing.",
- "type": "boolean"
- },
- "category": {
- "maxLength": 60,
- "type": "string"
- },
- "lat": {
- "description": "Latitude of a real place with no meridian_url, to about 100 m: the app draws the travel line between two stops only when both have a location and a time. Give lat and lng together; they are checked against the stop's town.",
- "maximum": 90,
- "minimum": -90,
- "type": "number"
- },
- "lng": {
- "description": "Longitude, with lat.",
- "maximum": 180,
- "minimum": -180,
- "type": "number"
- },
- "meridian_url": {
- "description": "The url of a Meridian Dispatch place (from get_place, get_destination or search_guides). Sets the title, town and location from the guide, so the stop lands on the map.",
- "type": "string"
- },
- "minutes": {
- "maximum": 1440,
- "minimum": 1,
- "type": "integer"
- },
- "note": {
- "description": "A standing advisory about the place itself (closed Mondays, cash only, book weeks ahead): the app's Know before you go, replaced by the guide's own where a page exists. Not for what the traveller does there; that is visitNote.",
- "maxLength": 2000,
- "type": "string"
- },
- "prose": {
- "maxLength": 2000,
- "type": "string"
- },
- "ticketsURL": {
- "description": "https only. The official page to book this stop: a sight's own ticket shop, or for a restaurant its reservation page (its own site, or the booking service it uses: OpenTable, Resy, SevenRooms, TheFork, Tock). Still to book's BOOK opens it; without one the row shows no BOOK. Never a reseller or a search page.",
- "format": "uri",
- "type": "string"
- },
- "time": {
- "description": "HH:mm, 24-hour.",
- "pattern": "^([01]\\d|2[0-3]):[0-5]\\d$",
- "type": "string"
- },
- "title": {
- "maxLength": 200,
- "type": "string"
- },
- "town": {
- "maxLength": 100,
- "type": "string"
- },
- "type": {
- "description": "freeform for a transfer or a note.",
- "enum": [
- "activity",
- "restaurant",
- "freeform"
- ],
- "type": "string"
- },
- "visitNote": {
- "description": "ONE sentence (the day page shows only the first) on what the traveller does here on this day (\"Camel trek out for sunset on the dunes, then back to camp for dinner\"). Shown under the stop's name. Put the doing here and keep title the place's proper name (\"Erg Chebbi\", not \"Camel trek into Erg Chebbi\").",
- "maxLength": 240,
- "type": "string"
- }
- },
- "type": "object"
- }
- },
- "required": [
- "op",
- "date",
- "stop"
- ],
- "type": "object"
- },
- {
- "additionalProperties": false,
- "properties": {
- "fields": {
- "description": "null on a field clears it.",
- "properties": {
- "booked": {
- "description": "For a restaurant, a tour or a ticketed sight: true once the traveller holds the table or ticket, false while it still needs booking (it then shows in the app's Still to book, with BOOK opening ticketsURL). Leave it out for a place that needs nothing.",
- "type": "boolean"
- },
- "category": {
- "maxLength": 60,
- "type": "string"
- },
- "lat": {
- "description": "Latitude of a real place with no meridian_url, to about 100 m: the app draws the travel line between two stops only when both have a location and a time. Give lat and lng together; they are checked against the stop's town.",
- "maximum": 90,
- "minimum": -90,
- "type": "number"
- },
- "lng": {
- "description": "Longitude, with lat.",
- "maximum": 180,
- "minimum": -180,
- "type": "number"
- },
- "meridian_url": {
- "description": "The url of a Meridian Dispatch place (from get_place, get_destination or search_guides). Sets the title, town and location from the guide, so the stop lands on the map.",
- "type": "string"
- },
- "minutes": {
- "maximum": 1440,
- "minimum": 1,
- "type": "integer"
- },
- "note": {
- "description": "A standing advisory about the place itself (closed Mondays, cash only, book weeks ahead): the app's Know before you go, replaced by the guide's own where a page exists. Not for what the traveller does there; that is visitNote.",
- "maxLength": 2000,
- "type": "string"
- },
- "prose": {
- "maxLength": 2000,
- "type": "string"
- },
- "ticketsURL": {
- "description": "https only. The official page to book this stop: a sight's own ticket shop, or for a restaurant its reservation page (its own site, or the booking service it uses: OpenTable, Resy, SevenRooms, TheFork, Tock). Still to book's BOOK opens it; without one the row shows no BOOK. Never a reseller or a search page.",
- "format": "uri",
- "type": "string"
- },
- "time": {
- "description": "HH:mm, 24-hour.",
- "pattern": "^([01]\\d|2[0-3]):[0-5]\\d$",
- "type": "string"
- },
- "title": {
- "maxLength": 200,
- "type": "string"
- },
- "town": {
- "maxLength": 100,
- "type": "string"
- },
- "type": {
- "description": "freeform for a transfer or a note.",
- "enum": [
- "activity",
- "restaurant",
- "freeform"
- ],
- "type": "string"
- },
- "visitNote": {
- "description": "ONE sentence (the day page shows only the first) on what the traveller does here on this day (\"Camel trek out for sunset on the dunes, then back to camp for dinner\"). Shown under the stop's name. Put the doing here and keep title the place's proper name (\"Erg Chebbi\", not \"Camel trek into Erg Chebbi\").",
- "maxLength": 240,
- "type": "string"
- }
- },
- "type": "object"
- },
- "id": {
- "description": "A stop or booking id from get_plan.",
- "type": "string"
- },
- "op": {
- "const": "update_stop"
- }
- },
- "required": [
- "op",
- "id",
- "fields"
- ],
- "type": "object"
- },
- {
- "additionalProperties": false,
- "properties": {
- "date": {
- "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
- "type": "string"
- },
- "id": {
- "description": "A stop or booking id from get_plan.",
- "type": "string"
- },
- "op": {
- "const": "move_stop"
- },
- "position": {
- "minimum": 0,
- "type": "integer"
- }
- },
- "required": [
- "op",
- "id",
- "date"
- ],
- "type": "object"
- },
- {
- "additionalProperties": false,
- "properties": {
- "id": {
- "description": "A stop or booking id from get_plan.",
- "type": "string"
- },
- "op": {
- "const": "remove_stop"
- }
- },
- "required": [
- "op",
- "id"
- ],
- "type": "object"
- },
- {
- "additionalProperties": false,
- "properties": {
- "booking": {
- "properties": {
- "booked": {
- "type": "boolean"
- },
- "city": {
- "maxLength": 100,
- "type": "string"
- },
- "countryCode": {
- "pattern": "^[A-Za-z]{2}$",
- "type": "string"
- },
- "details": {
- "additionalProperties": {
- "type": "string"
- },
- "description": "The booking's particulars, in these keys only (any other is dropped). Fill every one you know: the app draws the booking from them, not from the title. A flight: airline, flightNumber, originCode and destinationCode (IATA), originAirport and destinationAirport (the airports' names), originCity and destinationCity, departureTerminal, arrivalTerminal, cabin, seat; startDate/startTime is the departure and endDate/endTime the arrival, local times. Prefer one booking per leg; a round trip already held as one booking carries returnAirline, returnFlightNumber, returnOriginCode, returnDestinationCode, returnDepartureDate, returnDepartureTime, returnArrivalDate, returnArrivalTime, returnSeat, with outboundArrivalDate/Time for the first leg. A hotel: address, website, roomType, nights (check-in and check-out times go in startTime and endTime). A restaurant: address, website, partySize (its stop's ticketsURL is the reservation page). A tour or activity: company (the operator), address (the meeting point), website. A train: operator, trainNumber, carriage, seat, originStation, destinationStation, originCity, destinationCity. A car rental: company, vehicleClass, pickupLocation, dropoffLocation. Never the name on the booking.",
- "properties": {
- "address": {
- "type": "string"
- },
- "airline": {
- "type": "string"
- },
- "arrivalTerminal": {
- "type": "string"
- },
- "cabin": {
- "type": "string"
- },
- "carriage": {
- "type": "string"
- },
- "company": {
- "type": "string"
- },
- "departureTerminal": {
- "type": "string"
- },
- "destinationAirport": {
- "type": "string"
- },
- "destinationCity": {
- "type": "string"
- },
- "destinationCode": {
- "pattern": "^[A-Z]{3}$",
- "type": "string"
- },
- "destinationStation": {
- "type": "string"
- },
- "dropoffLocation": {
- "type": "string"
- },
- "flightNumber": {
- "description": "e.g. OS36",
- "type": "string"
- },
- "nights": {
- "type": "string"
- },
- "operator": {
- "type": "string"
- },
- "originAirport": {
- "type": "string"
- },
- "originCity": {
- "type": "string"
- },
- "originCode": {
- "pattern": "^[A-Z]{3}$",
- "type": "string"
- },
- "originStation": {
- "type": "string"
- },
- "outboundArrivalDate": {
- "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
- "type": "string"
- },
- "outboundArrivalTime": {
- "pattern": "^([01]\\d|2[0-3]):[0-5]\\d$",
- "type": "string"
- },
- "outboundDepartureDate": {
- "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
- "type": "string"
- },
- "outboundDepartureTime": {
- "pattern": "^([01]\\d|2[0-3]):[0-5]\\d$",
- "type": "string"
- },
- "partySize": {
- "type": "string"
- },
- "pickupLocation": {
- "type": "string"
- },
- "returnAirline": {
- "type": "string"
- },
- "returnArrivalDate": {
- "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
- "type": "string"
- },
- "returnArrivalTime": {
- "pattern": "^([01]\\d|2[0-3]):[0-5]\\d$",
- "type": "string"
- },
- "returnDepartureDate": {
- "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
- "type": "string"
- },
- "returnDepartureTime": {
- "pattern": "^([01]\\d|2[0-3]):[0-5]\\d$",
- "type": "string"
- },
- "returnDestinationCode": {
- "pattern": "^[A-Z]{3}$",
- "type": "string"
- },
- "returnFlightNumber": {
- "type": "string"
- },
- "returnOriginCode": {
- "pattern": "^[A-Z]{3}$",
- "type": "string"
- },
- "returnSeat": {
- "type": "string"
- },
- "roomType": {
- "type": "string"
- },
- "seat": {
- "type": "string"
- },
- "trainNumber": {
- "type": "string"
- },
- "vehicleClass": {
- "type": "string"
- },
- "website": {
- "format": "uri",
- "type": "string"
- }
- },
- "type": "object"
- },
- "endDate": {
- "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
- "type": "string"
- },
- "endTime": {
- "pattern": "^([01]\\d|2[0-3]):[0-5]\\d$",
- "type": "string"
- },
- "startDate": {
- "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
- "type": "string"
- },
- "startTime": {
- "pattern": "^([01]\\d|2[0-3]):[0-5]\\d$",
- "type": "string"
- },
- "subtitle": {
- "maxLength": 200,
- "type": "string"
- },
- "title": {
- "maxLength": 200,
- "type": "string"
- },
- "type": {
- "enum": [
- "hotel",
- "flight",
- "train",
- "carRental",
- "restaurant",
- "activity",
- "other"
- ],
- "type": "string"
- }
- },
- "required": [
- "type",
- "title"
- ],
- "type": "object"
- },
- "op": {
- "const": "add_booking"
- }
- },
- "required": [
- "op",
- "booking"
- ],
- "type": "object"
- },
- {
- "additionalProperties": false,
- "properties": {
- "fields": {
- "properties": {
- "booked": {
- "type": "boolean"
- },
- "city": {
- "maxLength": 100,
- "type": "string"
- },
- "countryCode": {
- "pattern": "^[A-Za-z]{2}$",
- "type": "string"
- },
- "details": {
- "additionalProperties": {
- "type": "string"
- },
- "description": "The booking's particulars, in these keys only (any other is dropped). Fill every one you know: the app draws the booking from them, not from the title. A flight: airline, flightNumber, originCode and destinationCode (IATA), originAirport and destinationAirport (the airports' names), originCity and destinationCity, departureTerminal, arrivalTerminal, cabin, seat; startDate/startTime is the departure and endDate/endTime the arrival, local times. Prefer one booking per leg; a round trip already held as one booking carries returnAirline, returnFlightNumber, returnOriginCode, returnDestinationCode, returnDepartureDate, returnDepartureTime, returnArrivalDate, returnArrivalTime, returnSeat, with outboundArrivalDate/Time for the first leg. A hotel: address, website, roomType, nights (check-in and check-out times go in startTime and endTime). A restaurant: address, website, partySize (its stop's ticketsURL is the reservation page). A tour or activity: company (the operator), address (the meeting point), website. A train: operator, trainNumber, carriage, seat, originStation, destinationStation, originCity, destinationCity. A car rental: company, vehicleClass, pickupLocation, dropoffLocation. Never the name on the booking.",
- "properties": {
- "address": {
- "type": "string"
- },
- "airline": {
- "type": "string"
- },
- "arrivalTerminal": {
- "type": "string"
- },
- "cabin": {
- "type": "string"
- },
- "carriage": {
- "type": "string"
- },
- "company": {
- "type": "string"
- },
- "departureTerminal": {
- "type": "string"
- },
- "destinationAirport": {
- "type": "string"
- },
- "destinationCity": {
- "type": "string"
- },
- "destinationCode": {
- "pattern": "^[A-Z]{3}$",
- "type": "string"
- },
- "destinationStation": {
- "type": "string"
- },
- "dropoffLocation": {
- "type": "string"
- },
- "flightNumber": {
- "description": "e.g. OS36",
- "type": "string"
- },
- "nights": {
- "type": "string"
- },
- "operator": {
- "type": "string"
- },
- "originAirport": {
- "type": "string"
- },
- "originCity": {
- "type": "string"
- },
- "originCode": {
- "pattern": "^[A-Z]{3}$",
- "type": "string"
- },
- "originStation": {
- "type": "string"
- },
- "outboundArrivalDate": {
- "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
- "type": "string"
- },
- "outboundArrivalTime": {
- "pattern": "^([01]\\d|2[0-3]):[0-5]\\d$",
- "type": "string"
- },
- "outboundDepartureDate": {
- "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
- "type": "string"
- },
- "outboundDepartureTime": {
- "pattern": "^([01]\\d|2[0-3]):[0-5]\\d$",
- "type": "string"
- },
- "partySize": {
- "type": "string"
- },
- "pickupLocation": {
- "type": "string"
- },
- "returnAirline": {
- "type": "string"
- },
- "returnArrivalDate": {
- "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
- "type": "string"
- },
- "returnArrivalTime": {
- "pattern": "^([01]\\d|2[0-3]):[0-5]\\d$",
- "type": "string"
- },
- "returnDepartureDate": {
- "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
- "type": "string"
- },
- "returnDepartureTime": {
- "pattern": "^([01]\\d|2[0-3]):[0-5]\\d$",
- "type": "string"
- },
- "returnDestinationCode": {
- "pattern": "^[A-Z]{3}$",
- "type": "string"
- },
- "returnFlightNumber": {
- "type": "string"
- },
- "returnOriginCode": {
- "pattern": "^[A-Z]{3}$",
- "type": "string"
- },
- "returnSeat": {
- "type": "string"
- },
- "roomType": {
- "type": "string"
- },
- "seat": {
- "type": "string"
- },
- "trainNumber": {
- "type": "string"
- },
- "vehicleClass": {
- "type": "string"
- },
- "website": {
- "format": "uri",
- "type": "string"
- }
- },
- "type": "object"
- },
- "endDate": {
- "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
- "type": "string"
- },
- "endTime": {
- "pattern": "^([01]\\d|2[0-3]):[0-5]\\d$",
- "type": "string"
- },
- "startDate": {
- "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
- "type": "string"
- },
- "startTime": {
- "pattern": "^([01]\\d|2[0-3]):[0-5]\\d$",
- "type": "string"
- },
- "subtitle": {
- "maxLength": 200,
- "type": "string"
- },
- "title": {
- "maxLength": 200,
- "type": "string"
- },
- "type": {
- "enum": [
- "hotel",
- "flight",
- "train",
- "carRental",
- "restaurant",
- "activity",
- "other"
- ],
- "type": "string"
- }
- },
- "type": "object"
- },
- "id": {
- "description": "A stop or booking id from get_plan.",
- "type": "string"
- },
- "op": {
- "const": "update_booking"
- }
- },
- "required": [
- "op",
- "id",
- "fields"
- ],
- "type": "object"
- },
- {
- "additionalProperties": false,
- "properties": {
- "id": {
- "description": "A stop or booking id from get_plan.",
- "type": "string"
- },
- "op": {
- "const": "remove_booking"
- }
- },
- "required": [
- "op",
- "id"
- ],
- "type": "object"
- }
-]New value: +[
+ {
+ "additionalProperties": false,
+ "properties": {
+ "op": {
+ "const": "set_title"
+ },
+ "title": {
+ "maxLength": 200,
+ "minLength": 1,
+ "type": "string"
+ }
+ },
+ "required": [
+ "op",
+ "title"
+ ],
+ "type": "object"
+ },
+ {
+ "additionalProperties": false,
+ "properties": {
+ "op": {
+ "const": "set_start_date"
+ },
+ "startDate": {
+ "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
+ "type": "string"
+ }
+ },
+ "required": [
+ "op",
+ "startDate"
+ ],
+ "type": "object"
+ },
+ {
+ "additionalProperties": false,
+ "properties": {
+ "date": {
+ "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
+ "type": "string"
+ },
+ "op": {
+ "const": "add_day"
+ }
+ },
+ "required": [
+ "op",
+ "date"
+ ],
+ "type": "object"
+ },
+ {
+ "additionalProperties": false,
+ "properties": {
+ "date": {
+ "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
+ "type": "string"
+ },
+ "force": {
+ "description": "Required when the day holds stops or a booking starting that day: removes the day and its stops (bookings are kept). Without it such a day is refused, naming what it holds. Ask the traveller first.",
+ "type": "boolean"
+ },
+ "op": {
+ "const": "remove_day"
+ }
+ },
+ "required": [
+ "op",
+ "date"
+ ],
+ "type": "object"
+ },
+ {
+ "additionalProperties": false,
+ "properties": {
+ "date": {
+ "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
+ "type": "string"
+ },
+ "force": {
+ "description": "Required when the day holds stops: they are removed (its notes move to the day before). Ask the traveller first.",
+ "type": "boolean"
+ },
+ "op": {
+ "const": "close_day"
+ }
+ },
+ "required": [
+ "op",
+ "date"
+ ],
+ "type": "object"
+ },
+ {
+ "additionalProperties": false,
+ "properties": {
+ "date": {
+ "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
+ "type": "string"
+ },
+ "op": {
+ "const": "set_day"
+ },
+ "summary": {
+ "type": [
+ "string",
+ "null"
+ ]
+ },
+ "town": {
+ "type": [
+ "string",
+ "null"
+ ]
+ }
+ },
+ "required": [
+ "op",
+ "date"
+ ],
+ "type": "object"
+ },
+ {
+ "additionalProperties": false,
+ "properties": {
+ "date": {
+ "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
+ "type": "string"
+ },
+ "op": {
+ "const": "add_stop"
+ },
+ "position": {
+ "minimum": 0,
+ "type": "integer"
+ },
+ "stop": {
+ "properties": {
+ "booked": {
+ "description": "For a restaurant, a tour or a ticketed sight: true once the traveller holds the table or ticket, false while it still needs booking (it then shows in the app's Still to book, with BOOK opening ticketsURL). Leave it out for a place that needs nothing.",
+ "type": "boolean"
+ },
+ "category": {
+ "maxLength": 60,
+ "type": "string"
+ },
+ "lat": {
+ "description": "Latitude of a real place with no meridian_url, to about 100 m: the app draws the travel line between two stops only when both have a location and a time. Give lat and lng together; they are checked against the stop's town.",
+ "maximum": 90,
+ "minimum": -90,
+ "type": "number"
+ },
+ "lng": {
+ "description": "Longitude, with lat.",
+ "maximum": 180,
+ "minimum": -180,
+ "type": "number"
+ },
+ "meridian_url": {
+ "description": "The url of a Meridian Dispatch place (from get_place, get_destination or search_guides). Sets the title, town and location from the guide, so the stop lands on the map.",
+ "type": "string"
+ },
+ "minutes": {
+ "maximum": 1440,
+ "minimum": 1,
+ "type": "integer"
+ },
+ "note": {
+ "description": "A standing advisory about the place itself (closed Mondays, cash only, book weeks ahead): the app's Know before you go, replaced by the guide's own where a page exists. Not for what the traveller does there; that is visitNote.",
+ "maxLength": 2000,
+ "type": "string"
+ },
+ "prose": {
+ "maxLength": 2000,
+ "type": "string"
+ },
+ "ticketsURL": {
+ "description": "https only. The official page to book this stop: a sight's own ticket shop, or for a restaurant its reservation page (its own site, or the booking service it uses: OpenTable, Resy, SevenRooms, TheFork, Tock). Still to book's BOOK opens it; without one the row shows no BOOK. Never a reseller or a search page.",
+ "format": "uri",
+ "type": "string"
+ },
+ "time": {
+ "description": "HH:mm, 24-hour.",
+ "pattern": "^([01]\\d|2[0-3]):[0-5]\\d$",
+ "type": "string"
+ },
+ "title": {
+ "maxLength": 200,
+ "type": "string"
+ },
+ "town": {
+ "maxLength": 100,
+ "type": "string"
+ },
+ "type": {
+ "description": "freeform for a transfer or a note.",
+ "enum": [
+ "activity",
+ "restaurant",
+ "freeform"
+ ],
+ "type": "string"
+ },
+ "visitNote": {
+ "description": "ONE sentence (the day page shows only the first) on what the traveller does here on this day (\"Camel trek out for sunset on the dunes, then back to camp for dinner\"). Shown under the stop's name. Put the doing here and keep title the place's proper name (\"Erg Chebbi\", not \"Camel trek into Erg Chebbi\").",
+ "maxLength": 240,
+ "type": "string"
+ }
+ },
+ "type": "object"
+ }
+ },
+ "required": [
+ "op",
+ "date",
+ "stop"
+ ],
+ "type": "object"
+ },
+ {
+ "additionalProperties": false,
+ "properties": {
+ "fields": {
+ "description": "null on a field clears it.",
+ "properties": {
+ "booked": {
+ "description": "For a restaurant, a tour or a ticketed sight: true once the traveller holds the table or ticket, false while it still needs booking (it then shows in the app's Still to book, with BOOK opening ticketsURL). Leave it out for a place that needs nothing.",
+ "type": "boolean"
+ },
+ "category": {
+ "maxLength": 60,
+ "type": "string"
+ },
+ "lat": {
+ "description": "Latitude of a real place with no meridian_url, to about 100 m: the app draws the travel line between two stops only when both have a location and a time. Give lat and lng together; they are checked against the stop's town.",
+ "maximum": 90,
+ "minimum": -90,
+ "type": "number"
+ },
+ "lng": {
+ "description": "Longitude, with lat.",
+ "maximum": 180,
+ "minimum": -180,
+ "type": "number"
+ },
+ "meridian_url": {
+ "description": "The url of a Meridian Dispatch place (from get_place, get_destination or search_guides). Sets the title, town and location from the guide, so the stop lands on the map.",
+ "type": "string"
+ },
+ "minutes": {
+ "maximum": 1440,
+ "minimum": 1,
+ "type": "integer"
+ },
+ "note": {
+ "description": "A standing advisory about the place itself (closed Mondays, cash only, book weeks ahead): the app's Know before you go, replaced by the guide's own where a page exists. Not for what the traveller does there; that is visitNote.",
+ "maxLength": 2000,
+ "type": "string"
+ },
+ "prose": {
+ "maxLength": 2000,
+ "type": "string"
+ },
+ "ticketsURL": {
+ "description": "https only. The official page to book this stop: a sight's own ticket shop, or for a restaurant its reservation page (its own site, or the booking service it uses: OpenTable, Resy, SevenRooms, TheFork, Tock). Still to book's BOOK opens it; without one the row shows no BOOK. Never a reseller or a search page.",
+ "format": "uri",
+ "type": "string"
+ },
+ "time": {
+ "description": "HH:mm, 24-hour.",
+ "pattern": "^([01]\\d|2[0-3]):[0-5]\\d$",
+ "type": "string"
+ },
+ "title": {
+ "maxLength": 200,
+ "type": "string"
+ },
+ "town": {
+ "maxLength": 100,
+ "type": "string"
+ },
+ "type": {
+ "description": "freeform for a transfer or a note.",
+ "enum": [
+ "activity",
+ "restaurant",
+ "freeform"
+ ],
+ "type": "string"
+ },
+ "visitNote": {
+ "description": "ONE sentence (the day page shows only the first) on what the traveller does here on this day (\"Camel trek out for sunset on the dunes, then back to camp for dinner\"). Shown under the stop's name. Put the doing here and keep title the place's proper name (\"Erg Chebbi\", not \"Camel trek into Erg Chebbi\").",
+ "maxLength": 240,
+ "type": "string"
+ }
+ },
+ "type": "object"
+ },
+ "id": {
+ "description": "A stop or booking id from get_plan.",
+ "type": "string"
+ },
+ "op": {
+ "const": "update_stop"
+ }
+ },
+ "required": [
+ "op",
+ "id",
+ "fields"
+ ],
+ "type": "object"
+ },
+ {
+ "additionalProperties": false,
+ "properties": {
+ "date": {
+ "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
+ "type": "string"
+ },
+ "id": {
+ "description": "A stop or booking id from get_plan.",
+ "type": "string"
+ },
+ "op": {
+ "const": "move_stop"
+ },
+ "position": {
+ "minimum": 0,
+ "type": "integer"
+ }
+ },
+ "required": [
+ "op",
+ "id",
+ "date"
+ ],
+ "type": "object"
+ },
+ {
+ "additionalProperties": false,
+ "properties": {
+ "id": {
+ "description": "A stop or booking id from get_plan.",
+ "type": "string"
+ },
+ "op": {
+ "const": "remove_stop"
+ }
+ },
+ "required": [
+ "op",
+ "id"
+ ],
+ "type": "object"
+ },
+ {
+ "additionalProperties": false,
+ "properties": {
+ "booking": {
+ "properties": {
+ "booked": {
+ "type": "boolean"
+ },
+ "city": {
+ "maxLength": 100,
+ "type": "string"
+ },
+ "countryCode": {
+ "pattern": "^[A-Za-z]{2}$",
+ "type": "string"
+ },
+ "details": {
+ "additionalProperties": {
+ "type": "string"
+ },
+ "description": "The booking's particulars, in these keys only (any other is dropped). Fill every one you know: the app draws the booking from them, not from the title. A flight: airline, flightNumber, originCode and destinationCode (IATA), originAirport and destinationAirport (the airports' names), originCity and destinationCity, departureTerminal, arrivalTerminal, cabin, seat; startDate/startTime is the departure and endDate/endTime the arrival, local times. Prefer one booking per leg; a round trip already held as one booking carries returnAirline, returnFlightNumber, returnOriginCode, returnDestinationCode, returnDepartureDate, returnDepartureTime, returnArrivalDate, returnArrivalTime, returnSeat, with outboundArrivalDate/Time for the first leg. A hotel: address, website, roomType, nights (check-in and check-out times go in startTime and endTime). A restaurant: address, website, partySize (its stop's ticketsURL is the reservation page). A tour or activity: company (the operator), address (the meeting point), website. A train: operator, trainNumber, carriage, seat, originStation, destinationStation, originCity, destinationCity. A car rental: company, vehicleClass, pickupLocation, dropoffLocation. Never the name on the booking.",
+ "properties": {
+ "address": {
+ "type": "string"
+ },
+ "airline": {
+ "type": "string"
+ },
+ "arrivalTerminal": {
+ "type": "string"
+ },
+ "cabin": {
+ "type": "string"
+ },
+ "carriage": {
+ "type": "string"
+ },
+ "company": {
+ "type": "string"
+ },
+ "departureTerminal": {
+ "type": "string"
+ },
+ "destinationAirport": {
+ "type": "string"
+ },
+ "destinationCity": {
+ "type": "string"
+ },
+ "destinationCode": {
+ "pattern": "^[A-Z]{3}$",
+ "type": "string"
+ },
+ "destinationStation": {
+ "type": "string"
+ },
+ "dropoffLocation": {
+ "type": "string"
+ },
+ "flightNumber": {
+ "description": "e.g. OS36",
+ "type": "string"
+ },
+ "nights": {
+ "type": "string"
+ },
+ "operator": {
+ "type": "string"
+ },
+ "originAirport": {
+ "type": "string"
+ },
+ "originCity": {
+ "type": "string"
+ },
+ "originCode": {
+ "pattern": "^[A-Z]{3}$",
+ "type": "string"
+ },
+ "originStation": {
+ "type": "string"
+ },
+ "outboundArrivalDate": {
+ "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
+ "type": "string"
+ },
+ "outboundArrivalTime": {
+ "pattern": "^([01]\\d|2[0-3]):[0-5]\\d$",
+ "type": "string"
+ },
+ "outboundDepartureDate": {
+ "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
+ "type": "string"
+ },
+ "outboundDepartureTime": {
+ "pattern": "^([01]\\d|2[0-3]):[0-5]\\d$",
+ "type": "string"
+ },
+ "partySize": {
+ "type": "string"
+ },
+ "pickupLocation": {
+ "type": "string"
+ },
+ "returnAirline": {
+ "type": "string"
+ },
+ "returnArrivalDate": {
+ "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
+ "type": "string"
+ },
+ "returnArrivalTime": {
+ "pattern": "^([01]\\d|2[0-3]):[0-5]\\d$",
+ "type": "string"
+ },
+ "returnDepartureDate": {
+ "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
+ "type": "string"
+ },
+ "returnDepartureTime": {
+ "pattern": "^([01]\\d|2[0-3]):[0-5]\\d$",
+ "type": "string"
+ },
+ "returnDestinationCode": {
+ "pattern": "^[A-Z]{3}$",
+ "type": "string"
+ },
+ "returnFlightNumber": {
+ "type": "string"
+ },
+ "returnOriginCode": {
+ "pattern": "^[A-Z]{3}$",
+ "type": "string"
+ },
+ "returnSeat": {
+ "type": "string"
+ },
+ "roomType": {
+ "type": "string"
+ },
+ "seat": {
+ "type": "string"
+ },
+ "trainNumber": {
+ "type": "string"
+ },
+ "vehicleClass": {
+ "type": "string"
+ },
+ "website": {
+ "format": "uri",
+ "type": "string"
+ }
+ },
+ "type": "object"
+ },
+ "endDate": {
+ "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
+ "type": "string"
+ },
+ "endTime": {
+ "pattern": "^([01]\\d|2[0-3]):[0-5]\\d$",
+ "type": "string"
+ },
+ "startDate": {
+ "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
+ "type": "string"
+ },
+ "startTime": {
+ "pattern": "^([01]\\d|2[0-3]):[0-5]\\d$",
+ "type": "string"
+ },
+ "subtitle": {
+ "maxLength": 200,
+ "type": "string"
+ },
+ "title": {
+ "maxLength": 200,
+ "type": "string"
+ },
+ "type": {
+ "enum": [
+ "hotel",
+ "flight",
+ "train",
+ "carRental",
+ "restaurant",
+ "activity",
+ "other"
+ ],
+ "type": "string"
+ }
+ },
+ "required": [
+ "type",
+ "title"
+ ],
+ "type": "object"
+ },
+ "op": {
+ "const": "add_booking"
+ }
+ },
+ "required": [
+ "op",
+ "booking"
+ ],
+ "type": "object"
+ },
+ {
+ "additionalProperties": false,
+ "properties": {
+ "fields": {
+ "properties": {
+ "booked": {
+ "type": "boolean"
+ },
+ "city": {
+ "maxLength": 100,
+ "type": "string"
+ },
+ "countryCode": {
+ "pattern": "^[A-Za-z]{2}$",
+ "type": "string"
+ },
+ "details": {
+ "additionalProperties": {
+ "type": "string"
+ },
+ "description": "The booking's particulars, in these keys only (any other is dropped). Fill every one you know: the app draws the booking from them, not from the title. A flight: airline, flightNumber, originCode and destinationCode (IATA), originAirport and destinationAirport (the airports' names), originCity and destinationCity, departureTerminal, arrivalTerminal, cabin, seat; startDate/startTime is the departure and endDate/endTime the arrival, local times. Prefer one booking per leg; a round trip already held as one booking carries returnAirline, returnFlightNumber, returnOriginCode, returnDestinationCode, returnDepartureDate, returnDepartureTime, returnArrivalDate, returnArrivalTime, returnSeat, with outboundArrivalDate/Time for the first leg. A hotel: address, website, roomType, nights (check-in and check-out times go in startTime and endTime). A restaurant: address, website, partySize (its stop's ticketsURL is the reservation page). A tour or activity: company (the operator), address (the meeting point), website. A train: operator, trainNumber, carriage, seat, originStation, destinationStation, originCity, destinationCity. A car rental: company, vehicleClass, pickupLocation, dropoffLocation. Never the name on the booking.",
+ "properties": {
+ "address": {
+ "type": "string"
+ },
+ "airline": {
+ "type": "string"
+ },
+ "arrivalTerminal": {
+ "type": "string"
+ },
+ "cabin": {
+ "type": "string"
+ },
+ "carriage": {
+ "type": "string"
+ },
+ "company": {
+ "type": "string"
+ },
+ "departureTerminal": {
+ "type": "string"
+ },
+ "destinationAirport": {
+ "type": "string"
+ },
+ "destinationCity": {
+ "type": "string"
+ },
+ "destinationCode": {
+ "pattern": "^[A-Z]{3}$",
+ "type": "string"
+ },
+ "destinationStation": {
+ "type": "string"
+ },
+ "dropoffLocation": {
+ "type": "string"
+ },
+ "flightNumber": {
+ "description": "e.g. OS36",
+ "type": "string"
+ },
+ "nights": {
+ "type": "string"
+ },
+ "operator": {
+ "type": "string"
+ },
+ "originAirport": {
+ "type": "string"
+ },
+ "originCity": {
+ "type": "string"
+ },
+ "originCode": {
+ "pattern": "^[A-Z]{3}$",
+ "type": "string"
+ },
+ "originStation": {
+ "type": "string"
+ },
+ "outboundArrivalDate": {
+ "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
+ "type": "string"
+ },
+ "outboundArrivalTime": {
+ "pattern": "^([01]\\d|2[0-3]):[0-5]\\d$",
+ "type": "string"
+ },
+ "outboundDepartureDate": {
+ "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
+ "type": "string"
+ },
+ "outboundDepartureTime": {
+ "pattern": "^([01]\\d|2[0-3]):[0-5]\\d$",
+ "type": "string"
+ },
+ "partySize": {
+ "type": "string"
+ },
+ "pickupLocation": {
+ "type": "string"
+ },
+ "returnAirline": {
+ "type": "string"
+ },
+ "returnArrivalDate": {
+ "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
+ "type": "string"
+ },
+ "returnArrivalTime": {
+ "pattern": "^([01]\\d|2[0-3]):[0-5]\\d$",
+ "type": "string"
+ },
+ "returnDepartureDate": {
+ "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
+ "type": "string"
+ },
+ "returnDepartureTime": {
+ "pattern": "^([01]\\d|2[0-3]):[0-5]\\d$",
+ "type": "string"
+ },
+ "returnDestinationCode": {
+ "pattern": "^[A-Z]{3}$",
+ "type": "string"
+ },
+ "returnFlightNumber": {
+ "type": "string"
+ },
+ "returnOriginCode": {
+ "pattern": "^[A-Z]{3}$",
+ "type": "string"
+ },
+ "returnSeat": {
+ "type": "string"
+ },
+ "roomType": {
+ "type": "string"
+ },
+ "seat": {
+ "type": "string"
+ },
+ "trainNumber": {
+ "type": "string"
+ },
+ "vehicleClass": {
+ "type": "string"
+ },
+ "website": {
+ "format": "uri",
+ "type": "string"
+ }
+ },
+ "type": "object"
+ },
+ "endDate": {
+ "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
+ "type": "string"
+ },
+ "endTime": {
+ "pattern": "^([01]\\d|2[0-3]):[0-5]\\d$",
+ "type": "string"
+ },
+ "startDate": {
+ "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
+ "type": "string"
+ },
+ "startTime": {
+ "pattern": "^([01]\\d|2[0-3]):[0-5]\\d$",
+ "type": "string"
+ },
+ "subtitle": {
+ "maxLength": 200,
+ "type": "string"
+ },
+ "title": {
+ "maxLength": 200,
+ "type": "string"
+ },
+ "type": {
+ "enum": [
+ "hotel",
+ "flight",
+ "train",
+ "carRental",
+ "restaurant",
+ "activity",
+ "other"
+ ],
+ "type": "string"
+ }
+ },
+ "type": "object"
+ },
+ "id": {
+ "description": "A stop or booking id from get_plan.",
+ "type": "string"
+ },
+ "op": {
+ "const": "update_booking"
+ }
+ },
+ "required": [
+ "op",
+ "id",
+ "fields"
+ ],
+ "type": "object"
+ },
+ {
+ "additionalProperties": false,
+ "properties": {
+ "id": {
+ "description": "A stop or booking id from get_plan.",
+ "type": "string"
+ },
+ "op": {
+ "const": "remove_booking"
+ }
+ },
+ "required": [
+ "op",
+ "id"
+ ],
+ "type": "object"
+ }
+]