EndpointsGeneration

Generate loop route candidates from high-level parameters

Runs the RouteGeneration pipeline (ADR-0029): a fan of candidate loops around the start point, snap-validated, routed through Valhalla, scored on Overlap/distance/surface/shape, and reduced to up to 3 diverse candidates. A response with an empty candidate list carries a structured failure code that drives retry suggestions. Each request fans out into ~10-25 Valhalla calls, hence the strict per-IP throttle.

POST
/generation

Request Body

application/json
  1. body
start*

Loop start point; the generated route begins and ends here.

activity*string
Value in"run""cycle""walk"
targetDistanceKm*number

Target loop distance in kilometers.

Range1 <= value <= 200
heading*string

Compass arc the loop should extend toward. A soft preference, never a hard guarantee.

Value in"any""north""east""south""west"
preferences*
excludeBearings?array<number>

Fan bearings already shown to the user; regenerate passes them to get fresh shapes.

Itemsitems <= 16

Response Body

Scored candidates or a structured failure

application/json
  1. response
candidates*array<>

Up to 3 diverse GenerationCandidates, best score first. Empty when generation failed.

failure?

Set when no usable candidate could be produced; the code drives retry suggestions in the UI.

curl -X POST 'https://api.routess.com/generation' \  -H 'Content-Type: application/json' \  -d '{  "start": {    "lat": 50.8467,    "lon": 4.3525  },  "activity": "cycle",  "targetDistanceKm": 40,  "heading": "any",  "preferences": {    "surfacePreference": "mixed",    "avoidFerries": true,    "avoidHighways": true  }}'
{  "candidates": [    {      "bearingDeg": 0,      "viaPoints": [        {          "lat": 50.8467,          "lon": 4.3525        }      ],      "shape": "string",      "distanceKm": 0,      "durationSeconds": 0,      "overlapPct": 0,      "score": 0,      "lowQuality": true,      "surfaceMetersByBucket": {        "paved": 32000,        "compacted": 4500,        "unpaved": 2500,        "path": 1000      }    }  ],  "failure": {    "code": "invalid_input",    "bestOverlapPct": 0  }}