Skip to main content

Rate Limits

Rate limits protect the API from abuse and ensure fair usage across all tenants. Every endpoint enforces a limit on how many requests a single user can make within a given time window.

Strategies

The API uses three different rate limiting strategies depending on the endpoint:

Sliding Window

Used by most endpoints. A sliding window tracks requests over a rolling time period.

  • If the limit is 10 requests per 60 seconds, each request is timestamped.
  • When a new request arrives, the system counts how many requests were made in the last 60 seconds.
  • If the count exceeds the limit, the request is rejected with a 429 status.

This provides a smoother experience compared to fixed windows — there is no "reset cliff" where all capacity is restored at once.

Token Bucket

Used by the telemetry endpoint for GPS data ingestion. The token bucket allows short bursts while enforcing a sustained rate.

ParameterGlobalPer-IMEI
Bucket capacity180 tokens90 tokens
Refill rate30 tokens/sec15 tokens/sec
Cost1 token per 20 GPS points1 token per 20 GPS points

In practice this means:

  • Sustained throughput: ~600 GPS points/second globally, ~300 points/second per device
  • Burst capacity: up to 3,600 GPS points in a single request (180 tokens × 20 points)
  • A batch of 100 GPS points costs 5 tokens. If the bucket is empty, the request is rejected until tokens refill

Login Brute-Force

Used exclusively by the login endpoint to prevent credential stuffing attacks.

  • Limit: 5 attempts per 30-second window
  • Block duration: 60 seconds after exceeding the limit
  • During the block period, all login attempts from the same source are rejected immediately
danger

After 5 failed login attempts within 30 seconds, your account is blocked for 60 seconds. There is no way to bypass this block — you must wait for it to expire.

Rate Limit Policies by Endpoint Group

GroupStrategyLimitWindow
Loginlogin-bruteforce5 attempts30s window, 60s block
Telemetrytoken-bucket180 capacity30 refill/sec
Fleet — Devicessliding-window30 req60 sec
Fleet — Driverssliding-window30 req60 sec
Reports — AVLsliding-window10 req60 sec
Reports — GT Analyticssliding-window10 req60 sec
Reports — GT Operationssliding-window10 req60 sec
Reports — Generalsliding-window10 req60 sec
Reports — CPMsliding-window10 req60 sec
Accountssliding-window10 req60 sec
Clientssliding-window10 req60 sec
Workflowsliding-window30 req60 sec
Kanbansliding-window30 req60 sec
Billingsliding-window20 req60 sec
Portal Proveedoressliding-window20 req60 sec

Response Headers

Every API response includes rate limit information in the headers:

HeaderDescriptionPresent on
X-RateLimit-LimitMaximum requests allowed in the current windowAll responses
X-RateLimit-RemainingRequests remaining in the current windowAll responses
X-RateLimit-ResetUnix timestamp (seconds) when the window resetsAll responses
Retry-AfterSeconds to wait before retrying429 responses only

Reading headers proactively

Don't wait for a 429 to react — monitor X-RateLimit-Remaining on every response and throttle your requests before hitting the limit:

const response = await fetch(
`https://${TENANT}/apidev/v1/fleet/devices?limit=25`,
{ headers }
);

const remaining = parseInt(response.headers.get('X-RateLimit-Remaining'), 10);
const resetAt = parseInt(response.headers.get('X-RateLimit-Reset'), 10);

if (remaining <= 2) {
const waitMs = (resetAt - Math.floor(Date.now() / 1000)) * 1000;
console.warn(`Rate limit almost exhausted. ${remaining} left. Pausing ${waitMs}ms...`);
await new Promise((resolve) => setTimeout(resolve, waitMs));
}

Handling 429 Responses

When you receive a 429 Too Many Requests, use the Retry-After header to wait the exact required time. For a full exponential backoff implementation that handles both 429 and 500 errors, see the Retry Strategy in Error Handling.

Quick inline example:

# Check headers on any response
curl -s -D - \
-H "Authorization: Bearer $TOKEN" \
-H "X-API-Key: $APIKEY" \
-H "tenant: $TENANT" \
"https://$TENANT/apidev/v1/fleet/devices?limit=5" \
| grep -i "x-ratelimit\|retry-after"

# X-RateLimit-Limit: 30
# X-RateLimit-Remaining: 28
# X-RateLimit-Reset: 1743782520

Scope and Concurrency

Rate limits are scoped per tenant, per user. Key rules:

QuestionAnswer
Do different users share a limit?No. Each user has independent limits.
Can I use multiple API keys to bypass limits?No. Limits are tied to the user, not the key.
Can I use multiple user accounts to parallelize?Technically yes, but this is considered abuse and may result in tenant-level throttling. If you need higher throughput, contact your account manager to discuss a custom rate limit plan.
Do read and write operations share a limit?Yes. GET and POST/PUT/DELETE to the same endpoint group share the same window.