Skip to content
Last updated

Onboarding vehicles, EVSEs and inverters

This article explains how to connect your users to their hardware. You will first need to create a user, which is described here.

This guide covers three onboarding flows:

  • Vehicle onboarding — 3-level hierarchy: make → model → trim
  • EVSE onboarding — 2-level hierarchy: make → model (no trims)
  • Inverter onboarding — follows the same 2-level pattern as EVSE onboarding

The vehicle flow is documented first in full detail. The EVSE section follows — it uses the same pattern but is simpler.

Custom onboarding selector

Requirements

To begin you will need:

  • A valid Authorization token (see this page for instructions)
  • An onboarding redirect URL configured on your account. If you're not sure if this is done, contact developers@ev.energy.
  • Your OAuth2 client_id, as provided during initial setup (see Authentication).
  • An ID for a user in the system which you have access to, see here.

User header

In order for the API to automatically construct onboarding urls for the correct user, you must tell it which user you are onboarding. For each of the following requests, ensure you have set the EvEnergy-User header to the user ID of the correct user:

EvEnergy-User: user01J4459WYAFXJH187M7XJ5FY6A

Vehicle onboarding

Select a make

Request the list of vehicle makes from /vehicle_makes. Show each of these to your user and have them select the right one. You can use the icon field to include a logo image to aid selection.

The individual resource for the make will look something like this:

{
    "id": "vmak01HN2P75GBNFRJPCZJXEFVXH5E",
    "url": "https://api.ev.energy/v2/vehicle_makes/vmak01HN2P75GBNFRJPCZJXEFVXH5E",
    "name": "Volvo",
    "icon": "https://cdn.example.com/volvo.png",
    "onboarding_url": "https://api.ev.energy/v2/vehicle_onboarding?make_id=vmak01HN2P75GBNFRJPCZJXEFVXH5E&user_id=user01J4459WYAFXJH187M7XJ5FY6A",
    "models": "https://api.ev.energy/v2/vehicle_models?make_id=vmak01HN2P75GBNFRJPCZJXEFVXH5E"
}

If onboarding_url is not null, then great, you've got all the information you need to initiate onboarding. Take the URL and jump to the "Initiate Onboarding" section below!

If onboarding_url is null, then for that make of vehicle we need more information before we can continue. Take the url from the models field and go to the next step:

Select a model

You now need to repeat the process above but for models instead of makes. The previous step will have provided you with a models url, which is a link to the /vehicle_models collection filtered to only return models for the make selected by the user.

{
    "id": "vmod01HN2P436099PEQ20B7TKPGTEJ",
    "url": "https://api.ev.energy/v2/vehicle_models/vmod01HN2P436099PEQ20B7TKPGTEJ",
    "name": "C40",
    "make": "https://api.ev.energy/v2/vehicle_makes/vmak01HN2P75GBNFRJPCZJXEFVXH5E",
    "onboarding_url": "https://api.ev.energy/v2/vehicle_onboarding?model_id=vmod01HN2P436099PEQ20B7TKPGTEJ&user_id=user01J4459WYAFXJH187M7XJ5FY6A",
    "trims": "https://api.ev.energy/v2/vehicle_trims?model_id=vmod01HN2P436099PEQ20B7TKPGTEJ"
}

Request that URL and show the resulting list to your user. Once they select a model, check the onboarding_url field. If it is a url jump to the "Initiate Onboarding" section below. If it is null, then we still don't have enough information. Grab the url from the trims field and continue.

Select a trim

Repeat the process one last time. The link from the previous step's trims field is the url for /vehicle_trims collection, filtered to just trims for the selected model.

{
  "id": "trim01HN2NZ1040Y8E77CQGXADC2TZ",
  "url": "https://api.ev.energy/v2/vehicle_trim/trim01HN2NV5DY9C262PQKG75GHN8K",
  "name": "Recharge Core (69 kWh)",
  "model": "http://example.com",
  "onboarding_url": "https://api.ev.energy/v2/vehicle_onboarding?trim_id=trim01HN2NZ1040Y8E77CQGXADC2TZ&user_id=user01J4459WYAFXJH187M7XJ5FY6A&client_id=your_client_id"
}

Request that URL and show the resulting list to your user. Once they select their trim, check the onboarding_url field. If it is a url jump to the "Initiate Onboarding" section below.

If it is null, then we are currently unable to integrate with that vehicle. Instead, we must create an "Unintegrated vehicle" in the system by POSTing to the /vehicles endpoint with {"model": "<model_url>", "battery_size_watt_hours": 60000}. battery_size_watt_hours is optional; if omitted, the backend uses the default for that model and marks the battery size as estimated. description may also be provided as a human-readable label. The backend resolves or creates a hidden trim under the hood.

EVSE onboarding

EVSE onboarding follows the same pattern as vehicle onboarding but with only two levels (make and model — there are no trims).

Select a make

Request the list of EVSE makes from /evse_makes. Show each of these to your user and have them select the right one.

The individual resource for the make will look something like this:

{
    "id": "emak01HS8FRXKJD5JZZ7ZN6W8H21P8",
    "url": "https://api.ev.energy/v2/evse_makes/emak01HS8FRXKJD5JZZ7ZN6W8H21P8",
    "name": "BG SyncEV",
    "display_name": "BG SyncEV",
    "icon": "https://cdn.example.com/syncEV.png",
    "onboarding_url": "https://api.ev.energy/v2/evse_onboarding?make_id=emak01HS8FRXKJD5JZZ7ZN6W8H21P8&user_id=user01J4459WYAFXJH187M7XJ5FY6A",
    "is_beta": false,
    "evse_models": "https://api.ev.energy/v2/evse_models?make_id=emak01HS8FRXKJD5JZZ7ZN6W8H21P8"
}

If onboarding_url is not null, take the URL and jump to the "Initiate Onboarding" section below.

If onboarding_url is null, take the url from the evse_models field and go to the next step:

Select a model

The previous step will have provided you with an evse_models url, which is a link to the /evse_models collection filtered to only return models for the make selected by the user.

{
    "id": "emod01HS9A004X5TB5JCMHENB5Z446",
    "url": "https://api.ev.energy/v2/evse_models/emod01HS9A004X5TB5JCMHENB5Z446",
    "name": "EVWC2S22",
    "make": "https://api.ev.energy/v2/evse_makes/emak01HS8FRXKJD5JZZ7ZN6W8H21P8",
    "display_name": "EVWC2S22",
    "onboarding_url": "https://api.ev.energy/v2/evse_onboarding?model_id=emod01HS9A004X5TB5JCMHENB5Z446&user_id=user01J4459WYAFXJH187M7XJ5FY6A"
}

Show the models to your user. Once they select a model, check the onboarding_url field. If it is a url, jump to the "Initiate Onboarding" section below.

If it is null, then we are currently unable to integrate with that EVSE.

Note: There is no trim level for EVSEs — the hierarchy stops at model. This is the key simplification versus vehicle onboarding.

Import by serial number

Some EVSE providers (Wallbox, Easee, Zaptec, ChargePoint, EO, SyncEV, EnelX) onboard by serial number rather than via the OAuth onboarding_url flow — the user types the device's CPID/serial and we look it up at the provider using the authenticated user's email. Post the serial number to POST /v2/evse_onboarding/import:

curl --request POST \
     --url https://api.ev.energy/v2/evse_onboarding/import \
     --header 'authorization: Bearer <token>' \
     --header 'content-type: application/json' \
     --data '{"provider": "Wallbox", "serial_number": "WBX-12345678"}'

A 201 response carries the freshly created EVSE in the same shape as GET /v2/evses/{evse_id}, already linked to the authenticated user. Errors map to RFC 9457 problem responses: 404 evse-not-found-at-provider when the provider has no matching device, 422 evse-already-imported when the EVSE is already in our database, 422 evse-import-failed for unsupported providers or generic provider errors.

Initiate Onboarding

Send your user to the onboarding_url you got from the previous step. This could be in a web browser (which is also the easiest way for you to try it out yourself) or in an embedded web view in a mobile app. It should not be in an iframe embedded in a web page, as some of our third party providers do not function correctly within an iframe.

Important: The onboarding_url points to an API endpoint (e.g. /v2/vehicle_onboarding or /v2/evse_onboarding) which responds with a 302 redirect. The Location header in this redirect is a root-relative path such as /vehicle-onboarding/start/<uuid> or /evse-onboarding/start/<uuid>. This path is not under /v2/ — do not prepend /v2/ to it. Browsers and webviews will follow the redirect automatically.

Native mobile clients (response_type=json)

If your mobile app needs to decide between launching a provider's native SDK (e.g. Smartcar Connect for BMW/MINI) and opening a WebView before navigating to the onboarding URL, append &response_type=json to the vehicle onboarding_url. The endpoint then returns 200 with a JSON payload instead of a 302 redirect:

{
    "authorization_request_id": "4d4ce3d9-8a16-46a8-99e1-3f3f9b8a3a5b",
    "url": "https://connect.smartcar.com/oauth/authorize?...",
    "auth_method": "native",
    "scopes": ["read_vehicle_info", "read_charge", "control_charge"],
    "single_select": true
}
  • Open url in a WebView when auth_method is "api".
  • Hand url, scopes and single_select to the provider's native SDK when auth_method is "native".

The JSON variant requires at least one of make_id, model_id or trim_id (it does not fall back to the make-picker screen).

EVSE onboarding (/v2/evse_onboarding) supports the same &response_type=json toggle but with a smaller payload — only url (no auth_method/scopes/single_select, since no EVSE provider currently exposes a native SDK). The URL is the absolute onboarding wrapper that you open in a WebView (mobile) or redirect the browser to (web). Like the vehicle variant, the JSON path requires at least one of make_id or model_id.

{
    "url": "https://api.ev.energy/evse-onboarding/start/abc12345-..."
}
Completing the native SDK flow (POST /v2/vehicle_onboarding/complete/)

When the SDK returns an auth_code, exchange it for the list of created vehicles by POSTing to /v2/vehicle_onboarding/complete/:

{
    "authorization_request_uid": "<the authorization_request_id returned by init>",
    "auth_code": "<code returned by the SDK>"
}

The endpoint always returns an array — even when only one vehicle is created — and you can fetch each vehicle's details via GET /v2/vehicles/{id} using the IDs from the response. Like the init endpoint, no OAuth bearer token is required: the authorization_request_uid itself binds the call to the originating onboarding session.

Connect a vehicle

The user will be prompted to pick their vehicle manufacturer. Based on their choice and their location, we will then redirect them to the appropriate log-in service for their vehicle. They will need to enter their credentials and grant access to their account. The exact steps here vary quite a lot between manufacturers but we will guide the user through the process.

Connect an EVSE

The user will be guided through connecting their charger. Depending on the manufacturer, this may involve entering their charger's serial number or CPID, connecting via OAuth, or configuring a WiFi connection. We will guide the user through the process.

Finishing up

Once the user's hardware is set up in our system, we will redirect their browser (or webview) back to your onboarding redirect url with a query parameter identifying the new resource.

For vehicles, if your redirect url was https://example.com/redirect, we would send them to:

https://example.com/redirect?vehicle_id=vhcl01HN2NV5DY9C262PQKG75GHN8K

Your client can extract the vehicle_id query parameter to get the ID of the new Vehicle.

For EVSEs, we would send them to:

https://example.com/redirect?evse_id=12345

Your client can extract the evse_id query parameter to get the ID of the new EVSE. Note that the EVSE ID returned here is an integer database ID, not the ULID format used elsewhere in the v2 API.

If onboarding fails, the user will be redirected with a failure indicator:

https://example.com/redirect?failure=true

Summary

Vehicle onboarding flow

Yes

No

Yes

No

Yes

No

Select make

onboarding_url is null?

Select model

Initiate onboarding

onboarding_url is null?

Select trim

onboarding_url is null?

Create unintegrated vehicle

User has a vehicle

Yes

No

Yes

No

Yes

No

Select make

onboarding_url is null?

Select model

Initiate onboarding

onboarding_url is null?

Select trim

onboarding_url is null?

Create unintegrated vehicle

User has a vehicle

EVSE onboarding flow

Yes

No

Yes

No

Select EVSE make

onboarding_url is null?

Select EVSE model

Initiate onboarding

onboarding_url is null?

EVSE not supported

User has an EVSE

Yes

No

Yes

No

Select EVSE make

onboarding_url is null?

Select EVSE model

Initiate onboarding

onboarding_url is null?

EVSE not supported

User has an EVSE