Quickstart
Routing between two points in South Africa - three steps:
- Get a key from the Get a Key section below.
- Send the key in the
X-API-Keyheader on every request. - Call
/ors/v2/directions/{profile}withstartandendaslon,lat.
curl -H "X-API-Key: YOUR_KEY" \ "https://routing.dvz.services/ors/v2/directions/driving-car?start=28.0473,-26.2041&end=18.4241,-33.9249"
Get an API Key
API keys are created from the Dashboard. Create a free account and you get 10,000 tokens every month at no cost (no card required). From there you can create, rename, reveal, copy and revoke keys, watch your usage live, and upgrade when you outgrow the free tier. See Tokens & Limits below.
Already have a key? Paste it into the Check Usage box in the sidebar to see its usage right here.
Authentication
All /ors/v2/* endpoints (except /ors/v2/health and /ors/v2/status) require an X-API-Key header. Missing or unknown keys return 401.
Base URL
https://routing.dvz.services
Rate limit
30 requests/sec per key. Bursts beyond return429.
Profiles
driving-car, foot-walking
Tokens & Limits
Usage is metered in tokens, weighted by how heavy each call is. Every account starts with 10,000 free tokens per month - no card needed. When you run out, paid plans and once-off top-up packs are available on the Dashboard.
What each call costs
| Endpoint | Tokens per call |
|---|---|
/ors/v2/directions/{profile} | 5 (simple) · 10 (multi-stop) |
/ors/v2/snap/{profile} | 1 |
/geocode | 1 |
/reverse | 1 |
/ors/v2/matrix/{profile} | 1 per origin×destination pair |
/ors/v2/isochrones/{profile} | 10 |
/ors/v2/health, /ors/v2/status | 0 (free, no key) |
Only successful (2xx) authenticated calls are billed - failed or unauthorized requests cost nothing. Tokens reset monthly. On the free tier your keys stop working at 0 until the next reset or an upgrade; paid plans keep serving and you simply top up.
Free tier
10,000 tokens / month, all endpoints, no card.Rate limit
30 requests/sec per key (separate from tokens). Bursts return429.
Manage & upgrade
Balance, usage charts and plans live on the Dashboard.Endpoints
GET /ors/v2/directions/{profile} - Route between two points
Returns a single best route as GeoJSON with turn-by-turn instructions.
Query params
| Name | Type | Required | Description |
|---|---|---|---|
start | string | yes | Start lon,lat |
end | string | yes | End lon,lat |
Example
curl -H "X-API-Key: YOUR_KEY" \ "https://routing.dvz.services/ors/v2/directions/driving-car?start=28.0473,-26.2041&end=18.4241,-33.9249"
POST /ors/v2/directions/{profile} - Advanced routing
Multiple waypoints, alternative routes, preferences, full options.
Example
curl -X POST "https://routing.dvz.services/ors/v2/directions/driving-car" \
-H "X-API-Key: YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"coordinates": [[28.0473,-26.2041], [25.6022,-33.9608], [18.4241,-33.9249]],
"instructions": true,
"preference": "recommended"
}'POST /ors/v2/matrix/{profile} - N-to-N distance + duration
Computes all-pairs distance and duration between up to 50 locations (a 50×50 matrix = 2,500 pairs).
Example
curl -X POST "https://routing.dvz.services/ors/v2/matrix/driving-car" \
-H "X-API-Key: YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"locations": [[28.0473,-26.2041], [18.4241,-33.9249], [31.0218,-29.8587]],
"metrics": ["distance", "duration"]
}'POST /ors/v2/isochrones/{profile} - Reach polygons
Areas reachable from a point within given times or distances.
Example
curl -X POST "https://routing.dvz.services/ors/v2/isochrones/driving-car" \
-H "X-API-Key: YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"locations": [[28.0473,-26.2041]],
"range": [600, 1800],
"range_type": "time"
}'POST /ors/v2/snap/{profile} - Snap points to road network
Snap arbitrary lon/lat points to the nearest road within a radius.
Example
curl -X POST "https://routing.dvz.services/ors/v2/snap/driving-car" \
-H "X-API-Key: YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"locations": [[28.0473,-26.2041]], "radius": 350}'GET /ors/v2/health - Engine health public
Returns {"status": "ready"} when the routing engine is up. No API key required - useful for monitoring.
GET /ors/v2/status - Engine status & profiles public
Returns the engine version, graph build dates, the enabled routing profiles (driving-car, foot-walking) and the available services (routing, isochrones, matrix, snap). No API key required.
Example
curl "https://routing.dvz.services/ors/v2/status"
GET /geocode - Forward geocode (address → coordinates)
Takes free text and returns ranked coordinate matches. Powered by self-hosted Pelias on OpenStreetMap + Who's On First data, biased to South Africa. It matches businesses and POIs (e.g. Sandton City, Spar Polokwane, OR Tambo International Airport), as well as streets, suburbs, towns and place names. Coverage is as good as OpenStreetMap, so well-known places and chains resolve across both cities and rural towns; tiny unmapped businesses may not. Costs 1 token per call. Response is a stable DVZ envelope.
Query params
| Name | Type | Required | Description |
|---|---|---|---|
q | string | yes | Free-text address or place name (1–200 chars) |
limit | int | no | Max results, 1–20 (default 5) |
country | string | no | ISO-3166-1 alpha-2 country bias. Defaults to za. Pass empty string for worldwide. |
format | string | no | dvz (default, clean envelope) or raw for the full upstream Pelias GeoJSON. |
Example
curl -H "X-API-Key: YOUR_KEY" \ "https://routing.dvz.services/geocode?q=Sandton%20City&limit=5"
Response shape
{
"query": "Sandton City",
"provider": "pelias",
"count": 1,
"results": [
{
"lat": -26.10853,
"lon": 28.05299,
"display_name": "Sandton City, Sandton, GT, South Africa",
"type": "venue",
"importance": 0.9,
"address": {
"suburb": "Sandton",
"city": "Sandton",
"state": "GT",
"country": "South Africa",
"country_code": "za",
"postcode": null
}
}
]
}type reflects the match layer: venue (business/POI), address, street, locality (town), or admin area. importance is a 0–1 confidence score.
GET /reverse - Reverse geocode (coordinates → address)
Takes a lat/lon point and returns the closest matching address or place. Same self-hosted Pelias backend and DVZ envelope as /geocode, but for a single point. Costs 1 token per call.
Query params
| Name | Type | Required | Description |
|---|---|---|---|
lat | float | yes | Latitude, –90 to 90 |
lon | float | yes | Longitude, –180 to 180 |
format | string | no | dvz (default) or raw for the full upstream payload. |
Example
curl -H "X-API-Key: YOUR_KEY" \ "https://routing.dvz.services/reverse?lat=-26.2041&lon=28.0473"
Response shape
{
"lat": -26.2041,
"lon": 28.0473,
"provider": "pelias",
"result": {
"lat": -26.2041,
"lon": 28.0473,
"display_name": "Marshalltown, Johannesburg, GT, South Africa",
"type": "locality",
"address": {
"city": "Johannesburg",
"state": "GT",
"country": "South Africa",
"country_code": "za"
}
}
}Postman collection
Every endpoint above is also in our Postman collection - ready-to-run with collection variables for base URL, API key, and routing profile.
After importing, open the collection's Variables tab and paste your apiKey. The baseUrl defaults to production - change to http://localhost for local dev.
Also works in Insomnia, Bruno, Hoppscotch, and most other API clients via "Import from URL" with the JSON link above.
Errors
| Status | Meaning | What to do |
|---|---|---|
401 | Missing / unknown / revoked key, out of tokens, or suspended account | Check your key. If you've used all your monthly tokens, top up or upgrade on the Dashboard. |
429 | Rate limit exceeded (30 req/sec) | Add client-side throttling or request a higher limit. |
400 | Bad request (malformed body, invalid params) | Check the example for that endpoint. |
500/502/503 | Engine unavailable | Check /ors/v2/health - if it's down, contact the team. |