Recipes
Ready-made building blocks for the things every integration needs — authenticating once, paginating through a list, and streaming a full history. Copy, paste, and wire in your keys.
A tiny API client
Set the two key headers once, then call any path. It unwraps the response envelope and throws on any non-2xx so your own code only ever sees data.
JavaScript
const BASE = "https://api.lucideld.com";
const headers = {
"X-API-Provider-Key": process.env.PROVIDER_KEY,
"X-API-Company-Key": process.env.COMPANY_KEY,
};
// GET a path and unwrap the envelope. Throws on any non-2xx.
async function api(path) {
const res = await fetch(BASE + path, { headers });
const body = await res.json();
if (!res.ok) throw new Error(res.status + " " + (body.description || res.statusText));
return body; // { description, data, page, total_pages, ... }
} Python
import os, requests
BASE = "https://api.lucideld.com"
HEADERS = {
"X-API-Provider-Key": os.environ["PROVIDER_KEY"],
"X-API-Company-Key": os.environ["COMPANY_KEY"],
}
def api(path):
"""GET a path and unwrap the envelope. Raises on any non-2xx."""
res = requests.get(BASE + path, headers=HEADERS, timeout=30)
body = res.json()
if not res.ok:
raise RuntimeError(f"{res.status_code} {body.get('description', res.reason)}")
return body # {"description", "data", "page", "total_pages", ...}Fetch every page
Most list endpoints (drivers, vehicles, statuses) are page-based. Loop from page 1 and stop once you reach total_pages. Reuses the api() helper above.
JavaScript
// Walk every page of a list endpoint and collect all records.
async function fetchAll(path, limit = 100) {
const all = [];
for (let page = 1; ; page++) {
const sep = path.includes("?") ? "&" : "?";
const body = await api(path + sep + "page=" + page + "&limit=" + limit);
all.push(...body.data);
if (page >= body.total_pages) break;
}
return all;
}
const drivers = await fetchAll("/v2/drivers"); Python
def fetch_all(path, limit=100):
"""Walk every page of a list endpoint and collect all records."""
records, page = [], 1
while True:
sep = "&" if "?" in path else "?"
body = api(f"{path}{sep}page={page}&limit={limit}")
records.extend(body["data"])
if page >= body["total_pages"]:
break
page += 1
return records
drivers = fetch_all("/v2/drivers")Stream all location history
Vehicle Location History is token-based, not page-based. Pass the next_page_token from each response until it stops coming back. Yielding keeps memory flat over a six-month range.
JavaScript
// Page through location history with the next_page_token cursor.
async function* locationHistory(vehicleId, startDate, endDate) {
let token = null;
do {
const params = new URLSearchParams({
start_date: startDate,
end_date: endDate,
limit: "1000",
});
if (token) params.set("next_page_token", token);
const body = await api("/v2/vehicle-location-history/" + vehicleId + "?" + params);
yield* body.data;
token = body.next_page_token || null;
} while (token);
}
for await (const ping of locationHistory(vehicleId, "03-30-2026", "04-01-2026")) {
// ping.lat, ping.lng, ping.timestamp, ...
} Python
from urllib.parse import urlencode
def location_history(vehicle_id, start_date, end_date):
"""Yield every GPS breadcrumb across the token-paginated pages."""
token = None
while True:
params = {"start_date": start_date, "end_date": end_date, "limit": 1000}
if token:
params["next_page_token"] = token
body = api(f"/v2/vehicle-location-history/{vehicle_id}?{urlencode(params)}")
yield from body["data"]
token = body.get("next_page_token")
if not token:
break
for ping in location_history(vehicle_id, "03-30-2026", "04-01-2026"):
... # ping["lat"], ping["lng"], ping["timestamp"]Staying in sync
The API is polling-based. Refresh the latest-status
endpoints on an interval matched to how often the data actually moves — motion data refreshes roughly every 60 seconds,
so polling faster just returns the same values. Back off when you get a
429. See
Errors for the full list.