Push locations
Stream vehicle GPS breadcrumbs in batches — the single input that powers guidance, savings, and events.
Location breadcrumbs are the one input FuelAtlas needs to do everything else. Every recommended stop, savings figure, arrival event, and low-fuel alert is derived from the position (and, ideally, tank level) you stream in. Get this pipe flowing and the rest of the platform lights up.
The endpoint
POST /v1/locations
Authorization: Bearer fa_live_…
FA-Fleet: flt_8Qk2… # partner keys only
Content-Type: application/jsonRequires the locations:write scope. It ingests a batch of breadcrumbs — up to 500 items or 1 MB per request, whichever comes first. Exceed either and the whole request returns 413 batch_too_large; split into smaller batches.
Request body
{
"locations": [
{
"external_ref": "TRUCK-042",
"latitude": 35.1495,
"longitude": -90.0490,
"recorded_at": "2026-07-06T15:04:05Z",
"fuel_level_percent": 48.5,
"speed_mph": 62.0,
"heading_degrees": 91.0,
"driver_ref": "D-7781"
}
]
}| Field | Type | Notes |
|---|---|---|
vehicle_id or external_ref | string | Identify the vehicle by its veh_… id or your own external_ref. Provide one. |
latitude, longitude | number | WGS84 degrees. Required. |
recorded_at | string | RFC 3339 UTC timestamp the reading was taken. Required. |
fuel_level_percent | number | Tank level 0–100. Optional but strongly recommended — it's what makes fuel projections accurate. |
speed_mph | number | Ground speed, mph (converted to km/h on write). Optional. |
heading_degrees | number | 0–360. Optional. |
driver_ref | string | Your driver reference, stamped on the breadcrumb. Optional. |
address | string | Reverse-geocoded address, if you have one. Optional. |
Units are US customary (mph). Identify vehicles by external_ref if you'd rather not store our veh_… ids — the reference you set when creating the vehicle is a first-class lookup key.
Per-item results
The response reports each item independently, keyed by its zero-based index in the request. One bad row never fails the batch — it's rejected on its own while the good rows are accepted.
{
"accepted": 2,
"rejected": 1,
"results": [
{ "index": 0, "status": "accepted" },
{ "index": 1, "status": "accepted" },
{ "index": 2, "status": "rejected", "code": "unknown_vehicle",
"hint": "No matching vehicle found. Create it first with POST /v1/vehicles, or check the id/external_ref." }
]
}code and hint are present only on rejected items. Log the rejects and reconcile — a common cause is a breadcrumb for a vehicle you haven't created yet.
Cadence
Send breadcrumbs on a steady cadence rather than one request per ping:
- Every 1–5 minutes per vehicle is the sweet spot. Guidance recomputes on this rhythm, so more frequent than ~1 minute buys little.
- Batch across your fleet. One
POST /v1/locationswith 400 vehicles' latest positions is far better than 400 single-item calls — it's easier on your rate limit and quota. - Always include
fuel_level_percentwhen you have it. Without a tank level, fuel projections fall back to estimates and guidance can't tell you how many gallons to buy.
Reading a position back
The latest known position for a vehicle is available at:
curl https://api.fuelatlas.com/v1/vehicles/veh_5tR…/location \
-H "Authorization: Bearer fa_live_…"Returns 404 until the first breadcrumb lands. Requires vehicles:manage.