PreviewThis is a preview. The API is not open yet, the addresses in these examples do not serve traffic, and nothing here is a commitment.

WayMatrix
Sign in (not available yet)Get an API key (not available yet)

01

Get a key and make the first call

Start here. Sets up the credential and proves the connection with one request.

first-call.txtShow the prompt
You are integrating WayMatrix, an HTTP routing API.

BASE URL      https://api.waymatrix.io
AUTH          the API key raw in the "Authorization" header. No "Bearer " prefix.
              A Bearer prefix is tolerated. On GET you may use ?api_key=<key>.
KEY           read it from an environment variable. Never commit it.

Use only the endpoints named in this prompt. Do not infer others, and do not
guess at parameters — if something you need is not here, say so rather than
inventing it.

TASK
----
Add WayMatrix to this project and prove it works.

1. Read the key from an environment variable named WAYMATRIX_API_KEY.
   Add it to the project's env example file with an empty value. Do not
   commit a real key, and do not print it in logs or error messages.
2. Write one function that calls:
      POST /v2/matrix/driving-car
   with a body of {"locations": [[lon, lat], [lon, lat]], "metrics": ["duration"]}.
   NOTE THE ORDER: longitude first, then latitude. This is the opposite of
   what Google Maps shows, and getting it backwards produces valid-looking
   coordinates in the wrong place rather than an error.
3. Call it once with two real coordinates from the region this project
   serves, and print the duration in minutes.
4. Confirm the number is plausible for that pair before you call it done.

The response contains "durations" as an array of arrays in the order you
sent, in seconds, plus a metadata block. Do not reorder it — there is
nothing to reindex.

02

Split a job bigger than one request allows

Your origin and destination lists multiply out past your tier's per-request cap.

big-matrix.txtShow the prompt
You are integrating WayMatrix, an HTTP routing API.

BASE URL      https://api.waymatrix.io
AUTH          the API key raw in the "Authorization" header. No "Bearer " prefix.
              A Bearer prefix is tolerated. On GET you may use ?api_key=<key>.
KEY           read it from an environment variable. Never commit it.

Use only the endpoints named in this prompt. Do not infer others, and do not
guess at parameters — if something you need is not here, say so rather than
inventing it.

THE CONSTRAINT
--------------
An element is one origin paired with one destination, so a request costs
origins x destinations.

THE CAP IS PER TIER, AND IT IS NOT THE SAME NUMBER FOR EVERY KEY.
The service will not accept more than 90,000 elements from anyone
(300 x 300 square), and the smallest published tier cap is
2,500 (50 x 50). Which one applies depends on the key you are
holding, and it changes when the account changes plan.

So DO NOT hardcode a chunk size. Take it as a parameter, default it to
the smaller figure, and let the caller raise it. A splitter sized to the
service ceiling fails every single request on a smaller tier, and the
failure looks like a broken endpoint rather than a chunk size.

Over the cap the request is refused before any work happens, so there
is no partial result to salvage. The rejection names the limit it hit, so
read the cap off the first refusal rather than guessing it.

TASK
----
Write a function that takes any number of origins and destinations and
returns the full matrix, splitting into several requests when it must.

1. Compute origins x destinations. If it fits, send one request.
2. If not, split along DESTINATIONS first and keep origins whole where you
   can — it keeps each response's rows aligned with your origin list and
   makes reassembly a concatenation rather than a join.
3. Send the chunks with limited concurrency, not all at once. Respect 429
   by backing off; see the error-handling prompt.
4. Reassemble into one array of arrays in the original order.
5. Assert the final shape is origins x destinations before returning it.

Billing is per element, not per request, so splitting a job costs exactly
the same as sending it whole. Split for the ceiling, never to save money.

Send each coordinate once: the request takes one "locations" array plus
"sources" and "destinations" arrays of INDICES into it. A point that is
both an origin and a destination does not need to appear twice.

03

Get a route between points

You need the path, distance and duration for one journey rather than a grid.

directions.txtShow the prompt
You are integrating WayMatrix, an HTTP routing API.

BASE URL      https://api.waymatrix.io
AUTH          the API key raw in the "Authorization" header. No "Bearer " prefix.
              A Bearer prefix is tolerated. On GET you may use ?api_key=<key>.
KEY           read it from an environment variable. Never commit it.

Use only the endpoints named in this prompt. Do not infer others, and do not
guess at parameters — if something you need is not here, say so rather than
inventing it.

ENDPOINT
--------
      POST /v2/directions/driving-car

TASK
----
Add a function that returns the route between an ordered list of points.
1. Send {"coordinates": [[lon, lat], [lon, lat], ...]}. Longitude first.
2. The points are visited in the order given. This endpoint does not
   reorder them for you — it is not a travelling-salesman solver.
3. Read the distance and duration from the response's summary.
If you need the geometry as GeoJSON, the same operation has a GeoJSON form;
ask for it by path rather than by a format parameter.

KNOWN TRAP, and it is not ours:
  python + gpx: The Python client calls response.

04

Find everything reachable within a time

Coverage questions: what is inside a 30-minute drive of this depot.

isochrones.txtShow the prompt
You are integrating WayMatrix, an HTTP routing API.

BASE URL      https://api.waymatrix.io
AUTH          the API key raw in the "Authorization" header. No "Bearer " prefix.
              A Bearer prefix is tolerated. On GET you may use ?api_key=<key>.
KEY           read it from an environment variable. Never commit it.

Use only the endpoints named in this prompt. Do not infer others, and do not
guess at parameters — if something you need is not here, say so rather than
inventing it.

ENDPOINT
--------
      POST /v2/isochrones/driving-car

TASK
----
Add a function that returns the area reachable from a point within a given
travel time, as a polygon you can test other points against.

1. Send {"locations": [[lon, lat]], "range": [1800], "range_type": "time"}.
   Range is in SECONDS when range_type is time, and metres when it is
   distance. 1800 is thirty minutes.
2. Several ranges in one call return nested polygons — ask for [900, 1800]
   rather than making two calls, which costs the same and is one round trip.
3. The result is GeoJSON. Use a point-in-polygon test against it rather than
   re-querying the API per candidate point.

Use this instead of a matrix when the question is "what is within reach"
rather than "how far apart are these". It is one call instead of hundreds.

05

Move an openrouteservice integration across

You already call openrouteservice and want the same code pointed here.

migrate-ors.txtShow the prompt
You are integrating WayMatrix, an HTTP routing API.

BASE URL      https://api.waymatrix.io
AUTH          the API key raw in the "Authorization" header. No "Bearer " prefix.
              A Bearer prefix is tolerated. On GET you may use ?api_key=<key>.
KEY           read it from an environment variable. Never commit it.

Use only the endpoints named in this prompt. Do not infer others, and do not
guess at parameters — if something you need is not here, say so rather than
inventing it.

TASK
----
This codebase calls openrouteservice. Point it here instead.

1. Change the base URL to https://api.waymatrix.io. Change nothing else about
   the request: paths, bodies, field names and response shapes match.
2. The auth header is the same — the raw key, no Bearer prefix — so an
   existing openrouteservice client library works unmodified.
3. Then fix these four behaviours, which are the whole of the difference:

   a. THIS API NEVER RETURNS 503. An unreachable engine is 502. Find every
      retry that triggers on 503 and add 502, or retry only on 429.
   b. Retry on the STATUS, not on the error code. A 429 is always worth
      retrying with backoff — it is a per-minute limit or a concurrency
      refusal, and both clear on their own. A 403 is never worth retrying,
      and that is where an exhausted monthly allowance arrives: it is a 403
      by design, precisely so it cannot be mistaken for a throttle.
   c. Only matrix, directions and isochrones exist. No geocoding, no places,
      no elevation, no optimisation. If this project calls those, it is
      splitting across two providers rather than moving — say so.
   d. Driving only, North America only.

4. Run one real request and compare the durations against what the old
   endpoint returned for the same pair. They will not be identical; they
   should be close.

06

Move a Google Distance Matrix integration across

You call Google computeRouteMatrix. This is a rewrite, not a URL change.

migrate-google.txtShow the prompt
You are integrating WayMatrix, an HTTP routing API.

BASE URL      https://api.waymatrix.io
AUTH          the API key raw in the "Authorization" header. No "Bearer " prefix.
              A Bearer prefix is tolerated. On GET you may use ?api_key=<key>.
KEY           read it from an environment variable. Never commit it.

Use only the endpoints named in this prompt. Do not infer others, and do not
guess at parameters — if something you need is not here, say so rather than
inventing it.

TASK
----
This codebase calls Google's Routes API computeRouteMatrix. Move it here.
This is a real rewrite, not a base URL change. Map it field by field:

  origins[].waypoint.location.latLng  ->  locations[], as [lon, lat]
  destinations[]...                   ->  "destinations": indices into locations
  travelMode: "DRIVE"                 ->  the profile in the path
  routingPreference                   ->  NO EQUIVALENT. There is no traffic.
  X-Goog-Api-Key header               ->  the "Authorization" header
  X-Goog-FieldMask header             ->  no equivalent; the whole matrix returns
  element.duration ("123s")           ->  durations[i][j], a number of seconds
  element.distanceMeters              ->  distances[i][j], in metres
  element.originIndex/destinationIndex->  not needed; see below

THE TWO THAT WILL BITE:

1. THE COORDINATE ORDER FLIPS. Google names its numbers in an object.
   This API takes [longitude, latitude] as an array. A pair the wrong way
   round is usually still a valid coordinate, so nothing errors — you get
   durations for the wrong place. Check one result against a road you know.

2. GOOGLE'S RESPONSE IS UNORDERED and yours is not. Their documentation
   says elements are not guaranteed to arrive in any order, which is why
   each carries originIndex and destinationIndex. This API returns arrays
   of arrays in the order you sent. DELETE the reindexing code rather than
   porting it, and delete the parser that strips the trailing "s" from
   their duration strings.

Also remove any per-element status handling: a failed pair is null in the
matrix, and a failed request is an HTTP error.

07

Write the retry and error handling

Before you ship. Retrying the wrong status is how a quota outage becomes an outage.

errors.txtShow the prompt
You are integrating WayMatrix, an HTTP routing API.

BASE URL      https://api.waymatrix.io
AUTH          the API key raw in the "Authorization" header. No "Bearer " prefix.
              A Bearer prefix is tolerated. On GET you may use ?api_key=<key>.
KEY           read it from an environment variable. Never commit it.

Use only the endpoints named in this prompt. Do not infer others, and do not
guess at parameters — if something you need is not here, say so rather than
inventing it.

TASK
----
Write error handling for the calls in this project. Branch on these, and
do not add retries for anything not listed as retryable.

  429  Rate limited, or too many at once.
                            RETRY with exponential backoff and jitter.
                            Both causes clear on their own. Retry on the
                            status; do not branch on the code to decide.
  403  Key rejected, or the monthly quota is spent.
                            TERMINAL. Do not retry — it will not help.
                            Surface it; someone has to act.
  400  The request is too large, or malformed.
                            TERMINAL. Fix the request; see the splitting
                            prompt if it is a size problem.
  401  No key was sent.     TERMINAL. A configuration bug.
  404  A path that is not served.  TERMINAL.
  502  The routing engine did not answer.
                            RETRY a small number of times, then give up.

THIS API NEVER RETURNS 503. If your client library retries 503 by default,
that path is dead code here and 502 is what you must handle instead.

Errors come back as JSON with a "code" field alongside the HTTP status.
Log the code — it distinguishes cases that share a status, and 403 covers
both "this key is wrong" and "this month is spent", which need different
human responses.

Requests that fail are not billed. Do not build a reconciliation path for
charges on failed calls; there are none.

08

Estimate what a workload will cost

Before you commit. Turns a description of your job into a number.

cost.txtShow the prompt
You are integrating WayMatrix, an HTTP routing API.

BASE URL      https://api.waymatrix.io
AUTH          the API key raw in the "Authorization" header. No "Bearer " prefix.
              A Bearer prefix is tolerated. On GET you may use ?api_key=<key>.
KEY           read it from an environment variable. Never commit it.

Use only the endpoints named in this prompt. Do not infer others, and do not
guess at parameters — if something you need is not here, say so rather than
inventing it.

THE BILLING MODEL
-----------------
The billed unit is the element: one origin paired with one destination.
A 200 x 150 matrix costs 30,000 of them whether you send it as one request
or as thirty. Requests that fail are not billed.

The free tier includes 250,000 elements a month and stops rather than billing.

TASK
----
Work out what this project will actually spend.
1. Find every call this codebase makes to a routing or distance API.
2. For each, work out the element count per call: origins x destinations
   for a matrix; a directions call has a flat cost. An isochrone costs more
   the further it reaches — flat at short range, climbing with the square of
   the range — so price those from the ranges this code actually requests.
3. Multiply by how often each runs. Be honest about retries and about
   anything inside a loop — that is where the surprise usually is.
4. Report the monthly total, then say which tier it lands in.
Two things worth checking while you are in there. If the same matrix is
computed repeatedly from unchanged inputs, cache it — results may be stored
indefinitely here, which is not true of every provider. And if a loop calls
the API once per candidate point, one isochrone call may replace all of it.

Why these are generated

A person skimming a tutorial notices a wrong example. An agent does not — it follows the instruction confidently, at scale, and the mistake ends up committed. So every path, method, header and limit below is read from the same files the API is built from. When a cap changes, these change with it.

For agents that fetch rather than paste

There is a machine-readable summary of this API at /llms.txt. Point an agent at it and it gets the base URL, the endpoints, the limits and the absences without you pasting anything.

/llms.txt

Not using an agent?

Everything here is also written out for a person to read. The migration guides cover moving from openrouteservice or Google, and the reference has the full endpoint list.