OSRMplus

Cloud API

We run the servers, you send requests. Nothing to install, no map data to build, no machine to keep an eye on. You take a key from your dashboard and point your code at our address.

The API follows the OSRM conventions, so any client that already talks to OSRM works here. The only things that change are the address you call and the key you send with it.

https://api.osrmplus.com

Sending your key

Every request needs your key. Send it in whichever of these two headers suits your client. A request with no key is turned away.

x-api-key: opr_your_key_here

or, if your client prefers it this way

Authorization: Bearer opr_your_key_here

Keys are made in the dashboard, under API keys. The whole key is shown once, at the moment you create it. After that only the first few characters are visible, so keep it somewhere safe. If you lose one, delete it and make another.

Your first call

curl -s "https://api.osrmplus.com/route/v1/driving/46.6753,24.7136;46.7153,24.7536?overview=full" \
  -H "x-api-key: opr_your_key_here"

Coordinates are lng,lat pairs joined by semicolons. That is how OSRM has always taken them and we have not changed it, so the answers are the same shape your code already reads.

The endpoints are the same ones listed under API Reference further down: /route, /table, /nearest, /match, /trip, and the /vrp, /tsp and /optimize solvers.

Regions

A region is a part of the world we hold map data for, such as the Gulf or Europe. Your plan says how many you can hold, and you choose them in the dashboard. Your key works inside those regions and nowhere else.

You never name a region in a request. We work it out from the coordinates you send. If they land inside a region you hold, the request runs. If they do not, you get HTTP 403 and the list of regions your key does cover.

{
  "error": {
    "code": "region_not_licensed",
    "message": "This key does not cover the europe region",
    "details": { "region": "europe", "licensed": ["gulf"] }
  }
}

One request has to stay inside one region. A trip from a stop in the Gulf to a stop in Europe has no answer, even if you hold both. Inside a region you can travel as far as the map goes. Large regions are spread over several machines, and we join them up for you, so a long journey across a whole region is a single call like any other.

Adding a region in the dashboard takes effect within a minute, and your keys pick it up on their own. There is no key to rotate and no code to change. Changing plan works the same way.

Distance Matrix

A matrix gives you the travel time between every origin and every destination in one call. It is the usual first step before planning a delivery round, and it is far cheaper than asking about each pair on its own.

3 by 3: every point to every other point

curl -s "https://api.osrmplus.com/table/v1/driving/46.67,24.71;46.72,24.75;46.69,24.73" \
  -H "x-api-key: opr_your_key_here"

Use sources and destinations when you only need part of the grid, which is quicker and costs less. Ask for road distance as well as time with annotations.

1 origin to 2 destinations, with distances as well as times

curl -s "https://api.osrmplus.com/table/v1/driving/46.67,24.71;46.72,24.75;46.69,24.73?sources=0&destinations=1;2&annotations=duration,distance" \
  -H "x-api-key: opr_your_key_here"

The answer is the plain OSRM shape: times in seconds, distances in metres, and null for any pair with no way through.

What a matrix costs

Matrices are counted in elements, and elements are origins multiplied by destinations. The 3 by 3 call above is 9 elements. The 1 by 2 call is 2. Each call also counts as one routing call, the same as a route would.

Your plan sets the longest side a matrix may have. Ask for more and the request is refused before any work begins, with the code table_size_exceeds_plan and the limit in the body, so you can either split the job or move up a plan.

Traffic Profiles

Plain routing treats a motorway as being just as quick at eight in the morning as it is at midnight. A traffic profile fixes that. It is a short set of rules saying how much slower a kind of road is at a time of day, and we apply them to the times we hand back.

Profiles come with the Pro and Enterprise plans. The easiest way to make one is in the dashboard, under Traffic, where you pick a road type, a time of day and a multiplier and we build the file for you. You can also upload your own.

What a profile looks like

A profile is a CSV file with three columns.

road_class,time_slot,multiplier
motorway,morning_rush,1.6
motorway,evening_rush,1.8
primary,morning_rush,1.4
residential,night,0.9
ColumnWhat it accepts
road_classmotorway, trunk, primary, secondary, tertiary or residential.
time_slotmorning_rush, midday, evening_rush, night, or your own window on a 24 hour clock such as 07-09.
multiplierBetween 0.5 and 5.0. A value of 1.6 means the trip takes 60 percent longer. Below 1 means faster than normal.

upload a profile

curl -X POST https://api.osrmplus.com/traffic/profiles \
  -H "x-api-key: opr_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Riyadh weekday",
    "region": "gulf",
    "csv": "road_class,time_slot,multiplier\nmotorway,morning_rush,1.6"
  }'

see what you have

curl -s https://api.osrmplus.com/traffic/profiles -H "x-api-key: opr_your_key_here"

remove one

curl -X DELETE "https://api.osrmplus.com/traffic/profiles?profileId=YOUR_PROFILE_ID" \
  -H "x-api-key: opr_your_key_here"

A multiplier of exactly 1.0 means no change, so a rule set to 1.0 does nothing. That is worth checking first if a profile looks like it is being ignored.

Asking about a particular time

Add depart_at to a matrix request to say when the journey starts. Leave it out and we use the time right now. We then pick whichever of your profiles for that region covers that hour.

curl -s "https://api.osrmplus.com/table/v1/driving/46.67,24.71;46.72,24.75?depart_at=2026-09-03T08:00:00Z" \
  -H "x-api-key: opr_your_key_here"

To use one profile in particular, name it with traffic_profile. That profile is then used whatever the hour, which is how you compare two sets of assumptions over the same stops. Naming a profile that is not yours, or is not live, is refused with traffic_profile_unknown rather than quietly ignored.

curl -s "https://api.osrmplus.com/table/v1/driving/46.67,24.71;46.72,24.75?traffic_profile=YOUR_PROFILE_ID" \
  -H "x-api-key: opr_your_key_here"

When a profile was consulted, the answer carries a traffic_profile field naming it, the slot it matched and the number your times were multiplied by. A multiplier of 1 means that profile had nothing to say about that hour, so the times are the plain ones.

{
  "code": "Ok",
  "durations": [[0, 1299.2]],
  "traffic_profile": {
    "id": "9f2c41ab",
    "name": "Riyadh weekday",
    "time_slot": "morning_rush",
    "multiplier": 1.6
  }
}

How road classes are read

A matrix is one number per pair, with no record of which roads the journey used, so there is nothing to match a road class against. When your profile has rules for more than one class, we use the average of the ones that cover the hour. A profile with a single rule, such as motorways in the morning rush, applies that rule.

So write rules for the roads your journeys actually spend their time on. A rule about residential streets will pull down the average on a matrix that is mostly motorway driving.

Traffic changes matrix times only. Route answers are left as they are, so nothing you already rely on shifts underneath you when you upload a profile.

Playground

The playground is a map where you can try a route, a matrix or a delivery plan without writing any code. Click a few points, pick what you want, and read the answer next to the raw JSON we sent back.

Signed out, it runs on a New York demo so anyone can have a look. Signed in, it switches to the regions on your plan, and gives you a picker when you hold more than one. If your plan includes traffic, the time of day controls appear in matrix mode.

It is a real client, not a demo with canned answers. Calls you make there go through a key of your own, so they count against your account in the same way as calls from your code, and they show up in your usage.

Limits and Usage

Three numbers are counted for your account, and they reset at the start of each calendar month.

CountedWhat adds to it
Routing callsOne for each route, matrix, nearest, match or trip request.
Matrix elementsOrigins multiplied by destinations, on every matrix request.
OptimizationsOne for each VRP or TSP solve, however many stops it had.

Your dashboard shows where you stand against your plan. The free plan has a daily cap as well as a monthly one, which stops a runaway script from spending a whole month of allowance in an afternoon. Every plan has a burst limit per second and per minute.

A request we refuse is not counted. If you are turned away for being over a limit, that attempt is not added to your usage.

Error Codes

Errors come back as JSON with a code your program can branch on and a message meant for a person to read. The HTTP status tells you what sort of problem it is.

{
  "error": {
    "code": "region_not_licensed",
    "message": "This key does not cover the europe region"
  }
}
StatusCodeWhat it means
401api_key_requiredNo key was sent.
401api_key_invalidThe key is not one of ours, or it has been deleted.
403region_not_licensedThe coordinates fall outside the regions on your plan.
400table_size_exceeds_planThe matrix is larger than your plan allows.
400coordinates_exceed_planToo many points in one route request.
400vehicles_exceed_planToo many vehicles in one optimization.
402quota_exceededThe monthly routing allowance is used up.
402matrix_quota_exceededThe monthly matrix element allowance is used up.
402traffic_not_in_planTraffic profiles are not part of this plan.
400traffic_profile_unknownThe profile named in traffic_profile is not one of yours, or is not live.
429rate_limit_exceededToo many requests in one second or one minute.
429daily_limit_exceededThe daily cap on the free plan has been reached.

A 429 is worth trying again after a short wait. A 402 or a 403 will keep failing until something changes on your account, so retrying those only wastes time.