Sandbox
You do not need a dashcam to start. A test key returns a complete demo fleet — 12 vehicles, safety events, trips, GPS tracks, geofences and playable video — from the same endpoints, in the same shapes, that live keys use.
Build the integration today; swap one key when the hardware arrives.
Test keys
Test keys start with flt_test_ and are safe to paste anywhere — into a
terminal, a shared repo, a support ticket. They reach no customer data.
| Key | Tier | What it unlocks |
|---|---|---|
flt_test_free_00000000000000000001 | free | 1 scope — the smallest surface |
flt_test_starter_00000000000000000001 | starter | 4 scopes |
flt_test_standard_0000000000000001 | standard | 6 scopes |
flt_test_pro_00000000000000000001 | pro | 13 scopes — webhooks, media |
flt_test_ent_0000000000000000001 | enterprise | 15 scopes — everything |
These same keys run the reference demo app as-is — a nine-screen app built on this API, with nothing to configure.
Use them exactly like a live key:
curl "https://openapi.fleeta.io/v1/devices?perPage=5" \
-H "Authorization: Bearer flt_test_ent_0000000000000000001"
Scopes and rate limits follow the tier, so testing with the enterprise key
and shipping on standard will surprise you at the worst moment. Use the key
that matches your plan and you will hit the same 403 insufficient_scope
in development that you would hit in production.
What the demo fleet contains
| Vehicles | 12 — 10 cloud-connected + 2 Wi-Fi-only · 5 driving, 4 parked, 3 offline |
| Groups | grp_north (5) · grp_south (5) · 2 unassigned |
| Events | 16 of the 18 safety event types — 15 recording types plus three server-judged speed_limit violations (no clip; no calling / smoking sample) — spread across recent days |
| Trips & tracks | GPS traces you can draw on a map |
| Geofences | Circles and polygons, with enter/exit alerts |
| Video & thumbnails | Playable clips for front, rear and interior |
Three details are deliberate, because real fleets look like this:
- Three vehicles are offline, one of them for over two months. A fleet where every camera is online is not a fleet you can test against — your UI needs to say something sensible about the silent ones.
- Two vehicles belong to no group. The group totals do not add up to the fleet total, which is exactly the trap a group filter has to survive.
- Two dashcams are Wi-Fi-only (
Van-01,Van-02—category: wifi). They appear in the device list, but they have no cloud data: trips, events, SD-card access, settings and reboot answer422 cloud_onlyfor them, exactly as they would for a real Wi-Fi-only camera in your fleet. Handle that code once and your integration will not trip over mixed fleets.
Timestamps are always relative to now, so the demo never looks stale.
Video and thumbnails
The sandbox fleet includes events with more than one channel, so
channels comes back as ["front", "rear"] on some rows and [] on others —
the same shape a live key sees. Pick the channel from that array rather than
hard-coding front. The sandbox media set covers front, rear and
interior; the option channel (7-BOX option camera) exists on live keys only.
Media endpoints return URLs that actually open:
curl "https://openapi.fleeta.io/v1/events/evt_0032/video?channel=front" \
-H "Authorization: Bearer flt_test_ent_0000000000000000001"
{ "data": { "url": "https://developers.fleeta.io/sandbox/media/front.mp4",
"expiresAt": "2026-08-22T14:12:00.000Z", "channel": "front" } }
The thumbnail endpoint takes the same channel parameter and defaults to the
first entry of channels. To pull a whole page of thumbnails in one request,
ask the list for them instead — it costs no extra call and no quota:
curl "https://openapi.fleeta.io/v1/events?limit=20&include=thumbnail" \
-H "Authorization: Bearer flt_test_ent_0000000000000000001"
The sandbox clips are generated dashcam-style frames with a SANDBOX — SYNTHETIC SAMPLE watermark burned in. We do not use customer recordings for demos. They exist so your player, your download flow and your thumbnail grid have something real to render.
Two differences from live media, worth knowing before they surprise you:
- The URL does not really expire.
expiresAtis present and moves forward so your refresh logic can be written and tested against the real contract, but the sandbox file stays reachable afterwards. On live keys the URL is a genuine presigned link and stops working atexpiresAt. - Sandbox clips play inline. Live event video is served as an attachment
(browsers download rather than play it), so do not assume a
<video>tag that works here will play a live URL.
What writes do
Most writes behave here exactly as they will on a live key. The only difference is that nothing reaches a vehicle — there is no vehicle.
What you write is kept for 24 hours, scoped to your key (webhooks are scoped to the demo organization behind your key, so every tier's key sees the same subscriptions). Create a geofence, list it, update it, delete it — the sequence behaves as it will on a live key, and the sandbox tidies itself up a day later so one visitor's experiments do not accumulate for the next. Seeded objects are templates: your key gets its own copy the first time it touches one, and that copy returns to the template after the 24 hours pass.
| Operation | Sandbox | Live key |
|---|---|---|
POST /v1/devices/{psn}/reboot | accepted instantly | reaches the camera |
GET /v1/devices/{psn}/sd-files/{filename}/video | returns a sandbox clip link at once (receivedBytes is always null) | starts the upload, spends the vehicle's mobile data |
POST /v1/media/recall-jobs | completes at once, returns a sandbox clip | takes minutes, spends the vehicle's mobile data |
POST /v1/gps/export-jobs | completes at once (same validation as live — a range over 90 days is 422 invalid_field). The finished job carries a real downloadUrl, downloadFileName and downloadUrlExpiresIn, and the archive is a small zip in the format you asked for (csv / gpx / kml), laid out exactly as a live export is — one export.<ext> entry, the same CSV columns and the same GPX/KML structure — holding synthetic points | queued, then processed |
POST /v1/webhooks | stored, not delivered | stored and delivered |
POST /v1/webhooks/{webhookId}/test | nothing leaves our side. The response is delivered: false with sandbox: true and an error saying so, and the attempt is recorded in the delivery list with test: true. The signatureHeader is computed for real, so you can check your HMAC code against it before going live | posts the sample payload to your URL and returns the status it answered |
POST /v1/webhooks/{webhookId}/reactivate | works on the seeded suspended subscription wh_demo0002 (active ones answer 409 webhook_not_suspended). Each test key gets its own private copy of the seed on first use: the first call returns 200, later calls with the same key return 409 until the sandbox recycles — other keys are not affected | resumes deliveries |
POST /v1/webhooks/{webhookId}/rotate-secret | stored — the next test delivery shows both signatures (on the seeds, only your key's copy changes) | applied to live deliveries |
DELETE /v1/webhooks/{webhookId} | removes the subscription; deleting a seed (wh_demo0001 / wh_demo0002) removes only your key's copy, which comes back when the sandbox recycles | removes the subscription |
Build the whole flow against these — including the approval gate on MCP — and it runs unchanged once you swap the key.
These return a realistic 2xx in the sandbox. On a live key they return
501 and change nothing:
| Operation | Live key response |
|---|---|
PUT /v1/devices/{psn} | 501 write_delegation_not_configured |
POST /v1/devices (pre-register) | 501 write_delegation_not_configured |
In the sandbox both of these do work, and PUT now keeps what you changed for
the 24 hours above — the name and vehicle you set come back from the detail view,
the list and search. It applies the same validation the live path will: a body
with neither name nor vehicle is 422, a Wi-Fi-only PSN is 422 cloud_only,
vehicle.year outside 1900–2100 is 422, and vehicle.tag is read-only (it is
set in the Fleeta web viewer).
This is not a setting you can switch on. The write path into the system that
owns device records is still being built. We return 501 rather than a 2xx
that quietly persists nothing — a rename that reports success and then vanishes
is worse than a clear refusal.
Geofence writes are live. Creating, updating and deleting geofences works on live keys — including through the MCP approval gate. Reads are complete everywhere: listing, fetching and filtering devices and geofences all work on live keys today. Only the two device writes above are affected.
If your integration depends on renaming or pre-registering devices through the API, tell Fleeta support before you build on it — the sandbox will let you write the code, but it cannot tell you when the live path opens.
Rate limits and quota
Test keys are metered like any other key at their tier, so you can watch
429 handling actually fire instead of hoping it works. Check what you have
left at any time:
curl "https://openapi.fleeta.io/v1/usage" \
-H "Authorization: Bearer flt_test_ent_0000000000000000001"
Moving to live data
Nothing in your code changes but the key.
- Install a cloud-connected dashcam and add it to your account
- Issue a live key in the Fleeta web viewer under Management → Open API → API keys
- Replace
flt_test_…withflt_live_…
The endpoints, field names, pagination, error envelopes and scopes are identical, and every read behaves the same — the data is just yours.
There are three exceptions, all listed in What writes do.
Two device write operations succeed in the sandbox and return 501 on a live
key. And a webhook test delivery never leaves our side in the sandbox, so a
receiver you only exercised here has not actually been reached — re-run the test
with a live key before you rely on it. Everything else that worked in the
sandbox works live.
GET /v1/api-logs is a read with the same shape of caveat: it validates every
parameter exactly as a live key does, but always answers with an empty list.
The request log is shared by every sandbox visitor, and it records source IP and
user agent, so the sandbox does not hand it back. Your own call history appears
as soon as you use a live key.
Camera seats are the other thing a test key does not rehearse: the sandbox
never locks a dashcam — every demo dashcam is entitlement: covered and the
cameras.limit beside data simply equals registered. A live key on an
organization that holds more cloud dashcams than its subscription covers
answers 403 camera_limit_exceeded for video, SD-card access, recall and
reboot on the over-limit ones — see
Rate Limits › Camera seats.
Live data is messier than a demo: cameras go quiet mid-trip, GPS drops, a recall times out because the vehicle drove into a tunnel. The Errors guide covers the failure modes worth handling before you go live.