Walk15 Connect V1
Errors and limits
Status codes, error bodies, rate limits, Retry-After and what to do in each case.
Walk15 Connect returns fixed error codes with fixed messages. Messages never include your request data, so log the code, HTTP status and X-Request-ID — never tokens or response bodies containing user data.
Error formats
| Where | Format |
|---|---|
GET /oauth/authorize (browser) | Generic Walk15 HTML error page, status 400. Never redirected to your callback. |
| User cancels consent | Redirect to your callback with error=access_denied&state=… |
| Token, revoke and disconnect endpoints | { "error": "<code>", "error_description": "<fixed text>" } |
| Activity endpoints | { "error": { "code": "<code>", "message": "<fixed text>" }, "request_id": "<uuid>" } |
Requests to unknown paths or with the wrong HTTP method are rejected by the server framework (usually 404) before any of the checks below.
Authorization errors
These appear to the user as "Unable to connect with Walk15". You do not receive them; check your configuration if users report this page.
| Cause | Check |
|---|---|
invalid_request | Every parameter present exactly once; redirect_uri identical to the registered value; state 22–2048 visible ASCII characters; 43-character S256 code_challenge; request not older than 10 minutes |
unauthorized_client | Client ID is correct for this environment and your client is active |
unsupported_response_type | response_type=code |
invalid_scope | Scopes are known, unique, single-space separated and within your allowance |
OAuth endpoint errors
| Code | Status | Meaning | What to do |
|---|---|---|---|
invalid_request | 400 | Malformed body, wrong content type, unknown or duplicate fields, query string present, client credentials outside the Authorization header or more than one such header, invalid grant ID shape | Fix the request; do not retry unchanged |
invalid_client | 401 | Client authentication failed: wrong ID or secret, replaced secret, disabled client, wrong environment | Fix credentials; contact Walk15 if your client may have been disabled. User re-consent does not help. |
invalid_grant | 400 | Code or refresh token unknown, expired, used, revoked or not yours; wrong redirect_uri or verifier; connection changed | For codes: restart authorization. For refresh: reauthorize the user. |
unsupported_grant_type | 400 | grant_type is not authorization_code or refresh_token | Fix the request |
unsupported_token_type | 400 | token_type_hint is not access_token or refresh_token | Fix or omit the hint |
server_error | 500 | Walk15 could not complete the request | Retry later with backoff — except a refresh, whose outcome is uncertain |
Activity API errors
| Code | Status | Meaning | What to do |
|---|---|---|---|
invalid_request | 400 | Unknown or duplicate query parameter, request body present, malformed encoding, URL over 4096 characters, invalid limit | Fix the request |
invalid_date_range | 400 | Missing or invalid dates, from after to, more than 31 dates, from before history_from, to after tomorrow (UTC) | Choose an allowed window. Ranges are never trimmed automatically. |
invalid_cursor | 400 | Cursor expired (15 minutes), changed, from another query/limit, or from an older connection version | Restart the traversal from the first page |
invalid_access_token | 401 | Access token missing, malformed, expired, revoked; connection revoked or lapsed; user deleted; client disabled | Refresh once if the token simply expired; if that fails, the user must reconnect |
insufficient_scope | 403 | The connection does not include this endpoint's scope | Stop calling it, or reconnect the user with that scope |
not_found | 404 | grant_id in the path does not match the access token | Use the grant_id stored with that token |
rate_limited | 429 | Your rate or concurrency budget is exhausted | Wait Retry-After seconds; reduce concurrency |
data_unavailable | 503 | Data or coordination is temporarily unavailable | Retry later with exponential backoff; keep your existing data |
401 responses include WWW-Authenticate: Bearer realm="walk15-connect", error="invalid_token" and 403 responses error="insufficient_scope".
Retry only 429 (after Retry-After), 5xx and network errors (exponential backoff with jitter), and a 401 once after refreshing the access token. Never retry a refresh whose outcome is unknown. An error is never an empty result and never means data was deleted.
Rate limits
Walk15 sets a technical rate policy for each customer individually, based on your expected traffic. A policy has three parts:
| Part | Meaning |
|---|---|
| Requests per minute | Sustained refill rate of your request budget |
| Burst | How many requests can be made back-to-back when the budget is full |
| Concurrent reads | How many activity reads Walk15 runs for you at the same time |
The policy applies to all activity requests from your client combined — across all connected users, all three endpoints and all your servers. Authentication, scope and malformed-request errors are not counted; anything that reaches the limiter is, including invalid_date_range and a 429 from the concurrency limit. Token, revoke and disconnect calls are not counted.
Responses that reached the limiter carry:
| Header | Meaning |
|---|---|
RateLimit-Limit | Your configured requests per minute |
RateLimit-Remaining | Whole requests currently left in your burst budget |
RateLimit-Reset | Seconds until the next request becomes available (minimum 1) |
Retry-After | On 429 only: seconds to wait before retrying (minimum 1) |
A 429 caused by the concurrency limit has Retry-After: 1.
Handling 429
- Apply
Retry-Afterto your whole worker pool, not just the one request, and keep parallel activity requests within your concurrency allowance. - Pace requests with a queue rather than fire-and-retry loops, and spread scheduled polling over time.
- Many users sync at the same moment, so
activity.updatedarrives in bursts. Acknowledge events immediately and let workers drain the queue at your allowed rate.
The withRateLimitRetry helper in the TypeScript client shows a minimal per-request version.
Other limits
| Limit | Value |
|---|---|
| Dates per activity request | 31 (inclusive) |
| Cycling activities per page | 1–500 (default 100) |
| Authorization URL | 16 KB |
| Activity request URL | 4096 characters |
| OAuth request body | 8 KB, fields up to 2048 characters |
scope parameter | 512 characters |
state parameter | 22–2048 characters |
| Authorization request | 10 minutes |
| Authorization code | 120 seconds at most |
| Access token | 5 minutes |
| Refresh inactivity | 90 days by default |
| Cursor traversal | 15 minutes |
| Webhook response | 2xx within 5 seconds, body up to 8 KB |