Skip to content

Web API and OAuth ​

Aidlab Web API access is based on OAuth clients created in Aidlab Cloud. Use this flow when your application needs access to supported data from an individual Aidlab user.

OAuth integrations are self-serve. You can create an OAuth client in Aidlab Cloud, select the scopes your app needs, and start testing without manual approval from Aidlab.

Create an OAuth client ​

  1. Open Aidlab Cloud.
  2. Go to Shortcuts → Developers.
  3. Click Create API key.
  4. Enter an application name and redirect URI.
  5. Select one or more available scopes for your integration.
  6. Copy the client secret when it is shown.

The client secret is displayed only once. Store it in your backend secret manager and never place it in mobile apps, browser code, GitHub, or public logs.

Scopes ​

Available scopes:

ScopeDescription
data:readRead supported health data and user events.
data:writeCreate or import supported health data.
profile:readRead the authorized user profile.

You can also discover the current list programmatically:

bash
curl https://my.aidlab.com/api/oauth/scopes

Endpoint access ​

Operations available to OAuth clients have an x-oauth-scopes field in the API Reference. Other endpoints reject OAuth client tokens with 403, even if a signed-in Aidlab user can call them.

If an endpoint returns 403 with OAuth client tokens cannot access this endpoint, the endpoint is not mapped for OAuth client tokens. If it returns 403 with Insufficient OAuth scope, request or grant the missing scope.

Quickstart: first API request ​

  1. Create an OAuth client and register your callback URL, for example https://partner.example/oauth/callback.
  2. Send the user to the authorization URL.
  3. Exchange the returned code for a token on your backend.
  4. Call an endpoint with the returned access token:
bash
curl "https://my.aidlab.com/api/data/steps?startDate=2026-06-01T00:00:00.000Z&endDate=2026-06-02T00:00:00.000Z&limit=10" \
  -H "Authorization: Bearer bearer_token"

Example response shape:

json
{
  "data": [
    {
      "id": "65f000000000000000000001",
      "date": "2026-06-01T12:00:00.000Z",
      "value": 1200,
      "source": {
        "type": "device",
        "id": "65f000000000000000000002"
      }
    }
  ],
  "hasMore": false,
  "next": null
}

Field names and item schemas differ by endpoint; see the API Reference.

Authorization code flow ​

Send the user to Aidlab to approve your application. The user must be logged in to Aidlab Cloud.

text
https://my.aidlab.com/oauth/authorize
  ?response_type=code
  &client_id=aid_live_...
  &redirect_uri=https%3A%2F%2Fpartner.example%2Foauth%2Fcallback
  &scope=data%3Aread%20profile%3Aread
  &state=opaque-state

Parameters:

ParameterRequiredDescription
response_typeYesMust be code.
client_idYesPublic client ID from the Developers page.
redirect_uriYesMust match one of the redirect URIs registered for the client.
scopeNoSpace-delimited scopes. If omitted, Aidlab uses the scopes configured on the client.
stateNoOpaque value returned to your redirect URI. Use it to protect against CSRF.

After the user approves access, Aidlab redirects to your callback:

text
https://partner.example/oauth/callback?code=returned_code&state=opaque-state

If the user denies access, Aidlab redirects with:

text
https://partner.example/oauth/callback?error=access_denied&state=opaque-state

Exchange the code for a token ​

Exchange the authorization code from your backend. Authorization codes are one-time use.

bash
curl https://my.aidlab.com/api/oauth/token \
  --data-urlencode "client_id=aid_live_..." \
  --data-urlencode "client_secret=secret_..." \
  --data-urlencode "grant_type=authorization_code" \
  --data-urlencode "code=returned_code" \
  --data-urlencode "redirect_uri=https://partner.example/oauth/callback"

Response:

json
{
  "access_token": "bearer_token",
  "refresh_token": "refresh_token",
  "expires_in": 86400,
  "token_type": "Bearer",
  "scope": "data:read profile:read"
}

Access tokens are short-lived; the default lifetime is 24 hours. Store the refresh token on your backend and use it to obtain a new access token without asking the user to approve the app again.

Refresh an access token ​

Refresh tokens are rotated. When you refresh an access token, store the new refresh token from the response and discard the old one.

Refresh tokens expire after 180 days by default and can stop working earlier if the user revokes your app, the client is revoked, or the token has already been rotated.

bash
curl https://my.aidlab.com/api/oauth/token \
  --data-urlencode "client_id=aid_live_..." \
  --data-urlencode "client_secret=secret_..." \
  --data-urlencode "grant_type=refresh_token" \
  --data-urlencode "refresh_token=refresh_token"

Response:

json
{
  "access_token": "new_bearer_token",
  "refresh_token": "new_refresh_token",
  "expires_in": 86400,
  "token_type": "Bearer",
  "scope": "data:read profile:read"
}

Server-to-server tokens ​

For owner-controlled backend jobs, you can use client credentials instead of user consent:

bash
curl https://my.aidlab.com/api/oauth/token \
  --data-urlencode "client_id=aid_live_..." \
  --data-urlencode "client_secret=secret_..." \
  --data-urlencode "grant_type=client_credentials" \
  --data-urlencode "scope=data:read"

Use authorization code flow for third-party apps that access a user’s data. Use client credentials only for server-to-server work owned by the Aidlab account that created the client.

Revoked access ​

Users can revoke connected apps in Aidlab Cloud. After revocation, refresh-token requests fail and active access tokens stop working.

API limits ​

Aidlab rate-limits API traffic to protect service availability. Defaults are 600 /api requests per minute per token or IP, 20 /api/oauth requests per minute, 120 bulk data imports per minute, and 60 time-window data queries per minute. If you receive 429 Too Many Requests, retry after the delay indicated by response headers when present, and use exponential backoff for background jobs.

For large imports, prefer bulk or CSV endpoints where available, split historical data into batches, and make retries idempotent in your own integration by tracking source, timestamp, and imported range.