Relay

BETA

powered by Scanbo AI

SupportSign in

Overview

Endpoints

More

API Example data only — replace with real credentials

Exposed API Documentation

Two endpoints for external integrators: authenticate with app credentials, then call the health gateway with the returned JWT.

https://dev-relay-backend.agent.scanbo.ai/api/v1

Access

Client credentials

Generate Client ID and Secret from OAuth / API before testing.

Headers

Tenant + country

Every request should include x-tenant-id and x-country-code.

Testing

Built-in runner

Use API Testing to inspect request, response, status, and latency.

Getting Started

Before calling any API, complete these 3 steps on the Relay platform.

1

Sign up or Sign in

Create your account on the Relay platform. Use the link below to open the portal.

https://dev-relay-backend.agent.scanbo.ai ->
2

Create an Application

Go to Dashboard -> Applications -> New Application and fill in the required fields:

Go to Dashboard → Applications → New Application and fill in the required fields:

App Name A unique name to identify your application

Webhook URL Your server endpoint to receive health data events

Redirection URL OAuth callback URL after user authorizes a device

Select Devices Choose which health providers to enable (Apple Health, Oura, Fitbit, etc.)

3

Generate OAuth / API Credentials

Inside your application, go to OAuth / API Keys and generate credentials. You will get a Client ID and Client Secret — use these in the two APIs documented below.

Once you have your credentials, proceed to the App Credentials endpoint below to get your JWT token and start calling the Health Gateway.

API

Common Requirements

All requests under /api/v1 require tenant headers unless noted otherwise.

HeaderRequiredExampleDescription
Content-Type
Yes (POST)
application/jsonJSON request body
x-country-code
Yes
INISO country code (IN, US, EU, AE...)
x-tenant-id
Yes*
relay-health-defaultTenant slug or ObjectId

* In development, server may fall back to DEFAULT_TENANT_ID from environment.

Standard response envelope

JSON

{
  "success": true,
  "code": 200,
  "message": "Human-readable message",
  "data": { }
}
1

Get User by App Credentials

Authenticate a registered application with client credentials. Returns user profile, JWT tokens, and active connector sources.

POST

/api/v1/

Auth

None (body credentials)

Dispatcher field

routname

Value

get-user-by-app-credentials

Request

HTTP

POST /api/v1/ HTTP/1.1
Host: dev-relay-backend.agent.scanbo.ai
Content-Type: application/json
x-country-code: IN
x-tenant-id: relay-health-default

Body parameters

FieldTypeRequiredDescription
routnamestring
Yes
get-user-by-app-credentials
clientIdstring
Yes
App client ID
clientSecretstring
Yes
App client secret
applicationIdstring
Yes*
Registered application ID

JSON · Request

{
  "routname": "get-user-by-app-credentials",
  "clientId": "relay_app_client_7f3a9c2e1b",
  "clientSecret": "sk_live_fake_8Qm2pL9xR4vN6wK1",
  "applicationId": "674a1b2c3d4e5f6789012345"
}

Success Response

JSON

200 OK
{
  "success": true,
  "code": 200,
  "message": "User retrieved successfully",
  "data": {
    "user": {
      "id": "674901234567890123456789",
      "firstName": "Priya",
      "email": "priya.sharma@example-health.app",
      "role": "user",
      "userStatus": "active"
    },
    "accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
    "refreshToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
    "activeDevices": [
      { "key": "strava", "name": "Strava",    "status": "active" },
      { "key": "oura",   "name": "Oura Ring", "status": "ACTIVE" }
    ]
  }
}

Use data.accessToken as the Bearer token for Health API calls.

Error Responses

JSON

422
{ "success": false, "message": '"clientId" is required.', "code": 422 }

JSON

401
{ "success": false, "message": "Invalid client credentials.", "code": 401 }

JSON

403
{ "success": false, "message": "App credentials are inactive.", "code": 403 }

cURL

Bash

curl -X POST 'https://dev-relay-backend.agent.scanbo.ai/api/v1/' \
  -H 'Content-Type: application/json' \
  -H 'x-country-code: IN' \
  -H 'x-tenant-id: relay-health-default' \
  -d '{
    "routname": "get-user-by-app-credentials",
    "clientId": "relay_app_client_7f3a9c2e1b",
    "clientSecret": "sk_live_fake_8Qm2pL9xR4vN6wK1",
    "applicationId": "674a1b2c3d4e5f6789012345"
  }'
2

Health API Gateway

Unified entry for wearable health operations. Uses routeName (camelCase), not routname.

POST

/api/v1/health

Auth

Bearer accessToken

Public routes

connectOura, connectStrava...

Supported routeName values

routeNameAuthPurpose
getAllHealthData
Yes
Aggregated health metrics from connected providers
getUserProfile
Yes
Profile data per connected source
getConnectionStatus
Yes
Provider link status and last sync
connectOura
No
Start Oura OAuth flow
connectStrava
No
Start Strava OAuth flow
connectFitbit
No
Start Fitbit OAuth flow
disconnectConnector
Yes
Disconnect one or more sources
getOuraCompleteHealthData
Yes
Full Oura health payload

Authenticated headers

HTTP

POST /api/v1/health HTTP/1.1
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
Content-Type: application/json
x-country-code: IN
x-tenant-id: relay-health-default

getConnectionStatus

Request

{ "routeName": "getConnectionStatus", "sourceType": ["strava","oura","fitbit"] }

Response

200 OK
{
  "success": true,
  "data": {
    "connections": [
      { "sourceType": "strava", "connected": true,  "lastSyncAt": "2026-05-21T18:45:00.000Z" },
      { "sourceType": "oura",   "connected": true,  "lastSyncAt": "2026-05-22T06:12:00.000Z" },
      { "sourceType": "fitbit", "connected": false, "lastSyncAt": null }
    ]
  }
}

getAllHealthData

Request

{
  "routeName": "getAllHealthData",
  "sourceType": ["oura", "strava"],
  "startDate": "2026-05-01",
  "endDate":   "2026-05-21",
  "categories": ["ALL"],
  "useCache": true
}
FieldTypeDescription
sourceTypestring | string[]Provider key(s) or all
startDatestringYYYY-MM-DD
endDatestringYYYY-MM-DD
categoriesstring[]ALL, Sleep, Activity...
useCachebooleanUse cached provider data
isFhirConvertbooleanFHIR-shaped payloads when supported

Response

200 OK
{
  "success": true,
  "data": {
    "providers": {
      "oura":   { "Sleep": { "summary": [{ "day": "2026-05-20", "score": 82 }] } },
      "strava": { "dailyActivity": [{ "date": "2026-05-20", "distance": 5200.3 }] }
    }
  }
}

iOS SDK

Docs in progress

The Relay iOS SDK integrates with Apple HealthKit to extract health data on-device and forward normalized payloads through the Relay backend. No OAuth redirect is required — data is pulled directly from the device.

Common principles

HealthKit integrations have a few key characteristics that differ from OAuth-based providers:

Data is stored only on-device — it must be actively extracted via HealthKit APIs.

Permission control is granular — each metric type (steps, heart rate, sleep) needs individual user approval.

Data becomes available as soon as it is recorded, with no webhook or delay.

Integration requires active lifecycle management through the SDK.

Setup guide

ItemValueNotes
Minimum versioniOS 15+HealthKit capability must be enabled in Xcode.
PackageRelayHealthKitSDKAvailable via Swift Package Manager.
Xcode setupHealthKit capabilityEnable in target → Signing & Capabilities.
Required credentialsclientId, applicationId, redirectUrlGenerate from Applications → OAuth / API.

Swift · Initialization

import RelayHealthKitSDK

let relay = RelayHealthKit(
  clientId: "relay_app_client_7f3a9c2e1b",
  applicationId: "674a1b2c3d4e5f6789012345",
  redirectUrl: "myapp://relay/callback"
)

// Request HealthKit permissions from the user
try await relay.requestAuthorization(
  readTypes: [.steps, .heartRate, .sleepAnalysis, .workouts]
)

Usage example

Swift · Export & submit

// Export health data for a date range
let payload = try await relay.exportHealthData(
  startDate: "2026-05-01",
  endDate:   "2026-05-21"
)

// Forward normalized payload to your backend
try await yourBackend.submitHealthPayload(payload)
📋

Detailed docs covering background delivery, backfill, logging, and Samsung Health are being prepared by the iOS team. This section will be updated when available.

Android SDK

Docs in progress

The Relay Android SDK integrates with Android Health Connect to read user-approved health metrics and sync them through the Relay API using the same normalized schema as HealthKit.

Common principles

Android Health Connect shares the same device-first model as HealthKit:

Data is stored on-device via Health Connect — it must be actively extracted, not pushed.

Permission control is metric-level — steps, heart rate, sleep, and activity each need separate approval.

Health Connect requires Android 9+ with the Health Connect app installed on the device.

Integration requires active lifecycle management through the SDK and background service.

Setup guide

ItemValueNotes
Minimum versionAndroid 9.0+Health Connect app must be installed on the device.
Packageai.scanbo.relay:health-connect-sdkAdd via Gradle with your private Maven token.
Manifesthealth_permissionsDeclare Health Connect read permissions in AndroidManifest.xml.
Required credentialsclientId, applicationId, packageNameRegister Android package name in Applications.

Kotlin · Initialization

import ai.scanbo.relay.health.RelayHealthConnect

val relay = RelayHealthConnect.Builder(context)
  .clientId("relay_app_client_7f3a9c2e1b")
  .applicationId("674a1b2c3d4e5f6789012345")
  .packageName("com.example.healthapp")
  .build()

// Request Health Connect permissions from the user
relay.requestPermissions(
  setOf(Metric.STEPS, Metric.HEART_RATE, Metric.SLEEP, Metric.ACTIVITY)
)

Usage example

Kotlin · Export & submit

// Export health data for a date range
val payload = relay.exportHealthData(
  startDate = "2026-05-01",
  endDate   = "2026-05-21"
)

// Forward normalized payload to your backend
yourBackend.submitHealthPayload(payload)
📋

Detailed docs covering Samsung Health, background delivery, backfill, and logging are being prepared by the Android team. This section will be updated when available.

API Testing

Test credentials, health gateway, and liveness endpoints directly from this documentation page.

Test API from docs

Choose an endpoint, add credentials or token, run the request, and inspect request/response details.

Service Liveness

Simple process check — not the wearable gateway.

GET

/health

Auth

None

JSON

200 OK
{ "success": true, "message": "Service is running", "data": { "status": "healthy", "version": "1.0.0" } }

Integration Flow

1

Authenticate with app credentials

POST /api/v1/ · routname: get-user-by-app-credentials

-> Receive accessToken, user, activeDevices

2

Check connections (optional)

POST /api/v1/health · routeName: getConnectionStatus

-> Authorization: Bearer <accessToken>

3

Fetch health data

routeName: getAllHealthData with date range and sourceType

-> providers { oura, strava, ... }

Notes for Integrators

->

Case: routname is normalized; getuserbyappcredentials also works.

->

Tokens: accessToken and token in the response are identical.

->

Dates: Use YYYY-MM-DD for startDate / endDate.

->

Data residency: x-country-code selects the regional database — match user registration region.

Relay Matrix Health Connector · Dev documentation

Health gateway

curl --request POST \
  --url 'https://dev-relay-backend.agent.scanbo.ai/api/v1/health' \
  --header 'Authorization: Bearer <token>' \
  --header 'Content-Type: application/json' \
  --header 'x-country-code: IN' \
  --header 'x-tenant-id: relay-health-default' \
  --data '{
    "routeName": "getConnectionStatus",
    "sourceType": ["strava", "oura"]
  }'
{
  "success": true,
  "code": 200,
  "message": "OK",
  "data": {
    "connections": [
      {
        "sourceType": "strava",
        "connected": true,
        "lastSyncAt": "2026-05-21T18:45:00.000Z"
      },
      {
        "sourceType": "oura",
        "connected": true,
        "lastSyncAt": "2026-05-22T06:12:00.000Z"
      }
    ]
  }
}