16 REST endpoints, authentication, rate limits, and integration guide.
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.
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:
read (GET requests only) or write (all HTTP methods)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.
Limits depend on account state:
| Tier | General Limit | Streams Limit | Export Limit |
|---|---|---|---|
| Free | Basic access | Limited | Limited |
| Endure | Full athlete access | Full athlete access | Standard export limits |
| Coach-linked athlete | Full athlete access while coached | Full athlete access | Standard export limits |
| Coach | Coaching workspace access | Roster-scoped | Standard export limits |
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)| 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 |
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), SERVICE_UNAVAILABLE (503: the API key could not be checked right now; it is not a rejection, so retry after the Retry-After seconds instead of treating the key as invalid).
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.
The API never returns sensitive fields: clerk_id, email, user_id, access_token, refresh_token, or any stripe_* fields are stripped from all responses.
The API supports cross-origin requests with Access-Control-Allow-Origin: *. All endpoints include an OPTIONS handler for preflight requests.
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.