Skip to main content

Content types

Token route in the API Reference: API key token.

Response envelope

Successful operations return the payload directly (200 OK with DTO JSON). There is no global wrapper like { "data": ... }. Service-layer results use ApiResult / ApiResult<T> internally; controllers map them to HTTP status codes and return either the DTO or the error object as the JSON body (see Errors).

Response headers


Rate limiting

Limits apply per API key and per endpoint, in four fixed windows: per second, per minute, per hour and per day. A request must be within all four. A request over any limit is rejected with 429, not queued. Every V2 endpoint is rate-limited except the token endpoint, POST /v2/api/authentication/token/api-key. Every response that reaches the endpoint counts against the limit, including 403, 404, 409, 422 and 500; follow-up pages in a pagination session do not. Responses from a rate-limited endpoint carry these headers once the token has authenticated: They are absent on a 401 for a missing, invalid or expired bearer token, on a 404 with code: PATH_NOT_FOUND, on a 405, on the token endpoint, and on follow-up pages served free by a pagination session. When a limit is exceeded, the server returns 429 Too Many Requests with an additional header: Retry strategy: wait the full Retry-After value before retrying. That always clears the window that was exhausted; if another window is also used up, the retry gets a new 429 with that window’s Retry-After, so wait again. Limits: Four single-vehicle endpoints have a single tight window that is the limit in practice: GET /v2/api/vehicles/info allows 60 per minute; GET /v2/api/vehicles/{id}/last-online allows 2 per second; GET /v2/api/vehicles/{id}/last-position allows 60 per day; GET /v2/api/vehicles/{id}/positions allows 60 per hour. The count is per API key across all vehicles, not per vehicle. ¹ This endpoint returns the last known position for every vehicle mapped to the company. Recommended usage is approximately one poll cycle every 5 minutes. A cycle costs at least one counted request per company — follow-up pages are free in a pagination session — so spread the requests: if the calls are sent together, the per-second (4) and per-minute (20) limits are the first ones hit. Polling more frequently than this is unlikely to yield new data and burns through the budget quickly. ² Nearest vehicles loads every vehicle mapped to the company on each request; Fleet last positions loads one page at a time. The rate limit applies per request regardless of fleet size. ³ Accepts a maximum of 50 vehicle IDs per request.

Pagination

Paginated V2 endpoints accept page (1-based, default 1) and pageSize (default 50) query parameters and return:
GET /v2/api/battery-health pages differently: it takes pageNumber (default 1) and pageSize (default 25), and returns page, pageSize and totalCount instead of currentPage, numberOfPages and totalResults. It has no lastResultIndex.
V2 pagination parameters: Legacy V1 pagination parameters (applies only to POST /api/GetCompanyVehiclesBatteryHealth): Endpoints with pagination support:

Pagination sessions

Follow-up pages of the V2 endpoints listed above, except battery health, can be fetched without counting against the rate limit:
  1. Request a page with an explicit page parameter. This first request counts as usual. A 200 response carries an X-Session-Token header.
  2. Request further pages of the same endpoint and query (page and pageSize may change) and send the latest token back in an X-Session-Token request header. Each page you have not fetched yet in this session is free and has no X-RateLimit-* headers.
  • Always send the token from the most recent response.
  • Fetching a page again counts against the limit and starts a new session.
  • A token works only with the API key that created it, and expires after 10 minutes without use.
  • Changing any other query parameter starts a new session.
  • GET /v2/api/battery-health does not take part (it pages with pageNumber).

Date and time

  • JSON serialization for DateTime uses custom converters (SimplifiedDateTimeConverter) that write without fractional seconds, e.g. 2026-04-07T14:32:00.
  • Request parameters: pass ISO-like strings that DateTime.Parse accepts (e.g. 2026-04-07T14:32:00 or 2026-04-07T14:32:00Z depending on client). Many actions call DateTime.SpecifyKind(..., Utc) in code—treat replay and position ranges as UTC unless the controller comment says otherwise.
  • TimeSpan values in JSON (e.g. trip duration) use the .NET format [d.]hh:mm:ss[.fffffff], not ISO 8601.

Null vs omitted

  • Fields are always present. A field with no value is written as null, not omitted.
  • For PositionDto, isOnline is always present. Single-vehicle Last position never sets it, so it is always false there.