EVKX API for developers
Electric vehicle specifications, batteries and charge curves for your product: try the EVKX API in a minute, then get a key.
The EVKX API serves the same curated data as this site: identity, prices and markets, drivetrain and batteries with measured charge curves, range, dimensions, interior, safety and more, for every published electric vehicle. It is read-only JSON over HTTPS, and it is in beta (see Versioning).
Full reference, with every field and a live "Try it out": the API reference.
Try it now, no key needed
The vehicle list is open, and two test vehicles answer every per-vehicle endpoint without a key.
curl "https://evkx.net/api/external/v1/ev?pageSize=5"
curl "https://evkx.net/api/external/v1/ev/80822ada-ddf9-4f9c-8165-010e4695cba1/summary"
curl "https://evkx.net/api/external/v1/ev/80822ada-ddf9-4f9c-8165-010e4695cba1/dimensions"
The two test vehicles are the Audi S6 Avant e-tron (80822ada-ddf9-4f9c-8165-010e4695cba1) and the
Mercedes EQA 250+ (794466b7-b421-4e3c-abed-42a0f0028437). Every other
vehicle needs a key with the right scope.
What you can read
Base URL: https://evkx.net/api/external/v1. Vehicles are addressed by their EVKX id (a GUID), which the list and search return.
| Endpoints | Scope |
|---|---|
GET /ev (paged list), GET /status | none |
GET /ev/search?query=… | evkx:external:search |
/ev/{id}/summary: the headline figures in one compact object | evkx:external:summary |
/ev/{id}/battery: packs and measured charge curves | evkx:external:battery |
/brand, /modelinfo (incl. prices and markets) | evkx:external:identity |
/drivetrain, /motors, /performance, /charging, /range, /suspension, /brakes | evkx:external:drivetrain |
/dimensions, /transport, /exterior, /lights | evkx:external:body |
/interior, /comfort, /infotainment, /ui, /app | evkx:external:cabin |
/safety, /security, /assistance, /ai | evkx:external:safety |
/ev/{id}: the whole vehicle | evkx:external:full |
evkx:external:full also opens every per-vehicle endpoint above. A scope can be
limited to a region (evkx:external:summary:europe; regions are africa, americas,
asia, europe and oceania): you then read the vehicles that have been offered there. Only
published vehicles are served.
Getting a key
- Contact us with what you are building. We agree the scopes you need and register your client: you send us a public key (an RSA key as JWK) and we give you a client id.
-
To get a token, sign a short-lived JWT with your private key: RS256,
iss= your client id,expa few minutes ahead. Post it as the form fieldassertion:
The answer holds ancurl -X POST "https://evkx.net/api/external/v1/auth/token" \ --data-urlencode "assertion=$ASSERTION"access_token, valid for 10 hours:{ "access_token": "eyJ…", "token_type": "Bearer", "expires_in": 36000 } -
Send the token on every request:
curl -H "Authorization: Bearer $TOKEN" \ "https://evkx.net/api/external/v1/ev/search?query=ioniq"
Keep the private key on your server. A key that leaks can read everything your scopes allow; tell us and we replace it.
Limits and caching
- 600 requests a minute per registered client, and 60 a minute per IP address without a key.
- Over the limit you get
429with aRetry-Afterheader in seconds. Wait that long and continue. - Per-vehicle responses may be cached for five minutes (
Cache-Control: private, max-age=300). Vehicle data changes slowly; a daily or weekly sync is plenty for most products.
Status codes
| Status | Meaning | Body |
|---|---|---|
400 | A malformed request: a parameter that is not a number or an id, or a search query under 2 characters. | JSON: validation problem details, or INVALID_QUERY |
401 | No token, or one that is invalid or expired. Get a new token. | empty |
403 | A valid token without the scope this endpoint needs, for example a cabin token asking for /dimensions. | empty |
404 | Unknown or unpublished vehicle, or one outside your regional scope. These are indistinguishable on purpose. | JSON, EV_NOT_FOUND |
429 | Over the rate limit. Wait for Retry-After seconds. | JSON, RATE_LIMITED |
503 | Market data is briefly unavailable, so a regional scope cannot be checked. Retry later. | JSON, MARKET_DATA_UNAVAILABLE |
A JSON error has an error message and a stable code; read the status first, and parse the body only when there is one.
Versioning and stability
The API is versioned in the path. Within v1:
- Changes are additive. We add endpoints, fields and enum values; we do not remove or rename them, or change their meaning or type. Ignore fields you do not know.
- Enum fields are open sets. New values can appear at any time; treat a value you do not recognise as
Unknown. Values are never removed or renamed within v1. - Breaking changes ship as v2. v1 keeps working for at least six months after v2 is announced, and registered clients hear from us directly.
Beta: until the beta ends, scopes, limits and these terms may still change. Registered clients are told before a change that affects them. Every change to the API is listed in the changelog.
Terms of use
- Attribution. Where you show EVKX data, credit it as Data: EVKX.net with a link to evkx.net (or to the vehicle's page on it).
- No resale of the data itself. Use it in your product. Do not sell, publish or share the raw data as a dataset or bulk export, or use it to build a competing vehicle database.
- One key per integration, kept private. We may suspend a key that is abused or shared, or that keeps exceeding the limits.
- As is. We work hard to keep the data correct, but give no warranty. If you find an error, tell us and we fix it for everyone.
Changelog
- 2026-11-05: Summary figures now describe one car on a vehicle with several batteries.
wltpRangeKm,wltpConsumptionKwh100km,epaRangeMi,cltcRangeKm,maxPowerKw,topSpeedKph,zeroToHundredKphSecondsandmaxDcChargeSpeedKwbelong to the standard battery, the same onenetBatteryCapacityKwhdescribes. They used to mix the best of every battery, so on those vehicles some values go down.batterySummariesand the performance and range sections still give each battery. No fields changed. - 2026-11-01: New optional
batteryIdon prices: theidof the battery a price buys. On a vehicle with several batteries, an absentbatteryIdmeans the battery is not known, so do not assume a particular one. We are adding these links over the coming weeks. - 2026-11-01: New optional
batteryIdon performance and range rows: theidof the battery a row belongs to. We are adding these links over the coming weeks, so until then an absentbatteryIdon a vehicle with several batteries usually means the battery is not known yet. Do not assume a row applies to all batteries, and do not pair rows and batteries by position. - 2026-10-22: Fix:
basicTrimEpaRangeKmandtopTrimEpaRangeKmin the range and consumption section now carry kilometres, as documented. Until now they carried EPA's mile figure unconverted. New fieldsbasicTrimEpaRangeMiandtopTrimEpaRangeMicarry the miles as EPA publishes them. If you converted the old value yourself, read the…Mifields instead. - 2026-10-21: The reference marks the fields the API always sends as required (ids, the paging envelope, the error, status and token bodies) and shows the paging bounds (
pageSize1–100). - 2026-10-21: List and search items carry
bodyTypeandmodelStatus. The error and status bodies are namedErrorResponseDtoandApiStatusDtoin the reference; their JSON is unchanged. Every endpoint in the reference has an example to run, and the reference lists only responses the API sends: 401 and 403 without a body, and no 406. - 2026-10-21: Section scopes (
identity,drivetrain,body,cabin,safety) andfullopen the per-section endpoints for every published vehicle; before, they served only the two test vehicles. Per-client rate limits (429 withRetry-After) and five-minute private caching. - 2026-10-10: Regional scopes (
…:europeand the other regions) for search, summary and battery. Tokens carry the client id. The unversioned/api/export/jscurvesendpoint was removed; charge curves come from/summaryand/battery. - 2026-07-16: Scoped tokens for search, summary and battery, covering the whole published catalogue.