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.

EndpointsScope
GET /ev (paged list), GET /statusnone
GET /ev/search?query=…evkx:external:search
/ev/{id}/summary: the headline figures in one compact objectevkx:external:summary
/ev/{id}/battery: packs and measured charge curvesevkx:external:battery
/brand, /modelinfo (incl. prices and markets)evkx:external:identity
/drivetrain, /motors, /performance, /charging, /range, /suspension, /brakesevkx:external:drivetrain
/dimensions, /transport, /exterior, /lightsevkx:external:body
/interior, /comfort, /infotainment, /ui, /appevkx:external:cabin
/safety, /security, /assistance, /aievkx:external:safety
/ev/{id}: the whole vehicleevkx: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

  1. 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.
  2. To get a token, sign a short-lived JWT with your private key: RS256, iss = your client id, exp a few minutes ahead. Post it as the form field assertion:
    curl -X POST "https://evkx.net/api/external/v1/auth/token" \
      --data-urlencode "assertion=$ASSERTION"
    The answer holds an access_token, valid for 10 hours:
    { "access_token": "eyJ…", "token_type": "Bearer", "expires_in": 36000 }
  3. 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 429 with a Retry-After header 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

StatusMeaningBody
400A 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
401No token, or one that is invalid or expired. Get a new token.empty
403A valid token without the scope this endpoint needs, for example a cabin token asking for /dimensions.empty
404Unknown or unpublished vehicle, or one outside your regional scope. These are indistinguishable on purpose.JSON, EV_NOT_FOUND
429Over the rate limit. Wait for Retry-After seconds.JSON, RATE_LIMITED
503Market 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, zeroToHundredKphSeconds and maxDcChargeSpeedKw belong to the standard battery, the same one netBatteryCapacityKwh describes. They used to mix the best of every battery, so on those vehicles some values go down. batterySummaries and the performance and range sections still give each battery. No fields changed.
  • 2026-11-01: New optional batteryId on prices: the id of the battery a price buys. On a vehicle with several batteries, an absent batteryId means 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 batteryId on performance and range rows: the id of the battery a row belongs to. We are adding these links over the coming weeks, so until then an absent batteryId on 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: basicTrimEpaRangeKm and topTrimEpaRangeKm in the range and consumption section now carry kilometres, as documented. Until now they carried EPA's mile figure unconverted. New fields basicTrimEpaRangeMi and topTrimEpaRangeMi carry the miles as EPA publishes them. If you converted the old value yourself, read the …Mi fields 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 (pageSize 1–100).
  • 2026-10-21: List and search items carry bodyType and modelStatus. The error and status bodies are named ErrorResponseDto and ApiStatusDto in 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) and full open the per-section endpoints for every published vehicle; before, they served only the two test vehicles. Per-client rate limits (429 with Retry-After) and five-minute private caching.
  • 2026-10-10: Regional scopes (…:europe and the other regions) for search, summary and battery. Tokens carry the client id. The unversioned /api/export/jscurves endpoint was removed; charge curves come from /summary and /battery.
  • 2026-07-16: Scoped tokens for search, summary and battery, covering the whole published catalogue.
Mere information