Skip to main content
Glama

Change one of my plans

edit_plan
Destructive

Change a plan with a list of ops (see the ops schema), applied in order, all or nothing; days are named by date (YYYY-MM-DD), set_start_date moves every day and booking, and close_day takes out a day between the first and last and moves every later day one date earlier (bookings keep their dates). base_seq is required: the seq from get_plan, so a plan changed elsewhere since you read it is refused rather than overwritten; on a conflict, read it again and redo the edit. Stop and booking ids come from get_plan. Prefer places from get_destination or get_place (meridian_url), so the map can place them; title each place by its proper name with what the traveller does there in visitNote, give every other real place its lat and lng, and every place a time, in the order of the day, so the app can draw the travel between them (a place without a time is timed after the one before it). Ask the traveller before removing anything. Needs sign-in.

Input Schema

NameRequiredDescriptionDefault
opsYes
plan_idYes
verboseNoReturn the whole plan. By default the reply shows only the days and bookings the edit touched.
base_seqYesThe seq from get_plan or list_my_plans. Required.

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed1 schema field changed
    • 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"
      +  }
      +]
  2. Changed1 schema field changed
    • 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": {
      -          "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": {
      -            "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": {
      -          "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": {
      -            "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"
      -            },
      -            "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"
      -            },
      -            "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"
      +      },
      +      "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"
      +  }
      +]
  3. Changed1 schema field changed
    • 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": {
      -          "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": {
      -            "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 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": 500,
      -            "type": "string"
      -          }
      -        },
      -        "type": "object"
      -      }
      -    },
      -    "required": [
      -      "op",
      -      "date",
      -      "stop"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "additionalProperties": false,
      -    "properties": {
      -      "fields": {
      -        "description": "null on a field clears it.",
      -        "properties": {
      -          "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": {
      -            "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 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": 500,
      -            "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"
      -            },
      -            "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"
      -            },
      -            "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"
      +      },
      +      "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": {
      +          "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": {
      +            "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": {
      +          "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": {
      +            "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"
      +            },
      +            "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"
      +            },
      +            "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"
      +  }
      +]
  4. Changed1 schema field changed
    • 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": {
      -          "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": {
      -            "maxLength": 2000,
      -            "type": "string"
      -          },
      -          "prose": {
      -            "maxLength": 2000,
      -            "type": "string"
      -          },
      -          "ticketsURL": {
      -            "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"
      -          }
      -        },
      -        "type": "object"
      -      }
      -    },
      -    "required": [
      -      "op",
      -      "date",
      -      "stop"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "additionalProperties": false,
      -    "properties": {
      -      "fields": {
      -        "description": "null on a field clears it.",
      -        "properties": {
      -          "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": {
      -            "maxLength": 2000,
      -            "type": "string"
      -          },
      -          "prose": {
      -            "maxLength": 2000,
      -            "type": "string"
      -          },
      -          "ticketsURL": {
      -            "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"
      -          }
      -        },
      -        "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"
      -            },
      -            "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"
      -            },
      -            "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"
      +      },
      +      "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": {
      +          "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": {
      +            "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 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": 500,
      +            "type": "string"
      +          }
      +        },
      +        "type": "object"
      +      }
      +    },
      +    "required": [
      +      "op",
      +      "date",
      +      "stop"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "additionalProperties": false,
      +    "properties": {
      +      "fields": {
      +        "description": "null on a field clears it.",
      +        "properties": {
      +          "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": {
      +            "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 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": 500,
      +            "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"
      +            },
      +            "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"
      +            },
      +            "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"
      +  }
      +]
  5. Changed3 schema fields changed
    • changedInput schema / properties / base_seq / description
      Previous value: -"The seq from get_plan or list_my_plans."New value: +"The seq from get_plan or list_my_plans. Required."
    • 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"
      -      },
      -      "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": {
      -          "category": {
      -            "maxLength": 60,
      -            "type": "string"
      -          },
      -          "meridian_url": {
      -            "description": "The url of a Meridian Dispatch place (from get_place, get_destination or search_guides). Sets the title and town from the guide, so the stop lands on the map.",
      -            "type": "string"
      -          },
      -          "minutes": {
      -            "maximum": 1440,
      -            "minimum": 1,
      -            "type": "integer"
      -          },
      -          "note": {
      -            "maxLength": 2000,
      -            "type": "string"
      -          },
      -          "prose": {
      -            "maxLength": 2000,
      -            "type": "string"
      -          },
      -          "ticketsURL": {
      -            "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"
      -          }
      -        },
      -        "type": "object"
      -      }
      -    },
      -    "required": [
      -      "op",
      -      "date",
      -      "stop"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "additionalProperties": false,
      -    "properties": {
      -      "fields": {
      -        "description": "null on a field clears it.",
      -        "properties": {
      -          "category": {
      -            "maxLength": 60,
      -            "type": "string"
      -          },
      -          "meridian_url": {
      -            "description": "The url of a Meridian Dispatch place (from get_place, get_destination or search_guides). Sets the title and town from the guide, so the stop lands on the map.",
      -            "type": "string"
      -          },
      -          "minutes": {
      -            "maximum": 1440,
      -            "minimum": 1,
      -            "type": "integer"
      -          },
      -          "note": {
      -            "maxLength": 2000,
      -            "type": "string"
      -          },
      -          "prose": {
      -            "maxLength": 2000,
      -            "type": "string"
      -          },
      -          "ticketsURL": {
      -            "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"
      -          }
      -        },
      -        "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"
      -            },
      -            "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"
      -            },
      -            "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"
      +      },
      +      "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": {
      +          "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": {
      +            "maxLength": 2000,
      +            "type": "string"
      +          },
      +          "prose": {
      +            "maxLength": 2000,
      +            "type": "string"
      +          },
      +          "ticketsURL": {
      +            "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"
      +          }
      +        },
      +        "type": "object"
      +      }
      +    },
      +    "required": [
      +      "op",
      +      "date",
      +      "stop"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "additionalProperties": false,
      +    "properties": {
      +      "fields": {
      +        "description": "null on a field clears it.",
      +        "properties": {
      +          "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": {
      +            "maxLength": 2000,
      +            "type": "string"
      +          },
      +          "prose": {
      +            "maxLength": 2000,
      +            "type": "string"
      +          },
      +          "ticketsURL": {
      +            "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"
      +          }
      +        },
      +        "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"
      +            },
      +            "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"
      +            },
      +            "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"
      +  }
      +]
    • changedInput schema / required
      Previous value: -[
      -  "plan_id",
      -  "ops"
      -]New value: +[
      +  "plan_id",
      +  "base_seq",
      +  "ops"
      +]
  6. Changed5 schema fields changed
    • addedInput schema / properties / ops / items / anyOf
      Added 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"
      +      },
      +      "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": {
      +          "category": {
      +            "maxLength": 60,
      +            "type": "string"
      +          },
      +          "meridian_url": {
      +            "description": "The url of a Meridian Dispatch place (from get_place, get_destination or search_guides). Sets the title and town from the guide, so the stop lands on the map.",
      +            "type": "string"
      +          },
      +          "minutes": {
      +            "maximum": 1440,
      +            "minimum": 1,
      +            "type": "integer"
      +          },
      +          "note": {
      +            "maxLength": 2000,
      +            "type": "string"
      +          },
      +          "prose": {
      +            "maxLength": 2000,
      +            "type": "string"
      +          },
      +          "ticketsURL": {
      +            "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"
      +          }
      +        },
      +        "type": "object"
      +      }
      +    },
      +    "required": [
      +      "op",
      +      "date",
      +      "stop"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "additionalProperties": false,
      +    "properties": {
      +      "fields": {
      +        "description": "null on a field clears it.",
      +        "properties": {
      +          "category": {
      +            "maxLength": 60,
      +            "type": "string"
      +          },
      +          "meridian_url": {
      +            "description": "The url of a Meridian Dispatch place (from get_place, get_destination or search_guides). Sets the title and town from the guide, so the stop lands on the map.",
      +            "type": "string"
      +          },
      +          "minutes": {
      +            "maximum": 1440,
      +            "minimum": 1,
      +            "type": "integer"
      +          },
      +          "note": {
      +            "maxLength": 2000,
      +            "type": "string"
      +          },
      +          "prose": {
      +            "maxLength": 2000,
      +            "type": "string"
      +          },
      +          "ticketsURL": {
      +            "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"
      +          }
      +        },
      +        "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"
      +            },
      +            "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"
      +            },
      +            "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"
      +  }
      +]
    • removedInput schema / properties / ops / items / properties
      Removed value: -{
      -  "op": {
      -    "enum": [
      -      "set_title",
      -      "set_start_date",
      -      "add_day",
      -      "remove_day",
      -      "set_day",
      -      "add_stop",
      -      "update_stop",
      -      "move_stop",
      -      "remove_stop",
      -      "add_booking",
      -      "update_booking",
      -      "remove_booking"
      -    ],
      -    "type": "string"
      -  }
      -}
    • removedInput schema / properties / ops / items / required
      Removed value: -[
      -  "op"
      -]
    • removedInput schema / properties / ops / items / type
      Removed value: -"object"
    • addedInput schema / properties / verbose
      Added value: +{
      +  "description": "Return the whole plan. By default the reply shows only the days and bookings the edit touched.",
      +  "type": "boolean"
      +}
  7. Added

TDQS

A4.5/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Adds substantial context beyond the already-informative annotations: all-or-nothing atomicity, ordered ops application, optimistic concurrency via base_seq with refusal rather than overwrite on conflict, side effects of set_start_date and close_day on later days and bookings, and the sign-in requirement. The destructiveHint annotation is reinforced and given concrete scope, not merely repeated.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the core mechanism, but the entire description is a single run-on paragraph chained with semicolons, mixing atomicity, concurrency, place-authoring conventions, and confirmation policy. The content is largely justified by tool complexity, but it would be far more usable broken into short labeled clauses.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a complex destructive mutation tool with no output schema, the description covers concurrency safety, ordering, side effects of temporal ops, place authoring conventions, and confirmation policy. An agent has everything needed to call this correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 50%, but the nested ops schema is extremely detailed and the description adds cross-parameter meaning: base_seq's conflict behavior, ops ordering, and conventions for meridian_url, visitNote, lat/lng, and time ordering. It doesn't enumerate every op's semantics (set_day, move_stop, add_booking details are left to the schema), which keeps it below 5.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Opens with a specific verb and resource ("Change a plan") and immediately defines the mechanism: a list of ops applied in order, all or nothing. This distinguishes it clearly from create_plan, delete_plan, get_plan, and suggest_edit as a direct, atomic mutation tool.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives strong prerequisites and workflow: base_seq must come from get_plan, stop/booking ids come from get_plan, places should be sourced from get_destination/get_place, and on conflict the agent should re-read and redo. The removal-confirmation requirement ("Ask the traveller before removing anything") is explicit. It does not explicitly contrast itself with suggest_edit, leaving that inference to the agent.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Try in Browser

Glama MCP Gateway

Add one secure layer between your agents and this server.

Resources