Authentication
All API endpoints require authentication. The Vital API supports Bearer tokens (user sessions) and API keys (service-to-service).
All API endpoints require authentication. The Vital API supports Bearer tokens (user sessions) and API keys (service-to-service).
Bearer Token
Use for user-authenticated requests (e.g. from a web or mobile app).
Authorization: Bearer <JWT>- Obtain the JWT from your auth flow (e.g. Auth0, Vital sign-in).
- Results are scoped to organizations the user belongs to.
API Key
Use for server-to-server or headless integration.
x-api-key: <API_KEY>- API keys are organization-scoped; results are limited to that organization.
- Admin (master) keys have unrestricted access across all organizations.
- Rate limits apply: 100 requests per minute per API key (see Rate Limits below).
Rate Limits
API key requests are limited to 100 requests per minute per key (all private endpoints). When exceeded, the API returns 429 with a Retry-After header (seconds until the current minute window ends) and a detail field such as "Rate limit exceeded. Max 100 requests per minute."
Bearer token requests are not covered by that API-key limiter. GET /api/v1/data/ and GET /api/v1/data/application_zones/ have additional limits that apply to every identity (bearer and API key):
| Limit | Default | Env override |
|---|---|---|
Global concurrent /data* queries | 8 | DATA_QUERY_GLOBAL_CONCURRENCY |
Per-identity concurrent /data* queries | 6 | DATA_QUERY_PER_USER_CONCURRENCY |
Per-identity /data* requests per minute | 20 | DATA_QUERY_PER_USER_PER_MINUTE |
| Influx query timeout | 30s | DATA_QUERY_TIMEOUT_MS |
Max location_ids (long-range) | 50 | DATA_QUERY_MAX_LOCATIONS |
Max location_ids (last() / ≤8d window) | 250 | DATA_QUERY_MAX_LOCATIONS_SNAPSHOT |
Excess /data* work is refused, not queued:
| Status | Meaning |
|---|---|
| 429 | Too many concurrent data queries, or data query rate limit exceeded. Honor Retry-After. |
| 400 | Too many location_ids in one request. Pass fewer IDs per call. |
| 504 | Data query timed out. Retry with fewer locations or a shorter time range. |
Prefer one request with all location_ids over one request per location. limit is applied across all locations combined (default 1000, max 10_000).
The Retry-After header is exposed to browsers via CORS (Access-Control-Expose-Headers).
Organization Scoping
Data endpoints support an optional organization_id query parameter:
| Parameter | Behavior |
|---|---|
| Omitted | Uses all organizations the identity can access |
| Provided | Limits results to that organization; returns 403 if access is denied |
Example:
GET /api/v1/data/?organization_id=5&location_ids=uuid1&aggregation_period=1d
Authorization: Bearer <token>Errors
| Status | Meaning |
|---|---|
| 401 | Missing or invalid credentials |
| 403 | Valid credentials but insufficient permission or access denied for requested resource |
| 429 | Rate limit exceeded (API key on any private route; also /data* concurrency or per-minute limit for all identities) |
Error responses include a detail field with a human-readable message.
