This is the documentation of version 0.62.3. Go to the latest version, 1.0.0-rc.5.

EV charging stations availability

Request Access

Important note EV Charging Stations Availability is unavailable on a Freemium or Pay As You Grow (PAYG) basis. Click the Request Access button above to contact our Sales team.

The EV Charging Stations Availability service adds real-time status to the electric vehicle charging stations the search services return: the status of each charging point, and counts per connector type and power level.

In the demo below, each searched station shows its free and total charging points under its pin; click one to list its connectors and charging points.

Basic usage

import { discoverPlaces, getPlacesWithEVAvailability } from '@tomtom-org/maps-sdk/services';

// First, search for EV charging stations
const stations = await discoverPlaces({
    query: 'EV charging',
    geoBias: { position: [4.9041, 52.3676] }, // Amsterdam
    filters: { poiCategories: ['CHARGING_LOCATION'] },
    limit: 10
});

// Fetch real-time availability data
const stationsWithAvailability = await getPlacesWithEVAvailability(stations);

How many requests it sends

getPlacesWithEVAvailability sends one request per station, one after the other by default, so a large result set takes as many round trips in series. maxConcurrentRequests lets more of them run at once, and the places come back in their input order either way.

Each request counts against your API key's queries-per-second limit, so raise it only as far as your key allows. The SDK retries a rate-limited (429) request with backoff bounded by retry.timeoutMs in the global configuration, and a request still failing after that leaves its station with unknown availability rather than failing the call.

const stationsWithAvailability = await getPlacesWithEVAvailability(stations, { maxConcurrentRequests: 4 });

Cancelling the availability calls

Pass a signal in the options when a newer search or a map move supersedes it: aborting cancels the in-flight requests, skips the remaining stations and rejects the call with an SDKAbortError, as for any other service call.

createLatestRequest keeps only the newest run: starting one stops the previous one working through its list.

import { createLatestRequest, getPlacesWithEVAvailability } from '@tomtom-org/maps-sdk/services';

const latestAvailability = createLatestRequest();

const showAvailability = async (stations) => {
    const availability = await latestAvailability.run((signal) =>
        getPlacesWithEVAvailability(stations, { signal })
    );
    if (availability.current) await placesModule.show(availability.value);
};

Individual station availability

Get availability for a specific charging station. It takes the same signal, and an abort rejects the call the same way; every other request failure resolves to undefined.

import { getPlaceWithEVAvailability } from '@tomtom-org/maps-sdk/services';

// Get a specific charging station (from search results)
const station = stations.features[0];

const stationWithAvailability = await getPlaceWithEVAvailability(station);
if (stationWithAvailability) {
    const { count, statusCounts } = stationWithAvailability.properties.chargingPark.availability.chargingPointAvailability;
    console.log(`${statusCounts.Available ?? 0} of ${count} charging points available`);
}

A place without a dataSources.chargingAvailability.id resolves to undefined without a request.

Charging stations and points on search results

An EV search result already describes its hardware in place.properties.chargingPark, without real-time status; EV charging stations lists its fields. Only one of a charging point's connectors can charge at a time.

const { chargingPark } = stations.features[0].properties;

chargingPark?.connectors.forEach(({ connector, count }) => {
    console.log(`${count} × ${connector.type}, ${connector.ratedPowerKW} kW (${connector.chargingSpeed})`);
});

chargingPark?.chargingStations?.forEach((chargingStation) => {
    chargingStation.chargingPoints.forEach((point) => {
        const plugs = point.connectors?.map((connector) => connector.type).join(' or ');
        console.log(`${point.evseId ?? chargingStation.id}: ${plugs}`);
        if (point.capabilities.includes('PlugAndCharge')) console.log('  Plug & Charge');

        if (point.restrictions.includes('Customers')) console.log('  customers only');
    });
});

Understanding availability data

getPlaceWithEVAvailability adds chargingPark.availability. A place with no chargingPark of its own, such as a route charging stop, also gets chargingPark.connectors, counted from the availability, but no static chargingStations:

getPlacesWithEVAvailability returns a station whose availability is unknown unchanged, so guard each one with hasChargingAvailability:

import { hasChargingAvailability } from '@tomtom-org/maps-sdk/services';

stationsWithAvailability.features.forEach((station) => {
    const { chargingPark } = station.properties;
    if (!hasChargingAvailability(chargingPark)) return;

    const { accessType, connectorAvailabilities, chargingStations } = chargingPark.availability;
    console.log(`Access: ${accessType}`);

    connectorAvailabilities.forEach(({ connector, count, statusCounts }) => {
        console.log(`${connector.type}, ${connector.ratedPowerKW} kW: ${statusCounts.Available ?? 0}/${count} available`);
    });

    chargingStations.forEach((chargingStation) => {
        chargingStation.chargingPoints.forEach((point) => {
            console.log(`${point.evseId ?? chargingStation.id}: ${point.status}`);
        });
    });
});

Integration with map display

PlacesModule labels each station with its available and total charging points once you enable evAvailability, green when the available share reaches threshold (0.3 unless you set it) and red below it. The station's pin follows the same threshold:

import { PlacesModule } from '@tomtom-org/maps-sdk/map';

const placesModule = await PlacesModule.create(map, {
    evAvailability: {
        enabled: true,
        threshold: 0.3,
        formatText: (available, total) => `${available} of ${total} free`,
    },
});

await placesModule.show(stationsWithAvailability);

Filtering by connector type

Keep the stations with a free connector of the types your vehicle takes:

import { hasChargingAvailability } from '@tomtom-org/maps-sdk/services';

const hasFreeConnector = (station, connectorTypes) =>
    hasChargingAvailability(station.properties.chargingPark) &&
    station.properties.chargingPark.availability.connectorAvailabilities.some(
        ({ connector, statusCounts }) => connectorTypes.includes(connector.type) && (statusCounts.Available ?? 0) > 0,
    );

const compatibleStations = {
    ...stationsWithAvailability,
    features: stationsWithAvailability.features.filter((station) =>
        hasFreeConnector(station, ['IEC62196Type2CCS', 'Chademo']),
    ),
};

Related guides and examples

Related guides

Related examples

Related services