update_route

Edit a route.

PATCH/v1/routes/{routeId}
MCP tool update_routeScope: writeStableSince 2026-09-17
Markdown

Only sent fields change. Strings clear on empty string, numeric stats and objects clear on null, arrays are full replacements, track null removes the line.

curl -X PATCH "https://sceniq.earth/api/v1/routes/kx7f2h8j4k0k6z2x8c4v0b6n2m8q4w0e" \
  -H "Authorization: Bearer $SCENIQ_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "status": {
    "state": "reopening",
    "note": "The overlook spur and platform are closed for repairs. The trail to Fairy Falls stays open.",
    "since": "2026-09-28",
    "until": "2026-10-16",
    "sourceUrl": "https://www.nps.gov/yell/planyourvisit/conditions.htm",
    "checkedOn": "2026-09-29"
  },
  "reviewBy": "2026-10-17"
}'

Path parameters

  • routeIdstring · route idrequired

    Id of the route (from list_routes).

Body parameters

  • activitystringoptional

    hike, walk, bike, drive, ski or paddle. A route without one is a hike; empty string clears.

  • ascentMinnumber or nulloptional

    Minutes up, when the source gives up and down separately. null clears.

  • descentMnumber or nulloptional

    Descent in meters, 0 or more. Never derived from gainM: give it when the source does. null clears.

  • descentMinnumber or nulloptional

    Minutes down. null clears.

  • descriptionstringoptional

    The route in the creator's words, shown on the route card. Empty string clears.

  • distanceKmnumber or nulloptional

    Distance in kilometers, 0 or more. null clears.

  • durationBasisstring or nulloptional

    What durationMin counts: round_trip (the default), one_way or ascent. null clears.

    round_tripone_wayascent
  • durationMinnumber or nulloptional

    Duration in minutes, 0 or more; durationBasis says what it counts (round trip unless set). null clears.

  • effortLabelstringoptional

    Easy, Moderate, Hard (free text). Empty string clears.

  • equipmentarray of strings or nulloptional

    Gear, full replacement, at most 50 items; [] means explicitly no special gear (shown as None), null clears back to unknown.

  • extraPropsarray of ExtraPropoptional

    Free label and value rows shown on the card, full replacement ([] clears), at most 24: [{ label (at most 60 characters), value (at most 500) }]. A row with both sides empty is dropped, a half-empty one refused.

    Show 2 fieldsof ExtraProp
    • labelstringrequired

      The row's label, at most 60 characters.

    • valuestringrequired

      The row's value, at most 500 characters.

  • factsCheckedOnstringoptional

    The day the facts were last checked against their sources (YYYY-MM-DD). Empty string clears.

  • figureSourcesarray of FigureSourceoptional

    Where each number comes from, full replacement: [{ field: durationMin|distanceKm|gainM|descentM|sacGrade, kind: sourced|computed, url?, note? }].

    Show 4 fieldsof FigureSource
    • fieldstringrequired

      The number it backs: durationMin, distanceKm, gainM, descentM or sacGrade.

      durationMindistanceKmgainMdescentMsacGrade
    • kindstringrequired

      sourced (taken from a source) or computed (worked out, for example from the GPX track).

      sourcedcomputed
    • urlstringoptional

      The source page (http or https).

    • notestringoptional

      How the number was found or worked out, at most 300 characters.

  • gainMnumber or nulloptional

    Elevation gain in meters, 0 or more. null clears.

  • gradeScalestringoptional

    sac, via_ferrata, cai, yds, mtb, whitewater or other. A route without one uses sac; empty string clears.

  • namestringoptional

    Route name, e.g. Fairy Falls trail or Oeschinensee loop. Without one the apps show Hike from <start> (Drive from, Bike ride from ... by activity), or Route N when there is no start either. Empty string clears.

  • reviewBystringoptional

    The day the facts need a new check (YYYY-MM-DD), e.g. when a season, fare or timetable runs out. get_guide_readiness and get_publish_status warn once it has passed. Empty string clears.

  • reviewNotesstringoptional

    Notes for the creator's review (why a value was chosen, what could not be verified). Never shown to buyers; get_guide_readiness lists them. Empty string clears.

  • sacGradestringoptional

    The grade as written in gradeScale, e.g. T2 (SAC), EE (CAI), Class 3 (US), S2 (mountain bike). Empty string clears.

  • seasonRouteSeason or nulloptional

    When the route can be walked, null clears: { months? [1-12], closureNote? (stairs chained November to April), statusUrl? }. Buyers opening it out of season see the closure.

    Show 3 fieldsof RouteSeason
    • monthsarray of numbersoptional

      The months it can be walked (1 to 12). Absent means all year.

    • closureNotestringoptional

      What closes and when, at most 500 characters (stairs chained November to April).

    • statusUrlstringoptional

      The page with the current conditions (http or https), linked from the season notice.

  • segmentsarray of RouteSegmentoptional

    Sections with their own access (free to Scout Lookout, permit for the chains): [{ name, km?, accessNote? }].

    Show 3 fieldsof RouteSegment
    • namestringrequired

      The section's name, at most 120 characters. Required.

    • kmnumberoptional

      Its length in kilometers (0 to 1,000).

    • accessNotestringoptional

      What access it needs, at most 300 characters (permit by lottery).

  • shapestring or nulloptional

    loop, out_and_back or one_way. null clears.

    loopout_and_backone_way
  • sourceGradestringoptional

    The source's own grade (Easy on the park page) next to your effortLabel. Empty string clears.

  • sourcesarray of stringsoptional

    Where the facts come from, full replacement ([] clears), at most 25 entries: links to official trail pages or plain text (the creator's GPX). Buyers see them under Sources, links by their host.

  • stagesarray of RouteStageoptional

    Days or legs of a trek, full replacement: [{ name, km?, min?, gainM?, note? }].

    Show 5 fieldsof RouteStage
    • namestringrequired

      The stage's name, at most 120 characters (Day 1: Refugio Grey to Paine Grande). Required.

    • kmnumberoptional

      Distance in kilometers (0 to 1,000).

    • minnumberoptional

      Duration in minutes (0 to 10,000).

    • gainMnumberoptional

      Elevation gain in meters (0 to 10,000).

    • notestringoptional

      One line for the stage, at most 300 characters.

  • startstringoptional

    Trailhead or starting point in words. Empty string clears.

  • startMapsUrlstringoptional

    Map link to the trailhead: https on Google Maps, Apple Maps, Swisstopo, OpenStreetMap or SchweizMobil, or a geo: URI. Empty string clears.

  • statusStatusNotice or nulloptional

    Closure or works notice, null clears: { state: open|partly_closed|closed|reopening, note?, since?, until? (the day the state is expected to end; buyers stop seeing the notice after it), sourceUrl?, checkedOn? }. reopening with until means reopens on that day.

    Show 6 fieldsof StatusNotice
    • statestringrequired

      open, partly_closed, closed or reopening. reopening with until means it reopens on that day.

      openpartly_closedclosedreopening
    • notestringoptional

      What is closed or changed, in the creator's words, at most 500 characters.

    • sincestringoptional

      The day the state began (YYYY-MM-DD).

    • untilstringoptional

      The day the state is expected to end (YYYY-MM-DD). Must not be before since.

    • sourceUrlstringoptional

      The page that announced it (http or https).

    • checkedOnstringoptional

      The day the value was last checked against its source (YYYY-MM-DD).

  • trackRouteTrack or nulloptional

    The route line (see create_route), replaced whole; null removes it.

    Show 3 fieldsof RouteTrack
    • coordinatesarray of array of numbersrequired

      Positions as [lon, lat] or [lon, lat, ele] (ele in meters), 2 to 1,000. Stored rounded to 6 decimals and whole meters.

    • sourcestringoptional

      The file type the line came from: gpx or kml. Other values are dropped.

    • fileNamestringoptional

      The imported file's name, cut to 200 characters.

  • transitarray of TransitNoteoptional

    Transit notes shown under Transit on the route card, full replacement ([] clears), at most 20: [{ mode: train|bus|cable_car|car|boat|ferry|plane, note }]. Rows with an empty note are dropped.

    Show 2 fieldsof TransitNote
    • modestringrequired

      train, bus, cable_car, car, boat, ferry or plane (shown as Flight).

      trainbuscable_carcarboatferryplane
    • notestringrequired

      The note in words: the connection, where to change, the last departure.

  • variantsarray of RouteVariantoptional

    Alternatives, full replacement: [{ name, start?, extraKm?, extraMin?, purpose? }].

    Show 5 fieldsof RouteVariant
    • namestringrequired

      The variant's name, at most 80 characters. Required.

    • startstringoptional

      Where it starts when that differs, at most 200 characters.

    • extraKmnumberoptional

      Kilometers it adds, negative when shorter (-1,000 to 1,000).

    • extraMinnumberoptional

      Minutes it adds, negative when faster (-10,000 to 10,000).

    • purposestringoptional

      Why take it, at most 300 characters.

Returns

200 OK with this object.

  • okbooleanrequired

    Always true: the write went through.

    Always true

  • routeIdstring · route idrequired

    The route's id.

  • warningsarray of stringsoptional

    Notes about things the write accepted but you should look at (a plain http link). Present only when there are any.

Response 200
{
  "ok": true,
  "routeId": "kx7f2h8j4k0k6z2x8c4v0b6n2m8q4w0e"
}

Errors

Every error is { error: { code, message } }. Act on the code.

  • 400invalid_argumentA required field is missing, a field is unknown, or a value does not match its type (the Convex validator's path and value are in the message).
  • 400invalid_requestA writer refused a value: a map link on a host that is not allowed, a title that is too long, a date that does not exist, too many items in a list. The message is the writer's own sentence.
  • 401unauthenticatedThe request carries no key. Send it as Authorization: Bearer sk_sceniq_... (or X-Api-Key).
  • 401invalid_api_keyThe key is unknown, revoked or expired.
  • 403api_scope_requiredA read-only key called a write operation, or a key without the publish option called publish_changes.
  • 403forbiddenThe key belongs to a creator account that is no longer active.
  • 404not_foundThe id does not exist or belongs to another creator. The two answers are identical on purpose, so ids never reveal what exists.
  • 413payload_too_largeA JSON body over 2 MB, an image over 6 MB, a batch upload over 19 MB, or an MCP message over 2 MB.
  • 429rate_limitedOver a limit: requests per key per minute, per creator per hour, uploads per key per minute, or check_links per guide per hour.
  • 500internal_errorAn unexpected failure. The message is hidden on purpose.