StrideMoor Agent API

Let your own AI agent read your own activity and health data from StrideMoor
中文

What this is

StrideMoor lets you expose your own activity and health data to an AI agent that you build or host.

Typical use: have your agent read your sleep and recovery every morning and draft training advice, or sync your runs into your personal knowledge base.

Three hard rules

An agent cannot run for you, so this API exposes no endpoint that writes activity data — otherwise leaderboards, challenges and points could all be farmed by a script.

1. Enable and get a key

  1. Open the StrideMoor app → Me → Help menu → Agent Access.
  2. The feature is off by default and must be enabled by you; a consent notice is shown and must be confirmed.
  3. Generate a key and copy it. The key is shown only once and cannot be viewed again.
  4. The key does not expire, but you can reset it or turn access off at any time. Resetting invalidates the old key immediately.
The key is equivalent to read access to your data. Never commit it to a repository, screenshot it, or share it. If you suspect a leak, reset it in the app right away.

2. Authentication

Send the key in a header on every request:

curl -H "X-API-Key: sk_sm_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
     https://www.8keya.com/api/v1/agent/capabilities

3. Quick start

Start with /agent/capabilities: it tells you which endpoints this key may call, which scopes it holds, and what the rate limits are.

Then get a full picture of today in a single call:

curl -H "X-API-Key: sk_sm_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
     https://www.8keya.com/api/v1/agent/overview

4. Scopes

All read scopes are granted by default when a key is created. Each one covers a category of data:

scopeDescription
read:profileProfile, cumulative stats, running/cycling realm
read:runsRuns: list, detail, averages, bookmarks
read:statsWeekly/monthly/yearly summary stats
read:routesRoutes: list, detail, leaderboard, nearby
read:socialFriends and follow relationships
read:challengesChallenges: list, ranking, detail, comparison
read:healthHealth: data points, daily stats, history, recovery, ECG
read:devicesBound devices and their status
read:pointsPoints: balance, transactions, products
read:contentCommunity feed, posts, comments (public content)
read:notificationsMy notifications
read:aiPreviously generated AI analyses (read-only)
read:systemWeather, reverse geocoding, version, public config
read:agentAgent aggregate endpoints
write:bookmarksRun bookmarks: add / remove (write, not granted by default)
write:favoritesRun & route favorites: add / remove (write, not granted by default)
write:followFollow / unfollow users (write, not granted by default)

5. Endpoints

60 endpoints in total, all GET. Endpoints marked self-only or participant-only verify ownership and return 403 on cross-user access.

agentAgent aggregates

EndpointDescription
GET /agent/capabilitiesSelf-describing: this key's scopes, all available endpoints, unit conventions, rate limits Agents bootstrap from this; no guessing needed.
GET /agent/health-summaryHealth summary for the last N days (aggregates only, no raw samples) ?days=1-30 (default 7). Use /health/* with a bounded window for raw samples.
Parameters: days optional (string)
GET /agent/overviewOverview: today's activity + latest run + recovery state + running realm Replaces 5-6 separate calls.
GET /agent/recent-runsRecent run summaries (with units and per-run pace) ?limit=1-200 (default 5) & ?page.
Parameters: limit optional (string) · page optional (string)
GET /agent/todayAll metrics for one day (steps / distance / calories / sleep / VO2max / ECG count) Optional ?date=YYYY-MM-DD; defaults to the server's current date.
Parameters: date optional (date, default None)
GET /agent/weekly-reportThis week vs last week: distance, duration, count, average pace Optional ?date= to pick the reference day.
Parameters: date optional (date, default None)

profileProfile & levels

EndpointDescription
GET /user/paojingRunning realm (running level system) Current realm, progress and badges.
GET /user/profileMy profile Nickname, avatar, body parameters, VIP level.
GET /user/qijingCycling realm (cycling level system)
GET /user/stats/heatsActivity heatmap Activity intensity aggregated by date.
GET /users/{id}/statsCumulative stats (self only) ⚠️ The path parameter must be your own users.id, otherwise 403.

runsRuns

EndpointDescription
GET /runsRun list (paginated) ?page & ?page_size (max 200).
Parameters: page optional (integer, default 1) · page_size optional (integer, default 10)
GET /runs/{id}Run detail (own runs only) Someone else's run returns 401.
GET /runs/{id}/bookmarkBookmark a run (write) Bookmarking twice returns a business error; replays with Idempotency-Key return the first response.
GET /runs/{id}/bookmarkRemove a run bookmark (write) No error when it was not bookmarked.
GET /runs/{id}/favoriteAdd a run to favorites (write) Separate list from bookmark; the app shows them independently.
GET /runs/{id}/favoriteRemove a run from favorites (write)
GET /runs/averagesRun averages (pace / distance / duration / cadence)
GET /runs/bookmarks/listBookmarked runs
Parameters: sport_type optional (string, default None)

statsSummary stats

EndpointDescription
GET /statsWeekly / monthly / yearly summary stats ?period=week|month|year|total & ?sport_type=all|run|cycle & ?date=
Parameters: sport_type optional (string, default all) · period optional (string, default week) · date optional (string, default None)

routesRoutes

EndpointDescription
GET /routesRoute list
GET /routes/{id}Route detail
GET /routes/{id}/favoriteFavorite a route (write)
GET /routes/{id}/favoriteUnfavorite a route (write)
GET /routes/{id}/leaderboardRoute leaderboard (public)
Parameters: page optional (integer, default 1) · page_size optional (integer, default 20) · sort_by optional (string, default None) · sport_type optional (string, default None)
GET /routes/favoritesFavourite routes
Parameters: page optional (integer, default 1) · page_size optional (integer, default 10)
GET /routes/nearbyNearby routes (public) ?lat & ?lng & ?radius (meters) & ?limit.
Parameters: lat required (number) · lng required (number) · radius optional (number, default 5000) · limit optional (integer, default 20)

socialFriends & follows

EndpointDescription
GET /friendsFriend list
Parameters: page optional (integer, default 1) · page_size optional (integer, default 20)
GET /friends/requests/pendingPending friend requests
Parameters: page optional (integer, default 1) · page_size optional (integer, default 20)
GET /users/{id}/followFollow a user (write) :id is the target user's users.id; following yourself is rejected. The actor is always the key owner.
GET /users/{id}/followUnfollow a user (write)
GET /users/followersMy followers
Parameters: page optional (integer, default 1) · page_size optional (integer, default 20)
GET /users/followingsAccounts I follow
Parameters: page optional (integer, default 1) · page_size optional (integer, default 20)

challengesChallenges

EndpointDescription
GET /challengesChallenge list ?status & ?page & ?page_size.
Parameters: status optional (string) · page optional (integer, default 1) · page_size optional (integer, default 10)
GET /challenges/{id}Challenge detail (participants only) Non-participants get 403.
GET /challenges/{id}/comparisonChallenge comparison report (participants only) Non-participants get 403.
GET /challenges/rankingChallenge ranking (public) ?type=challenger|defender & ?limit.
Parameters: type optional (string, default challenger) · limit optional (integer, default 20)

healthHealth data

EndpointDescription
GET /health/daily-statsDaily health statistics ⚠️ from/to (YYYY-MM-DD) required; span ≤30 days.
Parameters: from required (date) · to required (date)
GET /health/data-pointsHealth data points (heart rate / blood pressure / SpO2 / stress / invasive) ⚠️ from/to required; a single request may span at most 30 days.
Parameters: type required (string) · from required (integer) · to optional (integer, omitted = unbounded) · page optional (integer, default 1) · size optional (integer, default 100)
GET /health/ecgECG records ⚠️ from/to required; span ≤30 days.
Parameters: from required (integer) · to optional (integer, omitted = unbounded) · page optional (integer, default 1) · size optional (integer, default 20)
GET /health/historyHealth history by type and date ⚠️ ?type required; start_date + end_date span ≤30 days.
Parameters: type required (string) · start_date required (string) · end_date required (string) · date required (date)
GET /health/recoveryRecovery aggregate (recovery time / training load / body state / VO2max / weekly volume) Server-side fixed-window aggregate; no time parameters needed.

devicesDevices

EndpointDescription
GET /devicesBound devices (model / battery / last sync time)

pointsPoints

EndpointDescription
GET /points/balancePoints and token balance
GET /points/productsRedeemable products
GET /points/transactionsPoints transaction history
Parameters: page optional (string, default 1) · page_size optional (string, default 20) · type optional (string, default 0)

contentCommunity content

EndpointDescription
GET /feedCommunity feed (public content)
Parameters: cursor optional (string, default None) · limit optional (integer, default 10) · from optional (string) · to optional (string)
GET /feed/{id}/trackTrack attached to a feed post (public content)
GET /postsPost list (public content)
Parameters: page optional (integer, default 1) · page_size optional (integer, default 10)
GET /posts/{id}Post detail (public content)
GET /posts/{id}/commentsPost comments (public content)
Parameters: page optional (integer, default 1) · page_size optional (integer, default 10)

notificationsNotifications

EndpointDescription
GET /notificationsMy notifications
Parameters: page optional (integer, default 1) · page_size optional (integer, default 20)
GET /notifications/unread/countUnread notification count

aiAI results

EndpointDescription
GET /ai/analyses/{run_id}Previously generated run analysis (read-only, never triggers a new AI call) Returns only your own cached analysis; 404 if none, 403 for someone else's.
GET /ai/daily-quoteDaily quote
Parameters: city optional (string) · locale optional (string)
GET /ai/featuresAI feature list

systemPublic system APIs

EndpointDescription
GET /app/versionLatest app version (public)
Parameters: current optional (integer, default 0) · platform optional (string, default android)
GET /geocode/reverseReverse geocoding (public) ?lat & ?lng.
Parameters: location required (string)
GET /system/config/{key}Public system config value (public)
GET /weatherWeather (public)
Parameters: city required (string) · lat required (number) · lng required (number) · locale optional (string)

6. Units

Every numeric field is a value/unit object. Units used:

fieldunit
distancem
durations
paces/km
cadence_run / cadence_cyclespm / rpm
stepscount
calorieskcal
sleeph
heart_ratebpm
blood_oxygen%
body_temp°C
vo2maxml/kg/min
Heart rate is in bpm, blood oxygen in %, body temperature in °C. Two fields are dimensionless device-native indices (training load, body state) on a 0-10 scale — see the Recovery card in the app and do not treat them as physical quantities.

7. Errors

Failures return a real HTTP status code (errors are never hidden inside a 200), with a body of {code, message}:

HTTPDescription
400Invalid parameters
401Missing, invalid or revoked API key
403Insufficient scope, or attempting to access another user's data
404Not found, or not owned by you
429Rate limited (see Retry-After)

8. Rate limits

By default each key is limited to 60 requests per minute and 5000 per day. Exceeding it returns 429 with a Retry-After header.

9. Time and timezone

Timestamps are UTC seconds or RFC3339, alongside a local_date. All time-series endpoints require an explicit, bounded range of at most 30 days.

10. Privacy and disclaimer

Every endpoint that returns health data includes a top-level disclaimer field (in Chinese and English). Please preserve it in your agent's output — it is not an optional decoration you may strip.

11. MCP access (no code needed)

If your client supports MCP you can skip writing any HTTP code — point it at StrideMoor's MCP endpoint and it discovers the available tools itself. See MCP Access.

Machine-readable spec

An OpenAPI 3.1 spec is also published and can be imported directly by agent platforms that support function calling:

agent-openapi.yaml

StrideMoor

粤ICP备19023441号-4