# Integration steps ## Step 1: Implement the linking flows with LinkUI Your app needs to let users link both their vehicle and charger through LinkUI. Your backend requests separate link sessions for each device type. Linking a charger works the same as linking a vehicle. The only difference is the `scopes` you request when generating the token. See [Scopes reference](https://developers.enode.com/api/reference/scopes) for the full list. **Recommended flow:** 1. **Link the vehicle.** Request a `linkToken` with vehicle scopes (`vehicle:read:data`, `vehicle:read:location`, `vehicle:control:charging`). Open LinkUI with this token. See the [LinkUI Developer Guide](https://developers.enode.com/docs/link-ui/introduction) for details. 2. **Prompt for the charger.** After the vehicle links successfully, prompt the user to link their charger. Explain the benefits: smart charging for otherwise incapable vehicles, or improved reliability. See [UX Recommendations](https://developers.enode.com/docs/ev-charger-pairing/integration-considerations#ux-recommendations). 3. **Link the charger.** Request a new `linkToken` with charger scopes (`charger:read:data`, `charger:control:charging`). Open a second LinkUI session. ## Step 2: Set the charging location for chargers Associate the charger with a Location to know where the vehicle is charging. This is useful when the vehicle lacks GPS or when you need to verify charging happens at the user's home. 1. **Create a Location.** `POST` to [`/locations`](https://developers.enode.com/api/reference#createLocation) with the user's coordinates. This returns a `locationId`. 2. **Assign it to the charger.** `PUT` to [`/chargers/{chargerId}`](https://developers.enode.com/api/reference#updateCharger) with the `locationId`. Note: You don't need to assign a Location to the vehicle. When plugged into a charger with a location set, we infer the vehicle's `location.id` from the charger. For vehicles with native GPS, we also return the `locationId` when the vehicle is within 200 m of any Location. ## Step 3: Use the Vehicle API for data and controls Once both devices are linked to the same user, we establish the pair automatically. Data and controls surface through the Vehicle API. ### Basics - `pluggedInChargerId` appears when the vehicle is plugged into a linked charger. It's `null` otherwise. - The vehicle can charge elsewhere (public charging, unlinked chargers). We still return live vehicle data; `pluggedInChargerId` is just `null`. - The Charger API shows the inverse via `pluggedInVehicleId`. ### Unlocked capabilities The paired charger enables capabilities on the vehicle: - `chargeRate` falls back to the charger's value if the vehicle doesn't report it - `startCharging`, `stopCharging`, and `location` become `isCapable: true`. Associated interventions are suppressed. - For vehicles without GPS, location is inferred from the charger These capabilities persist once both devices are linked. We clear them when the pair is no longer valid (for example, after repeated failed commands while unplugged). When plugged back in, the pair re-establishes automatically. ### Sending commands Use the Vehicle API for charging commands: - [Control Charging](https://developers.enode.com/api/reference#postVehiclesVehicleidCharging) to start or stop charging - [Action](https://developers.enode.com/api/reference#getVehiclesAction) endpoint and webhooks to check status Commands work the same whether the vehicle is plugged into the paired charger, a different charger, or unplugged. We route them to the right device. ### Failure reasons When a charging action fails (`FAILED` or `CANCELLED`), the response includes a `failureReason`: - `failureReason.type`: Machine-readable error category - `failureReason.detail`: Human-readable explanation of what went wrong **Example Vehicle API response** ```json {% title="GET /vehicles/{vehicleId}" %} { "id": "05ee9df5-d072-4ee8-b773-399dec8f5693", "userId": "bb28471e-cde6-4eff-ace4-9a7f4f50882a", "vendor": "TESLA", "lastSeen": "2024-01-07T17:04:26.000Z", "isReachable": true, "information": { "vin": "2HGFB2F5XEH542858", "model": "Model S P85", "year": 2020 }, "chargeState": { "batteryLevel": 66, "range": 228, "batteryCapacity": 48.1, // EV Pair: When available, the chargeRate from the charger // is returned if it is not provided by the vehicle "chargeRate": 2.3, "chargeTimeRemaining": 285, "lastUpdated": "2020-04-07T17:04:26Z", "maxCurrent": 16, "powerDeliveryState": "PLUGGED_IN:CHARGING", // EV Pair: Will be "null" when not currently // plugged into a charger "pluggedInChargerId": "07f8368d-be7e-4dbd-8cf0-94d00dd67ad3" }, "capabilities": { "information": { "isCapable": true, "interventionIds": [] }, "chargeState": { "isCapable": true, "interventionIds": [] }, "odometer": { "isCapable": false, "interventionIds": ["4eaeb363-296d-4ccc-a973-7805e6f400bd"] }, "setMaxCurrent": { "isCapable": false, "interventionIds": [] }, // EV Pair: These capabilities are unlocked by the paired charger // and persist across charging sessions "startCharging": { "isCapable": true, "interventionIds": [] }, "stopCharging": { "isCapable": true, "interventionIds": [] }, "location": { "isCapable": true, "interventionIds": [] } } } ``` **Example Charger API response** ```json {% title="GET /chargers/{chargerId}" %} { ... "chargeState": { "isPluggedIn": true, "isCharging": true, "chargeRate": 2.3, "lastUpdated": "2020-04-07T17:04:26Z", "maxCurrent": 16, "powerDeliveryState": "PLUGGED_IN:CHARGING", // EV Pair: Will be "null" when not currently // plugged into a vehicle "pluggedInVehicleId": "05ee9df5-d072-4ee8-b773-399dec8f5693" } ... } ``` **Knowing when the vehicle is plugged in at the correct charging location** Subscribe to [webhooks](https://developers.enode.com/docs/webhooks) for the `user:vehicle:updated` event to receive notifications when vehicle state changes. When `pluggedInChargerId` and the expected `location.id` are returned, the vehicle is plugged in at the correct charging location. ## Step 4: Handle unified interventions [Interventions](https://developers.enode.com/docs/interventions) are user actions that unlock device capabilities. With EV Charger Pairing, the Vehicle API returns interventions from both the vehicle and charger. You don't need to query the Charger API separately. ### How interventions appear The Vehicle API response includes interventions from the vehicle and all linked chargers: - Charger interventions that unlock control or location capabilities appear first - If the charger can provide a capability, we suppress the vehicle's intervention for that capability - Interventions affecting `chargeState` from either device are always returned ### Optional interventions Sometimes a vehicle can control charging on its own, but the linked charger cannot. In this case: - `isCapable` remains `true` on the vehicle - We return the charger's interventions anyway, marked as optional Show optional interventions as recommended but not blocking. ### Presenting interventions to users 1. Fetch interventions from `capabilities.*.interventionIds` 2. Show them in the order returned 3. Subscribe to `user:vehicle:updated` [webhooks](https://developers.enode.com/docs/webhooks) for changes [Read next: Testing your integration](https://developers.enode.com/docs/ev-charger-pairing/integration-testing)