Tools reference
28 tools are exposed — 20 read tools covering every read domain of the
Open API, play_sd_recording (runs directly, but makes the dashcam upload
over mobile data — see SD-card recordings), 6 write
tools, and confirm_action, the shared second step that executes an
approved write.
Each tool requires the listed scope on the connected API key. Scopes follow your subscription tier, so the From plan column tells you which plan first grants the tool (scopes are cumulative — a higher plan includes everything below it). Tools whose scope the key lacks are not hidden; calling one returns a permission error, so the agent can tell you what would be needed.
Read tools carry the MCP annotation readOnlyHint: true and run immediately.
Write tools go through the approval gate; the destructive
ones also carry destructiveHint: true, so hosts that honor annotations may
show their own confirmation before even sending the call.
Reading past the first page
Every list tool returns a top slice, never the whole set — an MCP result is
loaded into the assistant's conversation, so a fleet of 645 vehicles or a month
of events cannot come back in one answer. Each tool caps its rows with limit
(or perPage) and then says so: summary.truncated and summary.hasMore
both turn true when more rows match, and summary.note spells out what to do
next. (note shows up in one other place: when fleet_locations walked the
fleet for a psn and did not find it, it says so and offers
summary.resumeAfter to carry that search on.)
Continuing is one argument, named after the value you hand back:
| Kind | Tools | Response carries | Pass it back as |
|---|---|---|---|
| Cursor | list_events, geofence_alerts, list_trips, fleet_locations, list_gps_export_jobs, audit_logs, driving_report (ranking mode) | summary.nextCursor | after |
| Page | list_devices, list_geofences, list_webhooks, list_sd_recordings | summary.nextPage | page |
null means that really was the last page. Keep every other argument identical
while continuing — the cursor is bound to the query it came from. A page number
also means nothing without the page size it was measured in, so the page tools
hand back perPage (limit on list_webhooks) and the note repeats it:
"Pass page=4 together with perPage=100". Rows arrive in whole pages, so a
limit that is not a multiple of the page size is rounded up to the page it
falls in — a half page is never dropped, because the rows dropped would be the
ones the next page skips.
The agent is instructed to follow at most two or three pages, even when you
say "all" or "the full list", and then to narrow the period or filters instead;
to say what a partial answer is a slice of ("the top 50 of 645 vehicles")
rather than presenting it as complete; and, when only a number is wanted, to
reach for safety_event_stats or fleet_summary instead of counting rows.
A page with 0 rows and hasMore: true is normal for list_events and
geofence_alerts — the server filters after reading a block of records — and
is not proof that nothing matched.
Devices
| Tool | What it does | Scope | From plan | Access |
|---|---|---|---|---|
list_devices | List dashcams — cloud-connected and Wi-Fi-only alike — with q (name / PSN search, run on the server), status (driving / parked / offline), category (cloud / wifi) and entitlement (covered / over_limit / all, default all) filters; every row carries entitlement, cameraPosition and the assigned vehicle (plate / vin / tag …), and the summary opens with cameras.seats ("N of M covered; over-limit: …"). Because the vehicle is on every row, resolving a plate never needs get_device. Offset-paged: limit stops at 500 rows, so a fleet of several hundred is read with page + perPage (summary.total is the matching fleet, summary.matched only the rows returned) | devices:read | free | read |
get_device | One dashcam — the same fields list_devices returns for each row (model, firmware, battery, SIM, group, vehicle). Use it when you already have a PSN, not once per row of a list. Device settings, firmware-update availability and battery history are REST-only (/settings, /firmware, /battery), and the tool tells the agent to say so rather than guess | devices:read | free | read |
reboot_device | Reboot a dashcam | devices:write | pro | write · gated |
Wi-Fi-only dashcams (category: wifi) appear in the list so the inventory is
complete, but they never connect to the cloud: tools that need cloud data —
locations, trips, events, video, SD recordings, settings, reboot — answer
cloud_only for such a PSN. The assistant is told not to retry; ask it for
category=cloud when the question is about location, trips, events or video.
Older cloud dashcam models have no SD-card command channel at all. For those,
the SD tools — list_sd_recordings, get_sd_recording_metadata,
play_sd_recording — answer unsupported_device right away instead of waiting
out a timeout. This is about the model, not about whether the dashcam is
online, and it is likewise not worth retrying; everything that does not touch
the SD card works normally on those dashcams.
Camera seats are the third thing the device tools report. list_devices
returns the organization's cameras block (limit, registered,
overLimit) and every row carries entitlement (covered / over_limit)
with its cameraPosition; get_device returns the same fields plus
requiredCameraLimit. A dashcam registered beyond the subscription's camera
count is still readable everywhere, but reboot_device, get_event_video
and the SD-card tools (list_sd_recordings, get_sd_recording_metadata,
play_sd_recording, recall_sd_recording, delete_sd_recording) answer
camera_limit_exceeded. The assistant is told that this is not retryable —
the camera count has to be raised in the Fleeta web viewer (Account ›
Subscription), after which the same connection is unlocked within 5
minutes. See Rate Limits › Camera seats.
Safety events
| Tool | What it does | Scope | From plan | Access |
|---|---|---|---|---|
list_events | Query the 18 safety event types (17 uploaded-recording types plus speed_limit, the server-judged road speed-limit violation with no clip), with type / device / time filters — one event is one row, its channels listing every recorded angle. Uploaded recordings plus speed-limit violations — not every detection the dashcam counted. Cursor-paged with after / summary.nextCursor. includeThumbnails: true adds a thumbnailUrl (still image, valid 5 minutes) to the first 25 rows — free of quota and of extra requests, but about 1.6 KB of text each | events:read | starter | read |
safety_event_stats | Event counts and trends per vehicle or fleet-wide — counts uploaded recordings plus server-judged speed_limit violations (same population as list_events; byType carries one speed_limit row) | events:read | starter | read |
get_event_video | Issue a presigned event video URL — counts a flat 6 MB toward the monthly transfer_bytes allowance per call | video:read | standard | read |
The 18 types an agent can filter on, exactly as the tool spells them:
driving_impact, parking_impact, overspeed (the dashcam's own speed alert,
with a clip), speed_limit (the server's road speed-limit judgement from the
GPS track, no clip), harsh_braking, harsh_acceleration, sharp_turn,
drowsy, distracted, seatbelt, undetected, calling, smoking,
geofence_enter, geofence_exit, geofence_pass, geofence_speed, manual.
There are no others — no lane departure, forward-collision or tailgating
events exist in the data, and the tool description tells the agent to say so
rather than substitute the nearest type. A row may still come back as
unknown (an internal code with no public name); unknown is not a filter
value. Leave the type filter out and both populations are returned together.
"How many events happened" has no single right answer. The event tools count
recordings uploaded to the cloud, while fleet_summary and driving_report
count every detection the dashcam reported in its telemetry — for the same day
the two can differ by orders of magnitude. The tool descriptions tell the agent
to name the population it counted, and to give both figures (or ask which you
meant) when the question is simply "how many harsh-braking events yesterday".
See Safety events — two populations.
Event images
list_events is also the way to get pictures. Pass
includeThumbnails: true and the rows carry a thumbnailUrl — the same
presigned still image GET /v1/events/{eventId}/thumbnail issues, built from
data the row already loaded, so it costs no extra requests and no quota. The
links are valid 5 minutes and cannot be renewed, so an agent should present
or download them right away and re-run the query rather than reuse an old
result. There is no per-event thumbnail tool, and the full video is a separate
call (get_event_video, which does consume quota).
Requests and quota are not the only cost, though: a presigned link is about
1.6 KB of text, so 200 of them would be roughly 350 KB of assistant context
for one tool call. The tool therefore attaches images to the first 25 events
of a call and returns the rest without one, saying so in summary.thumbnails.
Ask for a narrower window, a psn or a smaller limit when the images matter
— the REST endpoint GET /v1/events?include=thumbnail has no such cap and is
the right tool when you are building a gallery yourself.
Trips and GPS
| Tool | What it does | Scope | From plan | Access |
|---|---|---|---|---|
fleet_locations | Latest known position of every vehicle, or of one psn — coordinates, speed and heading, no addresses. There is no server-side device filter, so asking for one vehicle walks the fleet page by page instead of missing it past the limit; listing the whole fleet is cursor-paged with after | gps:read | starter | read |
list_trips | Per-vehicle trip history — cursor-paged with after | gps:read | starter | read |
trip_track | GPS track of one trip (sampled to maxPoints) | gps:read | starter | read |
list_gps_export_jobs | GPS Export job list and status — read-only: starting and cancelling an export are REST/SDK only. Cursor-paged with after | gps:export | pro | read |
Geofences
| Tool | What it does | Scope | From plan | Access |
|---|---|---|---|---|
list_geofences | Geofence list — a circle keeps its center and radius, while polygon and route shapes are summarized as a point count and a bounding box (full coordinates come from get_geofence). Each zone also carries style (color, opacity) — the colour Fleeta maps draw it in. Offset-paged with page + perPage | geofences:read | pro | read |
get_geofence | Single geofence detail, with the complete geometry and its map style | geofences:read | pro | read |
geofence_alerts | Alert history — enter, exit, pass (route zones) and speed (speeding inside a zone), filterable by vehicle, kind and UTC period. Cursor-paged with after; the cursor always points past the last row shown, so continuing neither repeats nor skips an alert | geofences:read | pro | read |
create_geofence | Create a circular geofence (center lat/lng + radius in m), optionally with a map color / opacity. The zone is saved empty — see the note below | geofences:write | pro | write · gated |
delete_geofence | Delete a geofence | geofences:write | pro | write · gated · destructive |
create_geofence saves the circle with no dashcams assigned and every
recording option (enter and exit, SD card and live upload) off, because the
API defaults those fields when a request omits them. Nothing fires and nothing
is recorded until someone assigns vehicles and switches those events on — and
neither is possible over MCP: it is done in the web viewer, or with
PUT /v1/geofences/{geofenceId}. The approval summary the agent shows you says
this before you approve.
There is no address lookup in the connection, so a zone can only be created from a center coordinate. Asked for "a 300 m zone around the depot", the agent is told to ask you for the latitude and longitude (or to take them from a tool result — a vehicle's position, a trip start or end, an earlier alert) rather than to invent a position for the name or to answer that it cannot be done.
Zone activity has two sources and the tools keep them apart: geofence_alerts
is the complete history the cloud judged from the GPS track (no video), while
the geofence_* types in list_events are only the zone recordings a zone was
configured to upload — a subset that is often empty. Ask "did it enter or
leave" with geofence_alerts; reach for list_events only when the user wants
the clip. Neither answers "which vehicles are inside the zone right now" —
there is no live containment check in the API.
geofence_alerts has no zone filter, but every alert carries geofenceName,
so the agent can call it straight away and filter the rows itself when the zone
you named is unmistakable. It is told to look the zone up in list_geofences
first only when the name is ambiguous, when nothing matches — then it can tell
you which zones do exist — or when the zone's existence itself is the question.
Insights
| Tool | What it does | Scope | From plan | Access |
|---|---|---|---|---|
fleet_summary | Fleet snapshot over fixed windows (driving = today UTC, event trend = 24 h, top devices = 7 days). Only disconnectedHours is tunable. Event figures are dashcam detections (telemetry counters), not uploaded recordings | insights:read | standard | read |
driving_report | Without psn: fleet ranking over from–to; with psn: that vehicle's single day (date, defaults to yesterday UTC). Event counts are dashcam detections — every event the camera reported, independent of video-upload settings; manual and geofence_* never appear | insights:read | standard | read |
Both tools count covered dashcams by default (entitlement: covered, the
same population as the web viewer's report numbers) and return the
organization's cameras block, so an organization with over-limit dashcams
sees smaller totals than safety_event_stats, which counts every dashcam by
default. Both take an entitlement input (covered / over_limit / all;
driving_report in ranking mode only — the single-vehicle day report answers
for any dashcam), as do list_devices, list_events, fleet_locations and
safety_event_stats (default all).
driving_report without psn returns at most limit rows (50 by default, 200
at most) and sets summary.hasMore when vehicles were left out — in a fleet of
several hundred, the rows you get back are the leaders, not everyone. The next
rows of the same ranking come from summary.nextCursor, passed back as
after. Adding their event counts up totals those vehicles, never the
organization, and the tool description says so. For an organization-wide figure the agent is pointed
at safety_event_stats (uploaded recordings, any period) or fleet_summary
(detections, fixed windows) — and told to say which of the two populations the
number came from.
SD-card recordings
Recordings stay on the dashcam's SD card until someone asks for them. Listing
and metadata ask the device; getting a playable or downloadable link makes the
dashcam upload the clip over LTE and uses the vehicle's mobile data.
play_sd_recording (sub-stream only — the low-resolution copy, a few MB;
there is no full-quality option on it) runs directly so "let me watch that
clip" is one step; a full-resolution download goes through
recall_sd_recording and the approval gate. The playback tool is not a read:
it carries readOnlyHint: false, and its description leads with the cost.
| Tool | What it does | Scope | From plan | Access |
|---|---|---|---|---|
list_sd_recordings | Recordings on a dashcam's SD card (asks the device, which must be online). Offset-paged (page, perPage up to 200): summary.truncated says when older files are still on the following pages, and summary.nextPage is the page to ask for. from / to are the dashcam's own local calendar days — the one place in this connection that is not UTC. type uses the same words as list_events for every safety event (driving_impact, parking_impact, harsh_braking, sharp_turn, the DMS and geofence types …) plus normal and parking, the only two recordings that are not events (manual is an event type in list_events as well), so "the hard-braking clip on the card" is one filter; a category the table does not know is listed as unknown with its raw letter in typeCode rather than dropped | media:read | pro | read |
get_sd_recording_metadata | Thumbnail / GPS track / G-sensor for one recording. A file that is no longer on the card answers 404, so a successful answer really does mean the file is there — it is the cheap check before a recall. gps.recordingEnabled separates "GPS recording is switched off" from "the track could not be decoded"; G-sensor x/y/z are raw signed device counts with no published scale factor, so the agent is told to compare shocks with each other and never to convert them to g | media:read | pro | read |
get_recall_job | Status, upload progress and link of a recall job | media:read | pro | read |
play_sd_recording | Playable link for one recording in a single step (psn, filename) — always the low-resolution sub stream, there is no quality input; returns url, expiresAt, jobId, sizeBytes, receivedBytes, quality (always sub). Same upload and allowance as a recall — 409 device_busy while the dashcam is on another transfer | media:recall | pro | direct · uses mobile data |
recall_sd_recording | Start the same upload as a recall job (quality defaults to main — the only way to a full-resolution file) — returns the job with its play/download link; 409 device_busy while the dashcam is on another transfer | media:recall | pro | write · gated |
cancel_recall_job | Cancel a recall job — stops the device upload (works on the jobId from play_sd_recording too) | media:recall | pro | write · gated |
delete_sd_recording | Delete one recording from the SD card, permanently | media:write | enterprise | write · gated · destructive |
Account
| Tool | What it does | Scope | From plan | Access |
|---|---|---|---|---|
api_usage | Usage and limits for the connected key. apiCalls.used is the live meter that enforces the monthly limit — a call made a moment ago is already counted; only callHistory and statusBreakdown come from a daily rollup, so today's row is usually missing (a missing day is not zero calls). Also carries the cameras block with overLimitPsns — the dashcams that answer camera_limit_exceeded | usage:read | starter | read |
audit_logs | Audit log query — cursor-paged with after | audit:read | enterprise | read |
list_webhooks | Webhook subscription list and status — flags suspended subscriptions and points to POST /v1/webhooks/{webhookId}/reactivate (REST/SDK only). Offset-paged with page | webhooks:manage | pro | read |
The confirm step
| Tool | What it does | Scope | Access |
|---|---|---|---|
confirm_action | Execute a previously approved write action (step 2 of the gate) | scope of the confirmed action | confirm |
confirm_action is the only path by which a write executes. It takes the
confirmation token a write tool returned, re-checks the scope at execution
time, and rejects tokens that are expired (5 minutes), tampered with, or issued
to a different key. On success it returns
{ status: "executed", action, summary, result } — summary repeating the
sentence you approved and result carrying the API response. Details in
Write actions & approval gate.
Not available through MCP
Some things the API can do have no tool here. The agent is told to say so and point you at the web viewer, the REST API or the SDK — not to improvise a substitute — so a "I can't do that from here" answer is the tool set working as intended, not a failure.
| You asked for | Where it lives instead |
|---|---|
| Adding or renaming a dashcam | Web viewer, or POST /v1/devices (pre-registration) / PUT /v1/devices/{psn} |
| Removing a dashcam | Web viewer — there is no delete-device endpoint in the REST API either |
| Device settings, firmware updates and update checks | Web viewer, or GET /v1/devices/{psn}/settings / …/firmware |
| Formatting or wiping an SD card | Web viewer |
| Editing a geofence — renaming, resizing, assigning vehicles, switching its recording options on | Web viewer, or PUT /v1/geofences/{geofenceId} |
| Polygon, rectangle or route (polyline) zones | Web viewer, or POST /v1/geofences (only circles can be created here) |
| "Which vehicles are inside the zone right now" | Nowhere — there is no live containment check; the closest answers are geofence_alerts (entries and exits) and fleet_locations (current positions) |
| Starting or cancelling a GPS export | POST / DELETE /v1/gps/export-jobs… (list_gps_export_jobs only reads the jobs) |
| Creating, deleting, testing or reactivating a webhook | POST /v1/webhooks… (list_webhooks only reads them) |
| Per-request API call logs | GET /v1/api-logs (api_usage returns totals, not individual calls) |
| Listing recall jobs | GET /v1/media/recall-jobs (get_recall_job reads one job by id) |
| Deleting a cloud event | Web viewer — the REST API has no delete-event endpoint; GET /v1/events… is read-only |
| An address for a coordinate | Nowhere — every location in this API is coordinates only; there is no geocoding |
Event images are the exception people expect to find here and do not.
There is no per-event thumbnail tool — the images come from list_events with
includeThumbnails: true, which puts a 5-minute thumbnailUrl on the first 25
rows at no quota cost (see Event images).
Scopes by tier
| Scope | free | starter | standard | pro | enterprise |
|---|---|---|---|---|---|
devices:read | ✓ | ✓ | ✓ | ✓ | ✓ |
gps:read · events:read · usage:read | — | ✓ | ✓ | ✓ | ✓ |
insights:read · video:read | — | — | ✓ | ✓ | ✓ |
devices:write · gps:export · media:read · media:recall · geofences:read · geofences:write · webhooks:manage | — | — | — | ✓ | ✓ |
media:write · audit:read | — | — | — | — | ✓ |
The authoritative matrix with per-scope descriptions is in the Authentication guide. Public sandbox keys exist for every tier, so you can see exactly which tools your plan will unlock before you subscribe — see the Sandbox guide.