Last updated: 27 August 2026
Two ways to integrate with Route AI: deep links (no key, the user's browser does the planning) and the Agent API (key-gated, the server plans and returns structured results with a share link). Both take a plain-language brief in any language.
Open the planner with the brief in the q query parameter
(URL-encoded) and the route builds itself on arrival:
https://route-ai.app/?q=90%20km%20coastal%20loop%20from%20Karlskrona%2C%20quiet%20roads
The visitor sees the route drawn on the map and can refine it by chat, drag waypoints, export GPX or a Garmin FIT course, and share it. Good briefs state a start place, a rough distance or duration, the activity, and preferences (loop or one-way, surface, avoid climbs). This is the recommended integration for chat assistants, articles and QR codes.
The Agent API plans server-side and returns structured route data plus a public share link — no browser involved. It exists so that assistants (ChatGPT Actions, Claude/MCP, plain scripts) can complete a request like "plan a 2-day gravel trip around Karlskrona and give me the link" end to end.
Authentication: Authorization: Bearer <token> on every
request. The normal way to get a token is the OAuth flow — connect an MCP
client (below) and the browser sign-in mints one for you, scoped to your
Google account with a daily plan quota. A plan call takes
1–3 minutes: geocoding is throttled to respect
OpenStreetMap Nominatim's usage policy.
curl -X POST https://route-ai.app/api/agent/routes \
-H "Authorization: Bearer $KEY" -H "content-type: application/json" \
-d '{
"prompt": "Plan a scenic 2-day gravel trip around Karlskrona, coastal and quiet roads",
"start": "Stena Line Terminal, Karlskrona",
"end": "Stena Line Terminal, Karlskrona",
"days": 2,
"daily_distance_km": {"min": 80, "max": 100},
"activity": "cycling",
"bike_type": "gravel"
}'
Only prompt is required; the structured fields strengthen the
brief when the agent knows them. Also accepted: preferences and
avoid (arrays of short strings).
Response (abridged):
{
"route_id": "8nHYRwAlKSxO",
"name": "Day 1 +1",
"days": 2,
"distance_km": 150.3,
"elevation_m": 627,
"stages": [
{"day": 1, "name": "Eastern coast and archipelago loop",
"distance_km": 87.8, "elevation_m": 344, "retraced_pct": 33,
"waypoints": ["Stena Line Terminal, ...", "Sturkö, ...", "..."]},
{"day": 2, "...": "..."}
],
"share_url": "https://route-ai.app/s/KTB5Mx-yxhLq",
"export": {"gpx": "https://route-ai.app/api/agent/routes/8nHYRwAlKSxO/export?format=gpx"},
"planner_reply": "…",
"warnings": [
{"type": "OUT_AND_BACK", "message": "'Sturkö' is reached out-and-back on the same road — kept because removing it would fall short of the requested distance."}
]
}
Every number is measured by routing real roads (OpenStreetMap + BRouter) — never estimated by a language model. The planner runs one automatic correction pass when a day misses the requested distance range, and reports what it could not fix as warnings rather than hiding it:
| warning | meaning |
|---|---|
GEOCODE_FAILED | a place name could not be located and was skipped |
ROUTING_GAP | a stretch could not be routed and is bridged by a straight line |
SPUR_REMOVED | a dead-end stop was dropped automatically |
OUT_AND_BACK | a dead-end stop was kept to honour the requested distance |
BACKTRACKING | a share of the day repeats the same roads |
UNDER_DISTANCE / OVER_DISTANCE | a day misses the requested daily range |
Returns the same summary. Add ?geometry=1 for full coordinates
(large; omitted by default to keep responses small for LLM consumption).
Returns the public share URL. Idempotent — the link is created with the route and never changes.
GPX 1.1 with elevation. &day=N exports a single stage.
FIT courses are available on the share page; the API is GPX-only for now.
Errors are structured for machine consumption:
{"error": "NO_PLAN", "message": "…", "suggestions": ["…"]}.
Codes: UNAUTHORIZED (401), QUOTA_EXCEEDED (429),
BAD_REQUEST (400), NO_PLAN /
NO_ROUTABLE_DAY (422), ROUTING_FAILED /
AI_FAILED (502).
Route AI is a hosted MCP server at https://route-ai.app/mcp
exposing plan_route, get_route,
share_route and export_route. Tools accept either
route ids or route-ai.app/s/… share URLs, so "here's my route
link — improve day 2" conversations work. One command to connect:
Claude Code
claude mcp add --transport http route-ai https://route-ai.app/mcp
Codex CLI (via the mcp-remote stdio bridge)
codex mcp add route-ai -- npx -y mcp-remote https://route-ai.app/mcp
No key needed: on first use a browser page opens, you sign in with Google
and click Approve, and the client receives its own token (OAuth 2.1 with
dynamic registration and PKCE). The endpoint is stateless Streamable HTTP,
so any other MCP client can connect the same way — or pass
Authorization: Bearer rai_… directly for scripts and CI.
Everything above is discoverable without reading this page:
| URL | what it is |
|---|---|
| /.well-known/mcp.json | MCP manifest: endpoint, tools, auth, install commands |
| /openapi.json | OpenAPI 3.1 — import straight into a ChatGPT Custom GPT Action |
| /.well-known/oauth-authorization-server | OAuth 2.1 metadata (authorize, token, dynamic registration) |
| /.well-known/oauth-protected-resource | Which authorization server protects /mcp |
| /llms.txt | Plain-text summary of the whole service for AI crawlers |
Planning costs real money and public-API goodwill (OpenAI, Nominatim, BRouter), hence the keys and quotas. Routes and share links are public snapshots — don't send anything private in a prompt. The underlying data is © OpenStreetMap contributors (ODbL); routing by BRouter.