EasyTrack API reference

Every endpoint you can integrate into your own system or external app: authentication, trackers, real-time GPS positions, vehicles, geofences, agent assignments, alerts, reports and share-links.

Overview

The EasyTrack API is a JSON REST API hosted on Cloudflare (edge, EU region). All requests use HTTPS. Responses are application/json (except CSV/PDF exports). Real-time tracking data comes from Teltonika / FMC trackers and is available a few seconds after the server receives it.

Domainhttps://api.easytrack.ch
FormatJSON UTF-8
AuthBearer token (obtained via email OTP)
MethodsGET, POST, PUT, PATCH, DELETE
CORSEnabled (Access-Control-Allow-Origin: * on the main resources)

Base URL & formats

https://api.easytrack.ch

Every endpoint below is relative to this base. Example: GET /deviceshttps://api.easytrack.ch/devices.

Authentication

Almost every endpoint requires a Bearer token. You obtain the token in two steps: request an OTP code by email, then verify the code. Then add the Authorization header to every request:

Authorization: Bearer <your_token>
Content-Type: application/json
Without a valid token Protected routes return 401 with {"error":"Token manquant"} or {"error":"Session invalide ou expirée"}. Endpoints marked Public do not require a token.

Your first call

1 · Request a code

curl -X POST https://api.easytrack.ch/auth/request-code \
  -H "Content-Type: application/json" \
  -d '{"email":"you@example.ch","lang":"en"}'

2 · Verify the code and get the token

curl -X POST https://api.easytrack.ch/auth/verify-code \
  -H "Content-Type: application/json" \
  -d '{"email":"you@example.ch","code":"123456"}'
# => { "success": true, "token": "…", "expires_at": "…", "user": { … } }

3 · List your trackers

curl https://api.easytrack.ch/devices \
  -H "Authorization: Bearer <token>"

In JavaScript (fetch):

const res = await fetch("https://api.easytrack.ch/devices", {
  headers: { Authorization: `Bearer ${token}` }
});
const { devices } = await res.json();

Endpoint families

Authentication — login & session

POST /auth/request-code Public

Sends a 6-digit OTP code by email (or SMS).

Body

{
  "email": "you@example.ch",
  "lang":  "en"          // optional (fr, de, en, it…)
}

Response

{ "success": true, "message": "Code sent", "expires_in": 600 }
POST /auth/verify-code Public

Verifies the OTP and returns a Bearer token. If 2FA is enabled, returns requires_2fa.

Body

{ "email": "you@example.ch", "code": "123456" }

Response (no 2FA)

{
  "success": true,
  "token": "…",
  "expires_at": "2026-08-01T10:00:00.000Z",
  "user": { "id": 42, "email": "you@example.ch", "role": "client", "two_factor_enabled": false }
}

Response (2FA required)

{ "success": true, "requires_2fa": true, "pending_token": "…" }
POST /auth/verify-2fa Public

Completes login with the TOTP code (or a backup code) and the pending_token.

Body

{ "pending_token": "…", "code": "654321" }
POST /auth/magic-link Public

Sends a one-time login link by email.

Body

{ "email": "you@example.ch" }
GET /auth/me Bearer

Returns the user tied to the current token (useful to validate a session).

POST /auth/logout Bearer

Invalidates the current session (the token can no longer be used).

GET /auth/sessions Bearer

Lists the account's active sessions. DELETE /auth/sessions revokes the other sessions.

Authentication — 2FA & profile

MethodEndpointPurpose
GET/auth/profileGet the profile
PUT/auth/profileUpdate the profile (name, language…)
GET/auth/2fa/status2FA status
POST/auth/2fa/setupGenerate TOTP secret + QR
POST/auth/2fa/verifyEnable 2FA (validates a code)
POST/auth/2fa/disableDisable 2FA
POST/auth/2fa/backup-codesRegenerate backup codes
POST/auth/push-tokenRegister a push token (mobile)
DELETE/auth/push-tokenRemove a push token
GET/auth/notification-preferencesNotification preferences
PUT/auth/notification-preferencesUpdate preferences

Trackers (devices)

A device is a GPS tracker identified by its imei. The endpoints below only return the trackers on your account (and those shared with you).

GET /devices Bearer

Enriched list of your trackers: last position, battery, online status, linked vehicle, active agent, SIM backup.

Response (excerpt)

{
  "success": true,
  "source": "known_devices",
  "devices": [
    {
      "id": 12, "imei": "350612073912345", "name": "Truck 1",
      "status": "online",
      "last_latitude": 46.204, "last_longitude": 6.143,
      "last_speed": 0, "last_heading": 180, "last_battery": 87,
      "last_position_at": "2026-07-11 06:12:33",
      "vehicle_plate": "GE 123456", "vehicle_name": "Van",
      "active_agent_name": null, "is_shared": false
    }
  ]
}
GET /devices/realtime Bearer

Real-time variant: latest raw values of each active tracker, ideal to refresh a map.

GET /devices/active-days Bearer

Days for which at least one of the given IMEIs has positions (useful for a date picker).

Query

ParamRequiredDescription
imeisyesComma-separated list of IMEIs
fromnoMin date YYYY-MM-DD
tonoMax date YYYY-MM-DD
GET /devices/imei/{imei} Bearer

Tracker details by IMEI + its last 50 positions.

GET /devices/{id} Bearer

Tracker details by internal ID + its last 50 positions.

POST /devices Bearer

Activates (registers) a tracker on your account by its IMEI.

Body

{ "imei": "350612073912345", "name": "Truck 1" }   // name optional
PUT /devices/{id} Bearer

Renames/activates a tracker and updates the linked vehicle (created if needed).

Body (all fields optional)

{
  "name": "Truck 1", "is_active": true,
  "vehicle_plate": "GE 123456", "vehicle_name": "Van",
  "vehicle_type": "van", "vehicle_model": "Ford Transit",
  "vehicle_color": "#2563eb", "vehicle_assigned_to": "John"
}
DELETE /devices/{id} Bearer

Removes a tracker from the account (linked positions and alerts cleaned up, vehicle unlinked).

GPS positions

GET /positions/latest Bearer

Last known position of each of your trackers (one row per device).

GET /positions Bearer

Stream of recent positions, filterable by IMEI.

Query

ParamDefaultDescription
imeiFilter on one tracker
limit100Max number of points
GET /positions/imei/{imei} Bearer

Position history of a tracker, with optional geocoded addresses.

Query

ParamDefaultDescription
limit100Max number of points
fromMin bound (server_timestamp)
toMax bound
addresstruefalse to disable reverse geocoding
GET /positions/export Bearer

Paginated export of a tracker's raw history (5000 points per page).

Query

ParamRequiredDescription
imeiyesTracker to export
from/tonoTime range
pagenoPage index (0 by default)

Response

{ "success": true, "imei": "…", "page": 0, "page_size": 5000,
  "count": 5000, "has_more": true, "positions": [ … ] }
GET /positions/device/{id} Bearer

Positions of a tracker via its internal ID.

GET /positions/sim/{imei} Bearer

Fallback positions from cellular (SIM) location when GPS is unavailable.

POST /position Public

Position ingestion (called by trackers/gateways). Rarely useful for a client integration.

Position fields

FieldDescription
latitude, longitudeWGS84 coordinates
speedSpeed (km/h)
heading / angleHeading (degrees)
altitudeAltitude (m)
satellites, hdopGPS fix quality
ignition, movementIgnition / movement (0/1)
battery_level, gsm_signalBattery and network signal
server_timestampServer timestamp (YYYY-MM-DD HH:MM:SS, UTC)

Vehicles

Vehicle record linked to a tracker (plate, model, color, assigned person).

MethodEndpointPurpose
GET/vehiclesList your vehicles
GET/vehicles/{id}Vehicle details
POST/vehiclesCreate a vehicle
PUT/vehicles/{id}Update a vehicle
DELETE/vehicles/{id}Delete a vehicle

Body (POST/PUT)

{
  "plate": "GE 123456", "name": "Van",
  "vehicle_type": "van", "vehicle_model": "Ford Transit",
  "color": "#2563eb", "device_id": 12, "assigned_to": "John"
}

Geofences

Circular zones triggering alerts on enter and/or exit.

MethodEndpointPurpose
GET/geofencesList your zones
GET/geofences/{id}Zone details
POST/geofencesCreate a zone
PUT/geofences/{id}Update a zone
DELETE/geofences/{id}Delete a zone

Body (POST/PUT)

{
  "name": "Geneva depot",
  "latitude": 46.204, "longitude": 6.143, "radius": 150,
  "type": "vehicle",            // or "general"
  "vehicle_id": 12,             // required if type = "vehicle"
  "color": "#ef4444",
  "alert_on_enter": true, "alert_on_exit": true,
  "description": "Parking zone"
}

Agent assignments

Manage your agents (promoters/drivers) and the allocation of trackers to an agent for a session.

MethodEndpointPurpose
GET/assignments/agentsList agents
POST/assignments/agentsCreate an agent
PUT PATCH/assignments/agents/{id}Update an agent
DELETE/assignments/agents/{id}Delete an agent
GET/assignments/devices/{imei}/currentAgent currently assigned to a tracker
GET/assignments/devices/{imei}/historyAssignment history
POST/assignments/devices/{imei}/assignAssign an agent to a tracker
POST/assignments/devices/{imei}/unassignRelease the tracker

Alerts

Notification rules (low battery, speeding, zone enter/exit, etc.).

MethodEndpointPurpose
GET/manager/alertsList alerts
POST/manager/alertsCreate an alert
PUT/manager/alerts/{id}Update an alert
DELETE/manager/alerts/{id}Delete an alert

Share-links (public sharing)

Create temporary share links that let anyone follow certain trackers without an account.

MethodEndpointPurpose
GET/manager/share-linksList your links
POST/manager/share-linksCreate a link (IMEI + expiry)
PUT/manager/share-links/{id}Update / (de)activate
DELETE/manager/share-links/{id}Revoke a link

Reports

Scheduled reports (PDF) and tracking of their runs.

MethodEndpointPurpose
GET/manager/reportsList configured reports
POST/manager/reportsCreate a scheduled report
POST/manager/reports/autoconfigAutomatic configuration
PUT/manager/reports/{id}Update a report
DELETE/manager/reports/{id}Delete a report
POST/manager/reports/{id}/run-nowGenerate immediately
GET/manager/reports/{id}/runsRuns of a report
GET/manager/report-runsAll recent runs
GET/manager/report-configsList configs
POST/manager/report-configsCreate a config

Notifications & settings

MethodEndpointPurpose
GET/manager/notificationsList notifications
POST/manager/notifications/{id}/readMark as read
GET/manager/settingsAccount settings
PUT/manager/settingsUpdate settings
PUT/manager/profileUpdate the manager profile
GET/manager/geofencesGeofences (manager view)

Public sharing

GET /open/share/{token} Public

Resolves a share-link: returns the shared trackers/IMEIs and the expiry. No token required.

Response

{ "success": true, "devices": [ … ], "imeis": ["…"], "expires_at": "…" }

Conventions — JSON responses

Successful responses usually carry success: true and the resource (or a list).

{ "success": true, "devices": [ … ] }

Errors

Errors return an appropriate HTTP status and a { "error": "message" } body.

StatusMeaning
400Invalid request (missing parameter / format)
401Missing, invalid or expired token
403Access denied to this resource (e.g. another account's tracker)
404Resource or endpoint not found
500Server error

Pagination

Position lists are limited via limit. The history export (/positions/export) is paginated in pages of 5000 points: iterate over page while has_more is true.

Dates & time zones

Good to know Each account only sees its own trackers (and those explicitly shared). A call on an unauthorized IMEI returns 403. Keep the token server-side; do not expose it in a public front end.