bymundi API

Edit a quote's lines and packages

POST/v1/quotes/{quoteId}/lines

Applies up to 50 ops to a quote's lines and packages as ONE change: add_line (a flight/transport, hotel or other line; into a package with packageId, or as an upgrade replacing a base line with replacesItemId), update_line, remove_line (a base line's upgrades go with it), add_package (up to 3; package quotes only), rename_package, remove_package (only when no line uses it). A later op may refer to an earlier add by its clientId. Lines that follow the trip's design refuse edits to what the design owns (a linked transport's route, dates and times; a linked hotel's city): change the design, then POST /quotes/{quoteId}/sync-design. Money is a decimal string; only an 'other' line may be negative (a discount). If any op is refused, nothing is written. With ?dryRun=true, returns a quote_preview of the resulting lines and totals.

Permissions: quotes:write · Kind: write · Cost: 1 unit · Dry run: ?dryRun=true · MCP tool edit_quote_lines

Undoable: the response carries Bymundi-Change-Id; revert it with POST /v1/changes/{changeId}/revert.

Path parameters

Field Type Required Description
quoteId uuid yes

Body

Field Type Required Description
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.

Response 200

One of:

quote_edit

Field Type Required Description
object "quote_edit" yes
quote object yes
quote.object "quote" yes
quote.id uuid yes
quote.tripId uuid yes
quote.code string yes
quote.name string yes
quote.mode "package" | "per_item" yes
quote.status "draft" | "sent" | "accepted" | "rejected" | "expired" | "superseded" yes
quote.travelers integer yes
quote.marginPct number yes
quote.finalPriceOverride string | null yes
quote.validUntil string | null yes
quote.ctaUrl string | null yes
quote.templateId string | null yes
quote.packages object[] yes
quote.packages[].id string yes
quote.packages[].name string yes
quote.lines object | object | object[] yes
quote.totals object yes
quote.totals.currency "EUR" yes
quote.totals.net string yes
quote.totals.marginAmount string yes
quote.totals.total string yes
quote.totals.finalPrice string yes
quote.totals.perPax string yes
quote.totals.finalMargin string yes
quote.totals.packages object[] yes
quote.textOverrides object yes
quote.imageOverrides object yes
quote.sentAt string | null yes
quote.modifiedSinceSent boolean yes
quote.acceptedAt string | null yes
quote.acceptedVia "prospect_link" | "agent" | null yes
quote.acceptedPackageId string | null yes
quote.acceptedLineIds string[] yes
quote.acceptance object | null yes What the customer typed when accepting on the quote page — personal data: present only for a key holding travelers:read, only on quote reads (a write's response carries null; read the quote), and every such read is audited.
quote.acceptance.name string | null yes
quote.acceptance.email string | null yes
quote.acceptance.phone string | null yes
quote.acceptance.message string | null yes
quote.engagement object yes
quote.engagement.views integer yes
quote.engagement.uniqueSessions integer yes
quote.engagement.activeSeconds integer yes
quote.engagement.ctaClicks integer yes
quote.engagement.maxScrollPct number yes
quote.engagement.sectionsSeen integer yes
quote.engagement.interactions integer yes
quote.engagement.lastSeenAt string | null yes
quote.engagement.lastCtaAt string | null yes
quote.metadata object yes
quote.appUrl string | null yes
quote.publicUrl string | null yes
quote.createdAt string yes
quote.updatedAt string yes
created object[] yes
created[].clientId string | null yes
created[].id string yes
created[].kind "line" | "package" yes
removed string[] yes

quote_preview

Field Type Required Description
object "quote_preview" yes
quoteId uuid | null yes
changes object[] yes
changes[].field string yes
changes[].from any
changes[].to any
sync object | null yes
sync.added integer yes
sync.updated integer yes
sync.removed integer yes
packages object[] yes
packages[].id string yes
packages[].name string yes
lines object | object | object[] yes
totals object yes
totals.currency "EUR" yes
totals.net string yes
totals.marginAmount string yes
totals.total string yes
totals.finalPrice string yes
totals.perPax string yes
totals.finalMargin string yes
totals.packages object[] yes
totals.packages[].id string yes
totals.packages[].name string yes
totals.packages[].deltaNet string yes
totals.packages[].deltaPvp string yes
totals.packages[].lineIds string[] yes

Errors

Errors are problem details. Besides the refusals described above, any call like this one can return: