Route brief

POST https://api.trailsplits.com/v1/route-brief

Checked by a live probe Key optional · 500 credits a day without one Heavy: 1 at a time on Free

One call for one day’s line: route analysis, weather at arrival time, sun and shade, places along the route and snow evidence, picked with include, each the same answer its own endpoint gives. On top, notices are fact codes placed along the line (a ford, a stretch tagged T4, 7 km without mapped water, a thunderstorm in the model at the hour you get there), each with its part and source. Notices are facts, never advice, gear or a safety score; snow_observed is never "now". A part that fails is null with the reason in unknowns. Heavy request; 10 credits.

Example

Route brief (curl)
# Without a key, leave out the Authorization line (500 credits a day per address).
curl --fail-with-body 'https://api.trailsplits.com/v1/route-brief' \
  -H "Authorization: Bearer $TRAILSPLITS_API_KEY" \
  -H 'Content-Type: application/json' \
  --data '{"geometry":{"type":"LineString","coordinates":[[6.97178,45.79266],[6.98409,45.80185],[6.98629,45.80488],[6.98231,45.80634],[6.9782,45.80782],[6.9784,45.81286],[6.98961,45.82424],[7.00303,45.82901],[7.0139,45.83525],[7.02084,45.83669],[7.02859,45.84621],[7.03402,45.84664]]},"include":["analysis","places"]}'

Sends a real request, with your key or the keyless allowance.

Request body

FieldTypeDescription
gpxstringOne line as GPX, one part, at most 120 km and 5,000 points. Or geometry, not both.
geometryobjectA GeoJSON LineString, [lon, lat].
includearrayThe parts to give; default all.
departurestringISO 8601 with offset, six hours ago to 16 days ahead. Required with weather or sun, refused without them.
profilestring: hike | run | bike
pace_factornumber
min_per_kmnumber
kmhnumber
stopsarray

Response

FieldTypeDescription
schemastring: route-brief/1
engineobject
includearray
settings_defaultedarray
lineobject
noticesarray
analysisobject or nullAs POST /v1/route-analysis answers, or null (see unknowns).
weatherobject or nullAs POST /v1/route-weather answers (with sun when included), or null.
placesobject or nullAs POST /v1/route-places answers, or null.
snowobject or nullThe snow evidence along the line, or null (snow_not_assessed below 800 m outside the snow months).
unknownsarray
Full response schema (JSON Schema)
{
  "type": "object",
  "properties": {
    "schema": {
      "type": "string",
      "enum": [
        "route-brief/1"
      ]
    },
    "engine": {
      "type": "object"
    },
    "include": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "settings_defaulted": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "line": {
      "type": "object",
      "properties": {
        "length_m": {
          "type": "number"
        },
        "points": {
          "type": "integer"
        }
      },
      "required": [
        "length_m",
        "points"
      ]
    },
    "notices": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "code": {
            "type": "string",
            "description": "A fact code, such as ford, via_ferrata, difficulty_t4_or_harder, off_mapped_paths, no_mapped_water_km, snow_observed, thunderstorm_forecast, storm_energy_cape, freezing_temperature, strong_gusts, beyond_civil_twilight. New codes may appear; ignore unknown ones."
          },
          "from_m": {
            "type": "number"
          },
          "to_m": {
            "type": "number"
          },
          "value": {
            "type": "number",
            "nullable": true
          },
          "unit": {
            "type": "string",
            "nullable": true
          },
          "rule": {
            "type": "string",
            "nullable": true
          },
          "part": {
            "type": "string"
          },
          "source": {
            "type": "string"
          },
          "message": {
            "type": "string"
          }
        },
        "required": [
          "code",
          "from_m",
          "to_m",
          "part",
          "source",
          "message"
        ]
      }
    },
    "analysis": {
      "type": "object",
      "nullable": true,
      "description": "As POST /v1/route-analysis answers, or null (see unknowns)."
    },
    "weather": {
      "type": "object",
      "nullable": true,
      "description": "As POST /v1/route-weather answers (with sun when included), or null."
    },
    "places": {
      "type": "object",
      "nullable": true,
      "description": "As POST /v1/route-places answers, or null."
    },
    "snow": {
      "type": "object",
      "nullable": true,
      "description": "The snow evidence along the line, or null (snow_not_assessed below 800 m outside the snow months)."
    },
    "unknowns": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "part": {
            "type": "string"
          },
          "code": {
            "type": "string"
          },
          "message": {
            "type": "string"
          }
        },
        "required": [
          "code",
          "message"
        ]
      }
    }
  },
  "required": [
    "schema",
    "engine",
    "include",
    "line",
    "notices",
    "unknowns"
  ]
}

Errors

400, 413, 422, 503, plus the gateway's 401, 429 and 503 (error conventions). A refused request costs no credits.

Contract

One call for one day's line, with include picking the parts:

Each part is the same answer its own endpoint gives for the same line and settings. On top of them, notices[] holds fact codes, each with a position on the line, a value where one applies, the part it comes from and its source.

What it does not do. Notices are facts, never advice. There is no gear list, no safety score and no avalanche or risk judgement. An app turns the codes into its own words: a long stretch without mapped water may become "carry water" in one app and nothing in another.

Request

{ "gpx": "<gpx…>", "departure": "2026-10-04T07:00:00+02:00" }
{ "geometry": { "type": "LineString", "coordinates": [[lon, lat], …] }, "include": ["analysis", "places", "snow"] }
Field
gpx or geometryone of themOne line (one part), at most 120 km (one day) and 5,000 points
includedefault all but slopesAny of analysis, weather, sun, places, snow, and slopes, which is only given when asked for (experimental, route-slopes-v1)
departurewith weather or sunAs for route weather: an ISO time with its offset, from six hours ago to 16 days ahead. Refused without weather or sun
profilehike (default), run, bikeUsed by analysis and weather
pace_factor, min_per_km, kmh, stopsAs for route weather; only with weather or sun
callerOptional label

Each part checks its own fields with its own rules and words, as its endpoint does.

Response

FieldMeaning
schemaroute-brief/1
include, settings_defaultedThe parts given, and the fields not given
linelength_m, points
notices[]In order along the line (by start, then end). Each has code, from_m, to_m, value and unit where one applies, rule for a notice that compares a value, part, source and message
analysis, weather, places, snow, slopesEach included part as its endpoint answers it (without the engine stamp), or null when that part could not be had (see unknowns). With sun, the weather part carries sun
unknowns[]part, code, message: a part that failed, with its own refusal code (e.g. forecast_unavailable, places_unavailable, snow_unavailable). budget_exhausted: the part was still running at the job's deadline, and its late result is dropped. snow_not_assessed: the line stays below 800 m outside the snow months, with the reason in words. The brief answers with the parts it has

Notice codes

CodeFromWhenSource
ford, aid, via_ferrataanalysisA mapped ford, aided passage (ladders, ropes, rungs) or via ferrata on the matched line; value its length in mOpenStreetMap way
difficulty_t4_or_harderanalysisThe hardest stretch is tagged T4 or harderOpenStreetMap sac_scale
off_mapped_pathsanalysisA stretch of 200 m or more follows no mapped pathMap matching on OpenStreetMap
no_mapped_water_kmplacesThe longest stretch without mapped drinking water is 5 km or more; value in km. Mapped is not runningOpenStreetMap through the places index
snow_observedsnowA run of points observed as snow, with its heights. Said with the evidence's own date (the oldest along the line) when it has one; v1 tiles carry none, so it says "the latest satellite and model observation", which can be days old (cloud), and names the 14-day mosaic when used. Never "current", never a forecast for the day you walkTrailSplits snow evidence (satellite and model)
thunderstorm_forecastweatherThe model codes a thunderstorm (95–99) at the hour you reach points of a section; value the samplesweather-forecast/1 and its model
storm_energy_capeweatherThe model's CAPE reaches 1,000 J/kg or more in a section: what its atmosphere could support, not that a storm will happenweather-forecast/1
freezing_temperatureweatherThe forecast reaches 0 °C or below at the hour you get thereweather-forecast/1
strong_gustsweatherGusts of 60 km/h or moreweather-forecast/1
beyond_civil_twilightsunA stretch walked with the sun more than 6° below the horizon, by the sun's position aloneNOAA solar position

The slopes part adds no notices while it is experimental. New codes may be added in route-brief/1; an app ignores codes it does not know. A changed meaning of a code is route-brief/2.

Errors

{ "error": { "code", "message" } }, from the brief or from a part's own request rules.

HTTPcodeWhen
400invalid_requestAn unknown field, a part not listed, departure missing with weather or sun, or given without them, pace fields without weather or sun, and each part's own request errors
400invalid_gpx, invalid_coordinatesAs for route analysis
405method_not_allowedAny method but POST (and OPTIONS)
413body_too_large, too_many_pointsOver 1 MB, or over 5,000 points
422too_long, several_parts, no_lineOver 120 km, more than one part, or no line
422departure_in_past, beyond_forecastAs for route weather
503overloadedThe worker's heavy-job queue is full

A part's failure inside the job (the forecast down, the budget out) is not an error of the brief: that part is null and unknowns says why.

Versioning

Additive fields and new notice codes may appear in route-brief/1. A change of meaning is route-brief/2.