Public API
16 REST endpoints, authentication, rate limits, and integration guide.
On this page
ENDURE offers a public API with 16 v1 endpoints + 2 api-key management routes (using Clerk auth) for external integrations and automation. The v1 endpoints are under /api/v1/ with API key authentication.
Authentication
All API requests require an API key in the Authorization header:
Authorization: Bearer endure_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Create API keys from Settings > API Keys. Keys have:
- Scope:
read(GET requests only) orwrite(all HTTP methods) - Optional expiration: Set a date after which the key stops working
- Revocation: Disable a key permanently at any time
- Maximum: 5 active keys per user
The full key is shown once at creation. Only a SHA-256 hash is stored — if you lose the key, you'll need to create a new one. Keys use the format endure_live_ followed by 32 hex characters.
Rate Limits
Limits depend on your subscription tier:
| Tier | General Limit | Streams Limit | Export Limit |
|---|---|---|---|
| Free | 30 requests/min | 50/day | 1/hour |
| Premium | 120 requests/min | 500/day | 1/hour |
| Pro | 240 requests/min | 1,000/day | 1/hour |
| Team | Unlimited | Unlimited | 1/hour |
Rate limit headers are included in every response:
X-RateLimit-Limit— Your limitX-RateLimit-Remaining— Requests remainingX-RateLimit-Reset— When the limit resets (Unix timestamp in milliseconds)Retry-After— Seconds to wait if rate limited (HTTP 429)
Endpoints
| Method | Endpoint | Description |
|---|---|---|
| GET | /api/v1/status |
API health check (no auth required) |
| GET | /api/v1/athlete |
Your athlete profile |
| PATCH | /api/v1/athlete |
Update FTP, zones, goals |
| GET | /api/v1/activities |
List activities (paginated, 90-day max range) |
| POST | /api/v1/activities |
Create a manual activity |
| GET | /api/v1/activities/:id |
Activity detail with zones and metrics |
| PATCH | /api/v1/activities/:id |
Update RPE, feeling, or notes |
| GET | /api/v1/activities/:id/streams |
Second-by-second stream data |
| GET | /api/v1/workouts |
List your custom workouts |
| GET | /api/v1/workouts/:id |
Workout detail with intervals |
| GET | /api/v1/plans |
List training plans |
| GET | /api/v1/plans/:id |
Plan detail with phases |
| GET | /api/v1/readiness/current |
Today's readiness score and signal |
| GET | /api/v1/readiness/history |
Readiness history (90-day max, paginated) |
| GET | /api/v1/pmc |
CTL/ATL/TSB daily values (365-day max) |
| GET | /api/v1/zones |
Your current power and HR zones |
| GET | /api/v1/integrations |
Connected platforms and sync status |
| POST | /api/v1/export |
Start an async data export |
| GET | /api/v1/export/:id |
Check export status and get download URL |
API Key Management (uses Clerk auth, not API keys):
| Method | Endpoint | Description |
|---|---|---|
| GET | /api/settings/api-keys |
List your active API keys |
| POST | /api/settings/api-keys |
Create a new API key |
| DELETE | /api/settings/api-keys/:id |
Revoke an API key |
Response Format
All successful responses follow this envelope:
{
"data": { ... },
"meta": {
"request_id": "uuid",
"timestamp": "2026-02-22T12:00:00.000Z"
}
}
Error responses:
{
"error": {
"code": "UNAUTHORIZED",
"message": "Invalid or revoked API key.",
"details": []
},
"meta": {
"request_id": "uuid",
"timestamp": "2026-02-22T12:00:00.000Z"
}
}
Error codes: UNAUTHORIZED (401), FORBIDDEN (403), NOT_FOUND (404), VALIDATION_ERROR (400), RATE_LIMITED (429), SCOPE_INSUFFICIENT (403), INTERNAL_ERROR (500).
Pagination
List endpoints use cursor-based pagination. The response includes:
{
"pagination": {
"has_more": true,
"cursor": "eyJkYXRlIjoiMjAyNi0wMS0xNSIsImlkIjoiYWJjMTIzIn0=",
"limit": 50
}
}
Pass the cursor as a query parameter to get the next page: ?cursor=eyJkYXRlIjoi...
Default page size is 50, maximum is 200.
PII Stripping
The API never returns sensitive fields: clerk_id, email, user_id, access_token, refresh_token, or any stripe_* fields are stripped from all responses.
CORS
The API supports cross-origin requests with Access-Control-Allow-Origin: *. All endpoints include an OPTIONS handler for preflight requests.
Status Endpoint
The /api/v1/status endpoint is the only public endpoint (no auth required). It returns:
{
"data": {
"status": "operational",
"version": "1.0.0",
"database": "healthy"
}
}
Use this for uptime monitoring and health checks.