Rate limits and quotas
Rate-limit headers
Every response carries the IETF rate-limit header family:
RateLimit-Limit: 50
RateLimit-Remaining: 47
RateLimit-Reset: 12
RateLimit-Limit and RateLimit-Remaining are request counts for the current short window; RateLimit-Reset is seconds until the window resets. A burst that exceeds the window gets 429 with a Retry-After header (seconds).
Daily quota
Each client also has a daily call cap, reset at 00:00 UTC. Check yours with GET /auth/me:
{
"clientId": "ppk_test_9f2c1a",
"tier": "STANDARD",
"dailyCallLimit": 50000,
"callsToday": 1274
}
Exceeding dailyCallLimit also returns 429. Both the burst rate limit and the daily quota use the same TooManyRequests response shape; see Errors.
Handling a 429
Read Retry-After (or RateLimit-Reset for a burst limit) and wait before retrying. Back off exponentially on repeated 429s rather than retrying immediately; a tight retry loop against an exhausted daily quota only wastes calls until 00:00 UTC.
curl -i https://data.placepoint.no/properties/NO/0301-208-15-0-0 \
-H "Authorization: Bearer $TOKEN"
# HTTP/1.1 429 Too Many Requests
# Retry-After: 34
Idempotency-Key on writes
Every POST except /auth/token requires an Idempotency-Key header, a client-generated UUID:
curl -X POST https://data.placepoint.no/subscriptions \
-H "Authorization: Bearer $TOKEN" \
-H "Idempotency-Key: 3f29b6c4-9e1a-4b7d-8c2e-1a9f6d4e7b3c" \
-H "Content-Type: application/json" \
-d '{ ... }'
The same key replays the same response for 24 hours, so a retried request after a dropped connection never double-creates a subscription. A missing key on a POST that requires one returns 400; the same key with a different body returns 409.