EV Charging & Range Routing
EV Charging & Range Routing
Electric-vehicle adoption across Jordan and the wider GCC has moved from early-adopter curiosity to mainstream choice. Jordan removed special taxes on EVs years before most of its neighbours, and Amman now has one of the highest per-capita EV ratios in the region; Saudi Arabia, the UAE, and Oman are building out fast-charging corridors along their intercity highways as part of national 2030 mobility plans. The result is a fast-growing fleet driving long, sparsely-served desert routes — Amman to Aqaba, Riyadh to the Eastern Province, Dubai to Muscat — where running out of charge is a real operational risk, not a theoretical one.
Generic, globally-trained range routers handle this region poorly: they miss stations that opened last quarter, mis-estimate consumption on long climbs like the Desert Highway descent to the Red Sea, and assume charger density that simply does not exist between cities here. Navvo's EV API is region-native. It draws on a charging-station inventory curated for Jordan and the GCC, and its planner walks the actual Navvo route corridor — inserting a charge stop only when the projected battery state would otherwise fall below your safety reserve before the next reachable charger.
This API has two parts: station discovery (GET /ev/stations) to find chargers in a viewport, and range-aware planning (POST /ev/plan) to turn an A-to-B trip into a feasible journey with the right charge stops in the right places.
{ "lat": number, "lng": number } objects (latitude first). The bbox query parameter on /ev/stations is west,south,east,north. Distances are in kilometres; battery state is expressed in percent. Every response carries provider: "navvo-ev".GET /ev/stations
Discover charging stations inside a map viewport, optionally filtered by minimum charging power. Ideal for drawing chargers on a map, building a station picker, or pre-loading the corridor before planning a trip.
Scope required: places
curl -s "https://navvo.io/api/v1/ev/stations?bbox=35.85,31.90,36.00,32.00&minKw=50&limit=100" \
-H "x-api-key: nvvo_YOUR_KEY"
Query parameters
west,south,east,north (longitude/latitude in decimal degrees). Only stations inside this box are returned.maxKw is at least this value are returned — e.g. minKw=50 for DC fast chargers only. Omit for all power levels.CCS, CHAdeMO, Type2, Tesla, GB/T. Only stations that have at least one connector of this type are returned. Match the plug your vehicle needs.1/true, only currently usable stations are returned — those with an offline / out-of-service / unavailable / broken status are excluded.GET /ev/networks.100, maximum 500. Stations are ordered by maxKw descending so the strongest chargers come first.The response echoes the active filters ({ minKw, connector, availableOnly, network }) so you can confirm what was applied. Filters combine — e.g. ?minKw=50&connector=CCS&available=1 returns only working CCS DC-fast chargers.
Response
{
"provider": "navvo-ev",
"count": 2,
"stations": [
{
"id": "ev_amman_abdali_01",
"name": "Abdali Boulevard Fast Charge",
"network": "Navvo EV Network",
"lat": 31.9566,
"lng": 35.9106,
"connectors": [
{ "type": "CCS2", "kw": 150, "count": 2 },
{ "type": "Type2", "kw": 22, "count": 4 }
],
"maxKw": 150,
"status": "operational",
"pricing": "0.085 JOD/kWh",
"address": "Abdali Boulevard, Amman"
},
{
"id": "ev_amman_mecca_02",
"name": "Mecca Mall Charging Hub",
"network": "Navvo EV Network",
"lat": 31.9667,
"lng": 35.8589,
"connectors": [
{ "type": "CCS2", "kw": 60, "count": 2 },
{ "type": "CHAdeMO", "kw": 50, "count": 1 }
],
"maxKw": 60,
"status": "operational",
"pricing": "0.090 JOD/kWh",
"address": "Mecca Street, Amman"
}
]
}
| Field | Type | Description |
|---|---|---|
provider | string | Always "navvo-ev". |
count | number | Number of stations returned (length of stations). |
stations[].id | string | Stable station identifier. |
stations[].name | string | Display name of the charging site. |
stations[].network | string | Operating network the station belongs to. |
stations[].lat / lng | number | Station coordinates. |
stations[].connectors[] | array | Connector groups: type (e.g. CCS2, Type2, CHAdeMO, GB/T), kw (power per connector), count (how many of that connector). |
stations[].maxKw | number | Highest power available at the site (the strongest connector). Used for filtering and ranking. |
stations[].status | string | "operational", "offline", or "unknown". |
stations[].pricing | string | null | Human-readable price (e.g. "0.085 JOD/kWh"), or null when not published. |
stations[].address | string | Best-known street address. |
minKw=50 to surface only DC fast chargers when you are planning an intercity trip — slow AC chargers (maxKw 7–22) are rarely useful for a highway charge stop.GET /ev/networks
The catalog of charging networks/operators in the dataset, each with its station count and strongest charger — for a "filter by network" UI. Pass a network name to GET /ev/stations?network=.
curl -s "https://navvo.io/api/v1/ev/networks" -H "x-api-key: $NAVVO_API_KEY"
{
"provider": "navvo-ev", "count": 2,
"networks": [
{ "network": "Navvo Charge", "count": 6, "maxKw": 150 },
{ "network": "Desert Power", "count": 2, "maxKw": 120 }
]
}
| Field | Type | Notes |
|---|---|---|
networks[].network | string | operator name ("Unknown" for stations with no network set) |
networks[].count | number | number of stations on that network |
networks[].maxKw | number | the strongest charger on that network |
POST /ev/plan
Range-aware route planning. Given an origin, destination, and your battery range, the planner walks the Navvo route corridor and inserts the strongest nearby charger whenever projected range would drop below the safety reserve. It returns whether the trip is feasible and exactly where to stop.
Scope required: routing
The planner projects battery state along the route. Starting from currentPercent, it consumes range as it walks the corridor; whenever the projected charge would fall below reservePercent before the next reachable charger, it searches within detourKm of the route for the strongest operational station, inserts a stop there, and resumes the projection from a recharged state. If a gap is too long to bridge even from a full charge, the trip is marked infeasible with a reason.
Request body
{ "lat": number, "lng": number }.{ "lat": number, "lng": number }.80.15.5.{
"from": { "lat": 31.9539, "lng": 35.9106 },
"to": { "lat": 29.5321, "lng": 35.0061 },
"rangeKm": 150,
"currentPercent": 80,
"reservePercent": 15,
"detourKm": 5
}
Response
Amman (≈31.95, 35.91) to Aqaba (≈29.53, 35.01) is roughly 330 km down the Desert Highway. With a 150 km full-range vehicle starting at 80% charge and a 15% reserve, a single charge is not enough — the planner inserts two stops to keep the projected battery above reserve the whole way.
{
"provider": "navvo-ev",
"feasible": true,
"chargingNeeded": true,
"totalKm": 330.4,
"stopCount": 2,
"stops": [
{
"station": {
"id": "ev_qatraneh_hwy_07",
"name": "Al-Qatraneh Highway Charge",
"network": "Navvo EV Network",
"lat": 31.2522,
"lng": 36.0489,
"connectors": [ { "type": "CCS2", "kw": 120, "count": 2 } ],
"maxKw": 120,
"status": "operational",
"pricing": "0.095 JOD/kWh",
"address": "Desert Highway, Al-Qatraneh"
},
"atKm": 98.6,
"detourKm": 1.2
},
{
"station": {
"id": "ev_maan_south_14",
"name": "Ma'an South Fast Charge",
"network": "Navvo EV Network",
"lat": 30.1721,
"lng": 35.7330,
"connectors": [ { "type": "CCS2", "kw": 150, "count": 1 }, { "type": "CHAdeMO", "kw": 50, "count": 1 } ],
"maxKw": 150,
"status": "operational",
"pricing": "0.090 JOD/kWh",
"address": "Desert Highway, Ma'an"
},
"atKm": 218.3,
"detourKm": 2.8
}
]
}
| Field | Type | Description |
|---|---|---|
provider | string | Always "navvo-ev". |
feasible | boolean | true if the destination is reachable with the inserted stops; false if a gap cannot be bridged. |
chargingNeeded | boolean | false when the trip fits within the current charge (no stops needed); true otherwise. |
totalKm | number | Total route distance in kilometres. |
stopCount | number | Number of charge stops in stops. |
stops[].station | object | The chosen station — same shape as a GET /ev/stations station object. |
stops[].atKm | number | Distance along the route, in kilometres, at which the stop occurs. |
stops[].detourKm | number | Detour from the route corridor to reach this station (≤ your detourKm). |
reason | string | Present only when feasible is false — explains the failure (e.g. a charger gap longer than the vehicle's full range). |
When the whole trip fits within the current charge, the planner short-circuits:
{
"provider": "navvo-ev",
"feasible": true,
"chargingNeeded": false,
"totalKm": 64.2,
"stopCount": 0,
"stops": []
}
And when a stretch is simply too long to bridge — no operational charger within detourKm of the corridor across a gap larger than rangeKm — the trip is infeasible:
{
"provider": "navvo-ev",
"feasible": false,
"chargingNeeded": true,
"totalKm": 412.0,
"stopCount": 1,
"stops": [ { "station": { "id": "ev_maan_south_14", "name": "Ma'an South Fast Charge", "maxKw": 150, "status": "operational" }, "atKm": 198.4, "detourKm": 2.8 } ],
"reason": "No reachable charger within 5 km of the route for the 210 km stretch after Ma'an; reduce detour constraint or increase rangeKm."
}
currentPercent: 80, reservePercent: 15, detourKm: 5) suit a typical intercity trip. For nervous drivers or commercial fleets, raise reservePercent to 20–25 to build in a bigger buffer; loosen detourKm if the route runs through sparse desert sections where the nearest charger may be a few kilometres off the highway.feasible before presenting a plan to the user. A feasible: false response still returns any stops it could place plus a reason — surface that reason so the driver can adjust (charge more before leaving, allow a longer detour, or pick a higher-range vehicle).Errors
| Status | When |
|---|---|
400 | Validation — e.g. malformed bbox, missing from/to, or a non-positive rangeKm. |
401 / 403 | Missing/invalid key, or the key lacks the required scope (places for stations, routing for planning). |
Summary
| Endpoint | Scope | Body / Query | Returns |
|---|---|---|---|
GET /ev/stations | places | bbox, minKw?, limit? | { provider, count, stations[] } |
POST /ev/plan | routing | { from, to, rangeKm, currentPercent?, reservePercent?, detourKm? } | { provider, feasible, chargingNeeded, totalKm, stopCount, stops[], reason? } |