bymundi API

Update a route

PATCH/v1/catalog/routes/{routeId}

Edits a route, as its editor's Save. A route is a day's walk through catalog places: stops in order, each a catalog place (punto) or activity (actividad) by placeId, with its own visit minutes (ownMinutes, null = the place's) and the LEG that arrives at it from the previous stop (mode: walking | transit | driving | bicycling, minutes, prose). intro and closing are the texts before and after. rules are how the planner uses it (structured: true lets it propose the route as a whole day). Send only the top-level fields that change; stops REPLACES the whole list (a pair of consecutive places that stays keeps its measured leg unless you send one). The route's destinos and duration are re-derived. Pass the updatedAt you read as expectedUpdatedAt to refuse a stale write with a 409 (without it, the version this call reads is the one checked). Undo with POST /changes/{changeId}/revert.

Permissions: catalog:write · Kind: write · Cost: 1 unit · MCP tool update_route

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

Path parameters

Field Type Required Description
routeId uuid yes

Body

Field Type Required Description
title string max 200 chars
intro string | object[] The text before the first stop.
closing string | object[] The text after the last stop.
stops object[] The whole stop list, in order. Absent = unchanged. max 40 items
stops[].placeId uuid yes A catalog place (punto) or activity (actividad), by id.
stops[].ownMinutes integer | null This route's own visit minutes for the stop; null or absent = the place's own.
stops[].leg object How you get HERE from the previous stop (ignored on the first). Absent = keep the measured leg when the same pair was already on the route.
stops[].leg.mode "walking" | "transit" | "driving" | "bicycling" | null
stops[].leg.minutes integer | null Travel minutes from the previous stop.
stops[].leg.prose string | object[] How to get here from the previous stop.
rules object The route's planning rules; only the fields sent change. destinos is derived from the stops.
rules.structured boolean true: the planner may propose it as a whole day (needs at least two stops).
rules.base string max 200 chars
rules.tipo "dia_entero" | "medio_dia" | "excursion" | "tematica" | "con_experiencias" | "llegada" | null
rules.duracion "medio_dia" | "dia_entero" | "dia_entero_largo" | null
rules.ritmo "relajado" | "equilibrado" | "intenso" | null
rules.incompatibleDias "lunes" | "martes" | "miercoles" | "jueves" | "viernes" | "sabado" | "domingo"[] Weekdays it cannot run. max 7 items
rules.requiereReserva boolean
rules.notasUso string[] max 20 items
expectedUpdatedAt datetime

Response 200

Field Type Required Description
object "route" yes
id uuid yes
title string yes
externalId string yes
intro object[] yes
stops object[] yes
stops[].placeId string yes
stops[].name string yes The place's name — or the stop's stored title when its place no longer resolves.
stops[].placeMinutes integer | null yes The place's own visit minutes; null when the place is gone.
stops[].ownMinutes integer | null yes This route's override for the stop; null = the place's.
stops[].leg object | null yes How you get here from the previous stop; null on the first stop, or when nothing is known.
stops[].leg.mode "walking" | "transit" | "driving" | "bicycling" | null yes
stops[].leg.minutes integer | null yes
stops[].leg.prose object[] yes
stops[].leg.source string yes Provenance: source (authored), routes (measured by Google), manual (typed).
stops[].leg.stale boolean yes true: measured for a different previous stop — the minutes no longer describe this leg.
closing object[] yes
rules object yes
rules.structured boolean yes
rules.base string yes
rules.tipo "dia_entero" | "medio_dia" | "excursion" | "tematica" | "con_experiencias" | "llegada" | null yes
rules.duracion "medio_dia" | "dia_entero" | "dia_entero_largo" | null yes
rules.ritmo "relajado" | "equilibrado" | "intenso" | null yes
rules.incompatibleDias "lunes" | "martes" | "miercoles" | "jueves" | "viernes" | "sabado" | "domingo"[] yes
rules.requiereReserva boolean yes
rules.notasUso string[] yes
destinos object[] yes Every destino the stops sit in (derived when the route is saved).
destinos[].id uuid yes
destinos[].name string yes
durationMin integer | null yes The route's computed length in minutes; null while never computed.
updatedAt string yes

Errors

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