# Edit a quote's lines and packages

> The edit_quote_lines MCP tool: edit a quote's lines and packages.

`edit_quote_lines` · writes

[REST: `POST /v1/quotes/{quoteId}/lines`](https://api.bymundi.com/docs/reference/quotes.editLines.md)

## What the model reads

Edits a quote's lines and packages in one call (up to 50 ops, all or nothing): add_line (kind flight, hotel or other; put it in a package with packageId, or make it an upgrade of a base line with replacesItemId + packageId), update_line (only the fields you send change), remove_line (its upgrades go with it), add_package (up to 3, package quotes only), rename_package, remove_package (only when empty). Give an add a `clientId` to refer to it in later ops of the same call. Lines linked to the trip's design refuse edits to what the design owns (a linked transport's route, dates and times; a linked hotel's city): change the design with update_trip, then sync_quote_with_design. Prices are decimal strings in euros; hotel room prices are per stay; only an 'other' line may be negative (a discount). Read get_quote first for line ids.

Permissions: quotes:write.
Set `dryRun: true` to preview the effect without writing anything.
Undo: the result names a change id; undo_change reverts it.

## Input

| Field | Type | Required | Description |
|---|---|---|---|
| `quoteId` | uuid | yes |  |
| `ops` | object \| object \| object \| object \| object \| object[] | yes | max 50 items |
| `expectedUpdatedAt` | datetime |  | The quote's updatedAt as you read it; the write is refused (409) if the quote changed since. |
| `dryRun` | boolean |  | Preview only: plan the change and return its effect without writing. |

## Input schema (JSON)

```json
{
  "type": "object",
  "properties": {
    "quoteId": {
      "type": "string",
      "format": "uuid"
    },
    "ops": {
      "type": "array",
      "items": {
        "anyOf": [
          {
            "type": "object",
            "properties": {
              "op": {
                "type": "string",
                "const": "add_line"
              },
              "clientId": {
                "type": "string",
                "pattern": "^[A-Za-z0-9_-]{1,40}$",
                "description": "Your own name for what this op creates, so later ops in the same batch can refer to it."
              },
              "line": {
                "anyOf": [
                  {
                    "type": "object",
                    "properties": {
                      "kind": {
                        "type": "string",
                        "const": "flight"
                      },
                      "name": {
                        "type": "string",
                        "maxLength": 300
                      },
                      "bookingRef": {
                        "type": "string",
                        "maxLength": 100,
                        "description": "The booking reference (localizador)."
                      },
                      "comments": {
                        "type": "string",
                        "maxLength": 4000
                      },
                      "marginable": {
                        "type": "boolean",
                        "description": "Whether the quote's margin applies to this line (default true)."
                      },
                      "catalogRef": {
                        "anyOf": [
                          {
                            "type": "object",
                            "properties": {
                              "kind": {
                                "type": "string",
                                "minLength": 1,
                                "maxLength": 40
                              },
                              "id": {
                                "type": "string",
                                "minLength": 1,
                                "maxLength": 100
                              }
                            },
                            "required": [
                              "kind",
                              "id"
                            ],
                            "additionalProperties": false
                          },
                          {
                            "type": "null"
                          }
                        ]
                      },
                      "packageId": {
                        "anyOf": [
                          {
                            "type": "string",
                            "minLength": 1,
                            "maxLength": 64,
                            "description": "A line or package id from get_quote, or the clientId an earlier op in this batch gave it."
                          },
                          {
                            "type": "null"
                          }
                        ],
                        "description": "Put the line in an upgrade package (package quotes only)."
                      },
                      "replacesItemId": {
                        "anyOf": [
                          {
                            "type": "string",
                            "minLength": 1,
                            "maxLength": 64,
                            "description": "A line or package id from get_quote, or the clientId an earlier op in this batch gave it."
                          },
                          {
                            "type": "null"
                          }
                        ],
                        "description": "Make the line an upgrade of this base line, inside packageId. Same kind as the base."
                      },
                      "role": {
                        "type": "string",
                        "enum": [
                          "ida",
                          "interno",
                          "vuelta"
                        ]
                      },
                      "mode": {
                        "type": "string",
                        "enum": [
                          "avion",
                          "tren",
                          "ferry",
                          "autobus",
                          "coche"
                        ]
                      },
                      "from": {
                        "type": "string",
                        "maxLength": 200
                      },
                      "to": {
                        "type": "string",
                        "maxLength": 200
                      },
                      "date": {
                        "anyOf": [
                          {
                            "type": "string",
                            "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
                          },
                          {
                            "type": "null"
                          }
                        ]
                      },
                      "departTime": {
                        "type": "string",
                        "pattern": "^(?:[01]\\d|2[0-3]):[0-5]\\d$|^$"
                      },
                      "arriveTime": {
                        "type": "string",
                        "pattern": "^(?:[01]\\d|2[0-3]):[0-5]\\d$|^$"
                      },
                      "arriveDayOffset": {
                        "type": "integer",
                        "minimum": 0,
                        "maximum": 14
                      },
                      "flight": {
                        "type": "object",
                        "properties": {
                          "flightNo": {
                            "type": "string",
                            "maxLength": 12
                          },
                          "airline": {
                            "type": "string",
                            "maxLength": 8
                          },
                          "fromAirport": {
                            "type": "string",
                            "maxLength": 8
                          },
                          "toAirport": {
                            "type": "string",
                            "maxLength": 8
                          }
                        },
                        "additionalProperties": false
                      },
                      "price": {
                        "type": "string",
                        "pattern": "^-?\\d{1,9}(\\.\\d{1,2})?$"
                      },
                      "perPax": {
                        "type": "boolean"
                      },
                      "pairedWithId": {
                        "anyOf": [
                          {
                            "type": "string",
                            "minLength": 1,
                            "maxLength": 64,
                            "description": "A line or package id from get_quote, or the clientId an earlier op in this batch gave it."
                          },
                          {
                            "type": "null"
                          }
                        ],
                        "description": "On a return: the outbound flight line that carries the round-trip price."
                      }
                    },
                    "required": [
                      "kind"
                    ],
                    "additionalProperties": false
                  },
                  {
                    "type": "object",
                    "properties": {
                      "kind": {
                        "type": "string",
                        "const": "hotel"
                      },
                      "name": {
                        "type": "string",
                        "maxLength": 300
                      },
                      "bookingRef": {
                        "type": "string",
                        "maxLength": 100,
                        "description": "The booking reference (localizador)."
                      },
                      "comments": {
                        "type": "string",
                        "maxLength": 4000
                      },
                      "marginable": {
                        "type": "boolean",
                        "description": "Whether the quote's margin applies to this line (default true)."
                      },
                      "catalogRef": {
                        "anyOf": [
                          {
                            "type": "object",
                            "properties": {
                              "kind": {
                                "type": "string",
                                "minLength": 1,
                                "maxLength": 40
                              },
                              "id": {
                                "type": "string",
                                "minLength": 1,
                                "maxLength": 100
                              }
                            },
                            "required": [
                              "kind",
                              "id"
                            ],
                            "additionalProperties": false
                          },
                          {
                            "type": "null"
                          }
                        ]
                      },
                      "packageId": {
                        "anyOf": [
                          {
                            "type": "string",
                            "minLength": 1,
                            "maxLength": 64,
                            "description": "A line or package id from get_quote, or the clientId an earlier op in this batch gave it."
                          },
                          {
                            "type": "null"
                          }
                        ],
                        "description": "Put the line in an upgrade package (package quotes only)."
                      },
                      "replacesItemId": {
                        "anyOf": [
                          {
                            "type": "string",
                            "minLength": 1,
                            "maxLength": 64,
                            "description": "A line or package id from get_quote, or the clientId an earlier op in this batch gave it."
                          },
                          {
                            "type": "null"
                          }
                        ],
                        "description": "Make the line an upgrade of this base line, inside packageId. Same kind as the base."
                      },
                      "stopId": {
                        "type": "string",
                        "minLength": 1,
                        "maxLength": 64,
                        "description": "A stop of the trip's design: the hotel takes the stop's city."
                      },
                      "city": {
                        "type": "string",
                        "maxLength": 200
                      },
                      "nights": {
                        "type": "integer",
                        "minimum": 0,
                        "maximum": 365
                      },
                      "board": {
                        "type": "string",
                        "maxLength": 200
                      },
                      "rooms": {
                        "type": "array",
                        "items": {
                          "type": "object",
                          "properties": {
                            "type": {
                              "type": "string",
                              "maxLength": 200
                            },
                            "qty": {
                              "type": "integer",
                              "minimum": 1,
                              "maximum": 50
                            },
                            "price": {
                              "type": "string",
                              "pattern": "^-?\\d{1,9}(\\.\\d{1,2})?$",
                              "description": "Per STAY, not per night."
                            }
                          },
                          "required": [
                            "type",
                            "qty",
                            "price"
                          ],
                          "additionalProperties": false
                        },
                        "minItems": 1,
                        "maxItems": 20
                      },
                      "optionKind": {
                        "type": "string",
                        "enum": [
                          "line",
                          "hotel"
                        ]
                      },
                      "place": {
                        "type": "object",
                        "properties": {
                          "placeId": {
                            "type": "string",
                            "maxLength": 300
                          },
                          "lat": {
                            "anyOf": [
                              {
                                "type": "number",
                                "minimum": -90,
                                "maximum": 90
                              },
                              {
                                "type": "null"
                              }
                            ]
                          },
                          "lng": {
                            "anyOf": [
                              {
                                "type": "number",
                                "minimum": -180,
                                "maximum": 180
                              },
                              {
                                "type": "null"
                              }
                            ]
                          },
                          "formattedAddress": {
                            "type": "string",
                            "maxLength": 500
                          }
                        },
                        "required": [
                          "placeId",
                          "lat",
                          "lng",
                          "formattedAddress"
                        ],
                        "additionalProperties": false
                      }
                    },
                    "required": [
                      "kind"
                    ],
                    "additionalProperties": false
                  },
                  {
                    "type": "object",
                    "properties": {
                      "kind": {
                        "type": "string",
                        "const": "other"
                      },
                      "name": {
                        "type": "string",
                        "maxLength": 300
                      },
                      "bookingRef": {
                        "type": "string",
                        "maxLength": 100,
                        "description": "The booking reference (localizador)."
                      },
                      "comments": {
                        "type": "string",
                        "maxLength": 4000
                      },
                      "marginable": {
                        "type": "boolean",
                        "description": "Whether the quote's margin applies to this line (default true)."
                      },
                      "catalogRef": {
                        "anyOf": [
                          {
                            "type": "object",
                            "properties": {
                              "kind": {
                                "type": "string",
                                "minLength": 1,
                                "maxLength": 40
                              },
                              "id": {
                                "type": "string",
                                "minLength": 1,
                                "maxLength": 100
                              }
                            },
                            "required": [
                              "kind",
                              "id"
                            ],
                            "additionalProperties": false
                          },
                          {
                            "type": "null"
                          }
                        ]
                      },
                      "packageId": {
                        "anyOf": [
                          {
                            "type": "string",
                            "minLength": 1,
                            "maxLength": 64,
                            "description": "A line or package id from get_quote, or the clientId an earlier op in this batch gave it."
                          },
                          {
                            "type": "null"
                          }
                        ],
                        "description": "Put the line in an upgrade package (package quotes only)."
                      },
                      "replacesItemId": {
                        "anyOf": [
                          {
                            "type": "string",
                            "minLength": 1,
                            "maxLength": 64,
                            "description": "A line or package id from get_quote, or the clientId an earlier op in this batch gave it."
                          },
                          {
                            "type": "null"
                          }
                        ],
                        "description": "Make the line an upgrade of this base line, inside packageId. Same kind as the base."
                      },
                      "tag": {
                        "anyOf": [
                          {
                            "type": "string",
                            "enum": [
                              "actividad",
                              "traslado",
                              "seguro"
                            ]
                          },
                          {
                            "type": "null"
                          }
                        ]
                      },
                      "qty": {
                        "type": "number",
                        "minimum": 0,
                        "maximum": 10000
                      },
                      "price": {
                        "type": "string",
                        "pattern": "^-?\\d{1,9}(\\.\\d{1,2})?$",
                        "description": "Unit price; negative for a discount."
                      },
                      "perPax": {
                        "type": "boolean"
                      },
                      "range": {
                        "anyOf": [
                          {
                            "type": "object",
                            "properties": {
                              "start": {
                                "type": "object",
                                "properties": {
                                  "offset": {
                                    "type": "integer",
                                    "minimum": 0,
                                    "maximum": 365
                                  },
                                  "time": {
                                    "type": "string",
                                    "pattern": "^(?:[01]\\d|2[0-3]):[0-5]\\d$|^$"
                                  }
                                },
                                "required": [
                                  "offset",
                                  "time"
                                ],
                                "additionalProperties": false
                              },
                              "end": {
                                "type": "object",
                                "properties": {
                                  "offset": {
                                    "type": "integer",
                                    "minimum": 0,
                                    "maximum": 365
                                  },
                                  "time": {
                                    "type": "string",
                                    "pattern": "^(?:[01]\\d|2[0-3]):[0-5]\\d$|^$"
                                  }
                                },
                                "required": [
                                  "offset",
                                  "time"
                                ],
                                "additionalProperties": false
                              }
                            },
                            "required": [
                              "start",
                              "end"
                            ],
                            "additionalProperties": false
                          },
                          {
                            "type": "null"
                          }
                        ]
                      },
                      "place": {
                        "type": "object",
                        "properties": {
                          "placeId": {
                            "type": "string",
                            "maxLength": 300
                          },
                          "lat": {
                            "anyOf": [
                              {
                                "type": "number",
                                "minimum": -90,
                                "maximum": 90
                              },
                              {
                                "type": "null"
                              }
                            ]
                          },
                          "lng": {
                            "anyOf": [
                              {
                                "type": "number",
                                "minimum": -180,
                                "maximum": 180
                              },
                              {
                                "type": "null"
                              }
                            ]
                          },
                          "formattedAddress": {
                            "type": "string",
                            "maxLength": 500
                          }
                        },
                        "required": [
                          "placeId",
                          "lat",
                          "lng",
                          "formattedAddress"
                        ],
                        "additionalProperties": false
                      }
                    },
                    "required": [
                      "kind"
                    ],
                    "additionalProperties": false
                  }
                ]
              }
            },
            "required": [
              "op",
              "line"
            ],
            "additionalProperties": false
          },
          {
            "type": "object",
            "properties": {
              "op": {
                "type": "string",
                "const": "update_line"
              },
              "id": {
                "type": "string",
                "minLength": 1,
                "maxLength": 64,
                "description": "A line or package id from get_quote, or the clientId an earlier op in this batch gave it."
              },
              "set": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "maxLength": 300
                  },
                  "bookingRef": {
                    "type": "string",
                    "maxLength": 100,
                    "description": "The booking reference (localizador)."
                  },
                  "comments": {
                    "type": "string",
                    "maxLength": 4000
                  },
                  "marginable": {
                    "type": "boolean",
                    "description": "Whether the quote's margin applies to this line (default true)."
                  },
                  "catalogRef": {
                    "anyOf": [
                      {
                        "type": "object",
                        "properties": {
                          "kind": {
                            "type": "string",
                            "minLength": 1,
                            "maxLength": 40
                          },
                          "id": {
                            "type": "string",
                            "minLength": 1,
                            "maxLength": 100
                          }
                        },
                        "required": [
                          "kind",
                          "id"
                        ],
                        "additionalProperties": false
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "role": {
                    "type": "string",
                    "enum": [
                      "ida",
                      "interno",
                      "vuelta"
                    ]
                  },
                  "mode": {
                    "type": "string",
                    "enum": [
                      "avion",
                      "tren",
                      "ferry",
                      "autobus",
                      "coche"
                    ]
                  },
                  "from": {
                    "type": "string",
                    "maxLength": 200
                  },
                  "to": {
                    "type": "string",
                    "maxLength": 200
                  },
                  "date": {
                    "anyOf": [
                      {
                        "type": "string",
                        "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "departTime": {
                    "type": "string",
                    "pattern": "^(?:[01]\\d|2[0-3]):[0-5]\\d$|^$"
                  },
                  "arriveTime": {
                    "type": "string",
                    "pattern": "^(?:[01]\\d|2[0-3]):[0-5]\\d$|^$"
                  },
                  "arriveDayOffset": {
                    "type": "integer",
                    "minimum": 0,
                    "maximum": 14
                  },
                  "flight": {
                    "type": "object",
                    "properties": {
                      "flightNo": {
                        "type": "string",
                        "maxLength": 12
                      },
                      "airline": {
                        "type": "string",
                        "maxLength": 8
                      },
                      "fromAirport": {
                        "type": "string",
                        "maxLength": 8
                      },
                      "toAirport": {
                        "type": "string",
                        "maxLength": 8
                      }
                    },
                    "additionalProperties": false
                  },
                  "price": {
                    "type": "string",
                    "pattern": "^-?\\d{1,9}(\\.\\d{1,2})?$",
                    "description": "Unit price; negative for a discount."
                  },
                  "perPax": {
                    "type": "boolean"
                  },
                  "pairedWithId": {
                    "anyOf": [
                      {
                        "type": "string",
                        "minLength": 1,
                        "maxLength": 64,
                        "description": "A line or package id from get_quote, or the clientId an earlier op in this batch gave it."
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "description": "On a return: the outbound flight line that carries the round-trip price."
                  },
                  "city": {
                    "type": "string",
                    "maxLength": 200
                  },
                  "nights": {
                    "type": "integer",
                    "minimum": 0,
                    "maximum": 365
                  },
                  "board": {
                    "type": "string",
                    "maxLength": 200
                  },
                  "rooms": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "type": {
                          "type": "string",
                          "maxLength": 200
                        },
                        "qty": {
                          "type": "integer",
                          "minimum": 1,
                          "maximum": 50
                        },
                        "price": {
                          "type": "string",
                          "pattern": "^-?\\d{1,9}(\\.\\d{1,2})?$",
                          "description": "Per STAY, not per night."
                        }
                      },
                      "required": [
                        "type",
                        "qty",
                        "price"
                      ],
                      "additionalProperties": false
                    },
                    "minItems": 1,
                    "maxItems": 20
                  },
                  "optionKind": {
                    "type": "string",
                    "enum": [
                      "line",
                      "hotel"
                    ]
                  },
                  "place": {
                    "type": "object",
                    "properties": {
                      "placeId": {
                        "type": "string",
                        "maxLength": 300
                      },
                      "lat": {
                        "anyOf": [
                          {
                            "type": "number",
                            "minimum": -90,
                            "maximum": 90
                          },
                          {
                            "type": "null"
                          }
                        ]
                      },
                      "lng": {
                        "anyOf": [
                          {
                            "type": "number",
                            "minimum": -180,
                            "maximum": 180
                          },
                          {
                            "type": "null"
                          }
                        ]
                      },
                      "formattedAddress": {
                        "type": "string",
                        "maxLength": 500
                      }
                    },
                    "required": [
                      "placeId",
                      "lat",
                      "lng",
                      "formattedAddress"
                    ],
                    "additionalProperties": false
                  },
                  "tag": {
                    "anyOf": [
                      {
                        "type": "string",
                        "enum": [
                          "actividad",
                          "traslado",
                          "seguro"
                        ]
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "qty": {
                    "type": "number",
                    "minimum": 0,
                    "maximum": 10000
                  },
                  "range": {
                    "anyOf": [
                      {
                        "type": "object",
                        "properties": {
                          "start": {
                            "type": "object",
                            "properties": {
                              "offset": {
                                "type": "integer",
                                "minimum": 0,
                                "maximum": 365
                              },
                              "time": {
                                "type": "string",
                                "pattern": "^(?:[01]\\d|2[0-3]):[0-5]\\d$|^$"
                              }
                            },
                            "required": [
                              "offset",
                              "time"
                            ],
                            "additionalProperties": false
                          },
                          "end": {
                            "type": "object",
                            "properties": {
                              "offset": {
                                "type": "integer",
                                "minimum": 0,
                                "maximum": 365
                              },
                              "time": {
                                "type": "string",
                                "pattern": "^(?:[01]\\d|2[0-3]):[0-5]\\d$|^$"
                              }
                            },
                            "required": [
                              "offset",
                              "time"
                            ],
                            "additionalProperties": false
                          }
                        },
                        "required": [
                          "start",
                          "end"
                        ],
                        "additionalProperties": false
                      },
                      {
                        "type": "null"
                      }
                    ]
                  }
                },
                "additionalProperties": false
              }
            },
            "required": [
              "op",
              "id",
              "set"
            ],
            "additionalProperties": false
          },
          {
            "type": "object",
            "properties": {
              "op": {
                "type": "string",
                "const": "remove_line"
              },
              "id": {
                "type": "string",
                "minLength": 1,
                "maxLength": 64,
                "description": "A line or package id from get_quote, or the clientId an earlier op in this batch gave it."
              }
            },
            "required": [
              "op",
              "id"
            ],
            "additionalProperties": false
          },
          {
            "type": "object",
            "properties": {
              "op": {
                "type": "string",
                "const": "add_package"
              },
              "clientId": {
                "type": "string",
                "pattern": "^[A-Za-z0-9_-]{1,40}$",
                "description": "Your own name for what this op creates, so later ops in the same batch can refer to it."
              },
              "name": {
                "type": "string",
                "minLength": 1,
                "maxLength": 60
              }
            },
            "required": [
              "op"
            ],
            "additionalProperties": false
          },
          {
            "type": "object",
            "properties": {
              "op": {
                "type": "string",
                "const": "rename_package"
              },
              "id": {
                "type": "string",
                "minLength": 1,
                "maxLength": 64,
                "description": "A line or package id from get_quote, or the clientId an earlier op in this batch gave it."
              },
              "name": {
                "type": "string",
                "minLength": 1,
                "maxLength": 60
              }
            },
            "required": [
              "op",
              "id",
              "name"
            ],
            "additionalProperties": false
          },
          {
            "type": "object",
            "properties": {
              "op": {
                "type": "string",
                "const": "remove_package"
              },
              "id": {
                "type": "string",
                "minLength": 1,
                "maxLength": 64,
                "description": "A line or package id from get_quote, or the clientId an earlier op in this batch gave it."
              }
            },
            "required": [
              "op",
              "id"
            ],
            "additionalProperties": false
          }
        ]
      },
      "minItems": 1,
      "maxItems": 50
    },
    "expectedUpdatedAt": {
      "type": "string",
      "format": "date-time",
      "description": "The quote's updatedAt as you read it; the write is refused (409) if the quote changed since."
    },
    "dryRun": {
      "type": "boolean",
      "description": "Preview only: plan the change and return its effect without writing."
    }
  },
  "required": [
    "quoteId",
    "ops"
  ],
  "additionalProperties": false
}
```
