Overview
v3 includes all of the v2 API — devices, positions, history, commands,
events — with the same code, under /api/v3 instead of /api/v2, plus the
one resource v2 has always been missing: areas (geofences) — create them, read them, update
them, delete them, check whether a point is inside one, and read their entry/exit events. Until
now no API key could manage areas at all: they could only be managed from the app. You can
integrate using only v3 (v2 + areas) without touching /api/v2 — or keep using v2 for
everything but areas: From v2 to v3 explains when each makes sense.
Resources
Section titled “Resources”| Resource | Endpoint | Page |
|---|---|---|
| Devices | /api/v3/devices |
Devices |
| Events | /api/v3/events |
Events |
| Areas (geofences) | /api/v3/areas |
Areas |
Devices and events are the same stable v2 contract, just mounted under /api/v3: the only real
novelties in v3 are areas, and — inside areas — the external_id code
and the dwell_seconds minimum dwell time.
Base URL
Section titled “Base URL”https://api.aitrack.it/api/v3Authentication
Section titled “Authentication”Same as the v2 API: X-API-Key header, created from Settings → API Keys. Authorization: Bearer
stays reserved for the app’s session tokens and is rejected — see Authentication.
Web sessions (user login) aren’t enough: v3 always requires an API key, otherwise it responds
403 API_KEY_REQUIRED.
curl https://api.aitrack.it/api/v3/areas \ -H "X-API-Key: $AITRACK_API_KEY"Permissions (scopes)
Section titled “Permissions (scopes)”Same permissions as v2 for devices and events, plus two new ones for areas — all grantable to the key from Settings → API Keys, independently of each other:
| Permission | Opens |
|---|---|
read_devices |
Device list, nearest device, detail |
read_locations |
Latest known position, nearest device |
read_history |
Position history |
read_history_summary |
History summaries |
send_commands |
Read the command queue (sending isn’t exposed via API) |
read_events |
Fleet events |
read_areas |
List, detail, contains, area entry/exit events |
write_areas |
Create, update, delete, import and external_id upsert for areas |
Without the permission: 403 INSUFFICIENT_SCOPE. Another customer’s area never returns 403,
always 404: it doesn’t even confirm the area exists — same rule for devices
(404 DEVICE_NOT_FOUND), see Errors & limits for the codes specific to devices
and events.
Response headers
Section titled “Response headers”Every v3 response carries X-API-Status: beta, so you can tell it apart from v2 automatically just
by looking at the headers. Unlike v1 (deprecated), v2 and v3 carry neither Deprecation nor
Sunset: both are active surfaces, just with a different status.
Response envelope
Section titled “Response envelope”Same envelope as v2 — see Errors & limits — with one extra field on validation errors:
{ "data": { }, "meta": { "pagination": { "limit": 50, "offset": 0, "count": 3 } } }{ "error": { "code": "VALIDATION_ERROR", "message": "Name is required.", "details": [ { "field": "name", "code": "REQUIRED", "message": "Name is required." }] } }details only appears on 422 VALIDATION_ERROR and lists every invalid field, not just the
first one — see the full code table in Areas.
General errors
Section titled “General errors”| HTTP | error.code |
Meaning |
|---|---|---|
| 400 | BAD_REQUEST |
Invalid parameter (e.g. unknown type filter, missing lat/lng, malformed id/external_id in the path) |
| 403 | API_KEY_REQUIRED |
Authenticated but not with an API key (web session), or no key at all |
| 403 | INSUFFICIENT_SCOPE |
Missing permission on the key (read_areas/write_areas, or the v2 ones) |
| 404 | NOT_FOUND |
Area doesn’t exist or belongs to another customer — the two cases aren’t distinguished |
| 409 | CONFLICT |
external_id already used by another of your areas, only on POST /areas — see Areas |
| 422 | VALIDATION_ERROR |
Invalid request body — detail in details[] |
| 429 | (no dedicated code) | Rate limit exceeded |
| 500 | INTERNAL_ERROR |
Our error |
Devices and events have their own codes too (DEVICE_NOT_FOUND, LOCATION_NOT_FOUND,
COORDINATES_REQUIRED…), identical to v2 — see Errors & limits.
Requests rejected before entering v3 (unknown, revoked, or IP-blocked API key) use the same
general codes as v2 — API_KEY_INVALID, API_KEY_REVOKED, API_KEY_OWNER_INACTIVE,
API_KEY_IP_BLOCKED — always 403.
Rate limit
Section titled “Rate limit”Same limit as v2, shared per key (not per version):
| Limit | Value |
|---|---|
| Per key, per minute | 120 |
| Per key, per hour | 1000 |
| Per IP address, per minute | 120 |
Past the limit: 429, with no X-RateLimit-* or Retry-After header.
Idempotency-Key
Section titled “Idempotency-Key”Only on POST /api/v3/areas (creation): an optional Idempotency-Key header (1–200 characters:
letters, digits, . _ : -) means repeating the same request with the same value, within
24 hours, returns the same response instead of creating a duplicate area. The replayed response
carries the Idempotent-Replayed: true header. Useful when a client retries after a timeout without
knowing whether the first request went through.
curl -X POST https://api.aitrack.it/api/v3/areas \ -H "X-API-Key: $AITRACK_API_KEY" \ -H "Idempotency-Key: create-north-warehouse-2026-09-27" \ -H "Content-Type: application/json" \ -d '{"name":"North Warehouse","type":"circle","center":{"lat":45.4642,"lng":9.19},"radius_m":150}'Not applied on PATCH, DELETE or POST /areas/import.
Machine-readable documentation
Section titled “Machine-readable documentation”v3 exposes its own OpenAPI 3.0 spec and an interactive page, both public (no API key required to read them):
GET /api/v3/openapi.json— the specGET /api/v3/docs— Swagger UI, to try calls from the browser
What may still change (beta)
Section titled “What may still change (beta)”We don’t yet freeze these details as a compatibility guarantee: they may be refined before the stable release, always announced first.
- The exact names and set of codes in
details[].codeon validation errors (the set can grow; existing codes keep their meaning). - Additional fields in an area’s response (
metrics,bounds) — only additions, never removals. - The response shape of
POST /areas/import(today{ dry_run, valid, created, errors, warnings }).
What does not change without notice: authentication headers, the { data, meta } / { error }
envelope shape, the read_areas/write_areas scopes, and every endpoint already documented in
Areas stays reachable.
Next steps
Section titled “Next steps”- Devices and Events — same reference as v2, under
/api/v3. - Areas — full reference for every endpoint, with curl and JSON examples.
- From v2 to v3 — what changes for existing v2 integrations.