create_route

Add a route (how to get there).

POST/v1/guides/{productId}/routes
MCP tool create_routeScope: writeStableSince 2026-09-17
Markdown

Planning facts the creator vouches for: route type, grade and its scale, effort, duration, gain, distance, trailhead, transit per mode, equipment ([] means explicitly none), sources (where the numbers come from) and the line from the creator's GPX or KML. Link spots with set_route_spots afterwards.

curl -X POST "https://sceniq.earth/api/v1/guides/j5738kd1q9x2m7v4c6b8n0p3r5t1w9y2/routes" \
  -H "Authorization: Bearer $SCENIQ_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "name": "Fairy Falls trail to the Grand Prismatic overlook",
  "activity": "hike",
  "sacGrade": "Class 1",
  "gradeScale": "yds",
  "sourceGrade": "Easy",
  "effortLabel": "Easy",
  "durationMin": 45,
  "durationBasis": "round_trip",
  "distanceKm": 2,
  "gainM": 35,
  "descentM": 35,
  "shape": "out_and_back",
  "start": "Fairy Falls trailhead on the Grand Loop Road, 1.6 km south of Midway Geyser Basin",
  "startMapsUrl": "https://maps.apple.com/?ll=44.5156,-110.8326&q=Fairy%20Falls%20Trailhead",
  "description": "A flat kilometer on the old Fountain Freight Road, then a short climb to a platform above Grand Prismatic Spring. Go mid morning on a warm day, once the steam has lifted.",
  "transit": [
    {
      "mode": "car",
      "note": "Park at the Fairy Falls trailhead lot, which fills by 09:30 in July and August. No public transport runs in the park."
    },
    {
      "mode": "plane",
      "note": "Yellowstone Airport (WYS) in West Yellowstone, 45 km by road, has flights from June to September."
    }
  ],
  "equipment": [
    "Bear spray",
    "A warm layer for the morning"
  ],
  "sources": [
    "https://www.nps.gov/places/000/grand-prismatic-spring.htm",
    "GPX recorded by Mara Lindgren on 2026-09-14"
  ],
  "extraProps": [
    {
      "label": "Dogs",
      "value": "Not allowed on park trails"
    }
  ],
  "season": {
    "months": [
      4,
      5,
      6,
      7,
      8,
      9,
      10
    ],
    "closureNote": "Park roads close to cars from early November to mid April; the trailhead is then reached by snowcoach only.",
    "statusUrl": "https://www.nps.gov/yell/planyourvisit/conditions.htm"
  },
  "variants": [
    {
      "name": "On to Fairy Falls",
      "extraKm": 6.8,
      "extraMin": 120,
      "purpose": "A 60 m waterfall 3.4 km further along the same trail, quiet before 09:00."
    }
  ],
  "segments": [
    {
      "name": "Fountain Freight Road",
      "km": 1.1,
      "accessNote": "Flat gravel road over the Firehole River, closed to cars. Bikes allowed."
    },
    {
      "name": "Overlook spur",
      "km": 0.3,
      "accessNote": "Hikers only. The one climb of the route."
    }
  ],
  "figureSources": [
    {
      "field": "distanceKm",
      "kind": "sourced",
      "url": "https://www.nps.gov/places/000/grand-prismatic-spring.htm"
    },
    {
      "field": "gainM",
      "kind": "computed",
      "note": "From the GPX, smoothed"
    },
    {
      "field": "durationMin",
      "kind": "computed",
      "note": "Walking time without the stop on the platform"
    }
  ],
  "track": {
    "coordinates": [
      [
        -110.8326,
        44.5156,
        2181
      ],
      [
        -110.8349,
        44.517,
        2182
      ],
      [
        -110.8372,
        44.5183,
        2183
      ],
      [
        -110.8391,
        44.519,
        2186
      ],
      [
        -110.8402,
        44.5196,
        2201
      ],
      [
        -110.8406,
        44.5199,
        2214
      ]
    ],
    "source": "gpx",
    "fileName": "fairy-falls-overlook-2026-09-14.gpx"
  },
  "reviewNotes": "The NPS page gives no elevation gain; the figure comes from the GPX.",
  "factsCheckedOn": "2026-09-20",
  "reviewBy": "2027-04-01"
}'

Path parameters

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.

  • descentMnumberoptional

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

  • descentMinnumber or nulloptional

    Minutes down. null clears.

  • descriptionstringoptional

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

  • distanceKmnumberoptional

    Distance in kilometers, 0 or more.

  • durationBasisstring or nulloptional

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

    round_tripone_wayascent
  • durationMinnumberoptional

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

  • effortLabelstringoptional

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

  • equipmentarray of stringsoptional

    Gear, at most 50 items; [] means explicitly no special gear (shown as None), absent means 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.

  • gainMnumberoptional

    Elevation gain in meters, 0 or more.

  • 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).

  • trackRouteTrackoptional

    The route line from the creator's GPX or KML: { coordinates: [[lon, lat] or [lon, lat, ele]], source: gpx|kml, fileName }. 2 to 1,000 points; simplify long recordings first.

    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

201 Created with RouteWrite: A route after create_route, with the write's warnings.

  • routeIdstring · route idrequired

    The route's id.

  • namestring or nullrequired

    The route's name.

  • activitystring or nullrequired

    hike, walk, bike, drive, ski or paddle; null means hike.

  • sacGradestring or nullrequired

    The grade as written in gradeScale.

  • gradeScalestring or nullrequired

    sac, via_ferrata, cai, yds, mtb, whitewater or other; null means sac.

  • effortLabelstring or nullrequired

    Easy, Moderate, Hard (free text).

  • durationMinnumber or nullrequired

    Duration in minutes (see durationBasis).

  • gainMnumber or nullrequired

    Elevation gain in meters.

  • descentMnumber or nullrequired

    Descent in meters.

  • distanceKmnumber or nullrequired

    Distance in kilometers.

  • startstring or nullrequired

    The trailhead in words.

  • startMapsUrlstring or nullrequired

    Map link to the trailhead.

  • transitarray of TransitNoterequired

    Transit notes per mode.

    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.

  • descriptionstring or nullrequired

    The route in the creator's words.

  • equipmentarray of strings or nullrequired

    Gear; [] means explicitly none, null means unknown.

  • sourcesarray of stringsrequired

    Where the facts come from.

  • extraPropsarray of ExtraProprequired

    Free label and value rows.

    Show 2 fieldsof ExtraProp
    • labelstringrequired

      The row's label, at most 60 characters.

    • valuestringrequired

      The row's value, at most 500 characters.

  • trackRouteTrack or nullrequired

    The route line.

    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.

  • statusStatusNotice or nullrequired

    A closure notice.

    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).

  • seasonRouteSeason or nullrequired

    When the route can be walked.

    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.

  • variantsarray of RouteVariantrequired

    Alternatives.

    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.

  • stagesarray of RouteStagerequired

    Days or legs of a trek.

    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.

  • segmentsarray of RouteSegmentrequired

    Sections with their own access.

    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 nullrequired

    loop, out_and_back or one_way.

    loopout_and_backone_way
  • durationBasisstring or nullrequired

    What durationMin counts: round_trip, one_way or ascent.

    round_tripone_wayascent
  • ascentMinnumber or nullrequired

    Minutes up.

  • descentMinnumber or nullrequired

    Minutes down.

  • sourceGradestring or nullrequired

    The source's own grade.

  • figureSourcesarray of FigureSourcerequired

    Where each number comes from.

    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.

  • reviewNotesstring or nullrequired

    Notes for the creator's review, never shown to buyers.

  • factsCheckedOnstring or nullrequired

    The day the facts were last checked (YYYY-MM-DD).

  • reviewBystring or nullrequired

    The day the facts need a new check (YYYY-MM-DD).

  • createdAtnumberrequired

    When the row was created (Unix time in milliseconds).

  • updatedAtnumberrequired

    When the row last changed (Unix time in milliseconds).

  • spotsarray of objectsrequired

    The spots the route passes, in order.

    Show 4 fields
    • spotKeystringrequired

      The spot's key.

    • ordernumberrequired

      Position on the route.

    • quickestbooleanrequired

      true when this is the fastest approach to the spot.

    • rolestringrequired

      required: the way in. optional: a walk from the spot that never sets its Accessibility.

      requiredoptional
  • facilitiesarray of objectsrequired

    The places the route uses, in order.

    Show 2 fields
    • facilityIdstring · place idrequired

      The place's id.

    • ordernumberrequired

      Position on the route.

  • 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 201
{
  "routeId": "kx7f2h8j4k0k6z2x8c4v0b6n2m8q4w0e",
  "name": "Fairy Falls trail to the Grand Prismatic overlook",
  "activity": "hike",
  "sacGrade": "Class 1",
  "gradeScale": "yds",
  "effortLabel": "Easy",
  "durationMin": 45,
  "gainM": 35,
  "descentM": 35,
  "distanceKm": 2,
  "start": "Fairy Falls trailhead on the Grand Loop Road, 1.6 km south of Midway Geyser Basin",
  "startMapsUrl": "https://maps.apple.com/?ll=44.5156,-110.8326&q=Fairy%20Falls%20Trailhead",
  "transit": [
    {
      "mode": "car",
      "note": "Park at the Fairy Falls trailhead lot, which fills by 09:30 in July and August. No public transport runs in the park."
    },
    {
      "mode": "plane",
      "note": "Yellowstone Airport (WYS) in West Yellowstone, 45 km by road, has flights from June to September."
    }
  ],
  "description": "A flat kilometer on the old Fountain Freight Road, then a short climb to a platform above Grand Prismatic Spring. Go mid morning on a warm day, once the steam has lifted.",
  "equipment": [
    "Bear spray",
    "A warm layer for the morning"
  ],
  "sources": [
    "https://www.nps.gov/places/000/grand-prismatic-spring.htm",
    "GPX recorded by Mara Lindgren on 2026-09-14"
  ],
  "extraProps": [
    {
      "label": "Dogs",
      "value": "Not allowed on park trails"
    }
  ],
  "track": {
    "coordinates": [
      [
        -110.8326,
        44.5156,
        2181
      ],
      [
        -110.8349,
        44.517,
        2182
      ],
      [
        -110.8372,
        44.5183,
        2183
      ],
      [
        -110.8391,
        44.519,
        2186
      ],
      [
        -110.8402,
        44.5196,
        2201
      ],
      [
        -110.8406,
        44.5199,
        2214
      ]
    ],
    "source": "gpx",
    "fileName": "fairy-falls-overlook-2026-09-14.gpx"
  },
  "status": null,
  "season": {
    "months": [
      4,
      5,
      6,
      7,
      8,
      9,
      10
    ],
    "closureNote": "Park roads close to cars from early November to mid April; the trailhead is then reached by snowcoach only.",
    "statusUrl": "https://www.nps.gov/yell/planyourvisit/conditions.htm"
  },
  "variants": [
    {
      "name": "On to Fairy Falls",
      "extraKm": 6.8,
      "extraMin": 120,
      "purpose": "A 60 m waterfall 3.4 km further along the same trail, quiet before 09:00."
    }
  ],
  "stages": [],
  "segments": [
    {
      "name": "Fountain Freight Road",
      "km": 1.1,
      "accessNote": "Flat gravel road over the Firehole River, closed to cars. Bikes allowed."
    },
    {
      "name": "Overlook spur",
      "km": 0.3,
      "accessNote": "Hikers only. The one climb of the route."
    }
  ],
  "shape": "out_and_back",
  "durationBasis": "round_trip",
  "ascentMin": null,
  "descentMin": null,
  "sourceGrade": "Easy",
  "figureSources": [
    {
      "field": "distanceKm",
      "kind": "sourced",
      "url": "https://www.nps.gov/places/000/grand-prismatic-spring.htm"
    },
    {
      "field": "gainM",
      "kind": "computed",
      "note": "From the GPX, smoothed"
    },
    {
      "field": "durationMin",
      "kind": "computed",
      "note": "Walking time without the stop on the platform"
    }
  ],
  "reviewNotes": "The NPS page gives no elevation gain; the figure comes from the GPX.",
  "factsCheckedOn": "2026-09-20",
  "reviewBy": "2027-04-01",
  "createdAt": 1789895640000,
  "updatedAt": 1789895640000,
  "spots": [],
  "facilities": []
}

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.