localEV.
FOR EV APPS AND INTEGRATORS

Nearby chargers API

A read-only endpoint that returns shared, host-listed EV chargers near any location, sorted by distance. EV navigation apps, dashboards and assistants can call it directly — no account or key needed today.

Endpoint

One endpoint, GET only. Send the caller's location and get back the closest active host chargers.

GET /api/public/chargers/nearby
Base URL: this API is served by this site — send requests to this domain, e.g. https://neighbor-charge-network.lovable.app/api/public/chargers/nearby.

Query parameters

All parameters are sent as URL query strings.

ParameterRequiredRangeDescription
latYes−90 to 90Latitude of the search origin, in decimal degrees.
lngYes−180 to 180Longitude of the search origin, in decimal degrees.
radius_kmNoDefault 10, max 50Search radius in kilometres. Anything above 50 is rejected.
connectorNoSee belowOnly return chargers with this plug type.
limitNo1–50, default 20Maximum number of results returned.

Accepted connector values: Type 2CCS2CHAdeMOType 1Standard power point

Filters at a glance

  • Distance — results are sorted nearest first and cut off at radius_km.
  • Plug type — exact match on the host's listed connector, e.g. connector=CCS2.
  • Speed and price — returned in every result (power_kw, price) so your app can filter or rank client-side.
  • Open now — every result includes an open_now flag calculated against the host's opening hours (Australian Eastern time).

Example request

curl "https://neighbor-charge-network.lovable.app/api/public/chargers/nearby?lat=-27.4698&lng=153.0251&radius_km=15&connector=Type%202&limit=5"

Example response

HTTP 200, application/json. Distances are rounded to 0.1 km.

{
  "count": 1,
  "location_precision": "suburb",
  "results": [
    {
      "id": "9f1c2a44-1b3e-4c55-9a7b-2d6f0e8c1234",
      "name": "West End driveway charger",
      "suburb": "West End",
      "approx_lat": -27.4821,
      "approx_lng": 153.0123,
      "distance_km": 1.4,
      "connector": "Type 2",
      "current_type": "AC",
      "power_kw": 7,
      "price": { "amount_cents": 30, "currency": "AUD", "unit": "kwh" },
      "open_now": true,
      "availability": "host-confirmed on request",
      "book_url": "https://neighbor-charge-network.lovable.app/chargers/9f1c2a44-1b3e-4c55-9a7b-2d6f0e8c1234"
    }
  ]
}
FieldDescription
countNumber of results in this response (may be less than the limit).
location_precisionAlways suburb — coordinates are deliberately approximate.
approx_lat / approx_lngApproximate charger position, suitable for map pins at suburb zoom.
distance_kmGreat-circle distance from the request origin, in kilometres.
priceHost's listed rate in Australian cents: per kWh (unit: "kwh") or per hour (unit: "hour").
open_nowWhether the charger is inside the host's opening hours right now.
availabilityAlways host-confirmed on request — this is not a live socket status.
book_urlDeep link to the charger page where a driver can request a session.

Errors

StatusWhenBody
400Missing or out-of-range parameters.{ "error": "Invalid query", "issues": { ... } } — issues names each bad parameter.
429Rate limit exceeded. Wait for Retry-After seconds, then retry.{ "error": "Too many requests", "retry_after_seconds": 42 }
503The listing service is temporarily unavailable. Retry with backoff.{ "error": "Unavailable" }

Rate limits and retries

  • 60 requests per minute per caller IP address, counted in fixed one-minute windows.
  • Every response carries RateLimit-Limit, RateLimit-Remaining and RateLimit-Reset (seconds until the window resets). These headers are readable from browser apps.
  • Over the limit you get 429 with a Retry-After header in seconds. Wait that long before retrying — don't hammer.
  • On 503 or network errors, retry with exponential backoff and jitter: about 1s, 2s, 4s, up to 30s, then stop after 5 attempts.
  • Never retry a 400. Fix the query parameters instead.
  • Best-effort today. Limits are enforced per server instance, so exact counts can vary slightly. Design for the published numbers, not the edge cases.
async function nearby(url, attempt = 0) {
  const res = await fetch(url);
  if (res.status === 429) {
    const wait = Number(res.headers.get("Retry-After") ?? 60);
    await new Promise(r => setTimeout(r, wait * 1000));
    return nearby(url, attempt + 1);
  }
  if (res.status === 503 && attempt < 5) {
    const wait = Math.min(30, 2 ** attempt) * 1000 * (0.5 + Math.random());
    await new Promise(r => setTimeout(r, wait));
    return nearby(url, attempt + 1);
  }
  return res.json();
}

Privacy limits

  • Host addresses are never exposed. The endpoint returns suburb-level coordinates only — enough for a map pin, never a street address.
  • Exact addresses unlock one way: a host reveals their address only after they accept a specific driver's booking request, inside the app.
  • Only active listings are returned. Paused or removed chargers disappear from responses immediately.
  • No personal data: responses contain no host names, contact details or booking information.

Integrating with an EV app

  • CORS is open. Browser apps can call the endpoint directly from JavaScript; server-side calls work the same way.
  • Cache for 60 seconds. Responses include Cache-Control: public, max-age=60 — respect it instead of polling faster.
  • Poll on arrival, not continuously. A good pattern is one query when a driver starts looking for a charge, and a refresh every few minutes while searching.
  • Send drivers to book_url. Sessions are confirmed by the host, so real-time availability is not guaranteed until a request is accepted.
  • Show prices as estimates. price is the host's listed rate; the final amount is agreed in the app.
  • Handle an empty list gracefully. New areas may have no host chargers yet — count: 0 is a normal response.
No API key required today. The endpoint is open while the network is small, within the rate limits above. If API keys are introduced later, they will be documented on this page first.