Add-ons
The ROOK Connect platform offers multiple add-ons to customize the data integration architecture. Core capabilities such as Time Zone alignment and Data Cleaning are activated by default, while optional ones such as Granular Data extraction, Notification Webhooks, hourly Steps Events, Lab Data, Clinical Ready, Device Metadata, and User Health Profile require manual activation. Pre-Existing Data automatically retrieves up to seven days of historical records for API-based sources on the initial user connection, enabling immediate health metric analysis.
ROOK offers several add-ons that extend the integration experience. Some add-ons are activated by default, while others must be requested. To activate an optional add-on, contact the ROOK support team or your account manager.
| Add-on | What it adds | Activated by default |
|---|---|---|
| Time Zone | Ensures local time delivery | Yes |
| Data Cleaning | Improves data accuracy | Yes |
| Activate Granular Data | Optimizes data delivery | No |
| Notification Webhook | Real-time integration notifications | No |
| Callback URL Setup | Redirects users post-connection | No |
Connections Page Sandbox | Simplifies user authorization | Yes |
| Pre-Existing Data | Historical data retrieval | Yes |
| Steps Events in API | Hourly step polling | No |
Lab Data Beta | Laboratory document processing | No |
Clinical Ready Beta | FHIR R4 clinical documents | No |
Device Metadata Beta | Medical device metadata enrichment | No |
| User Health Profile | Generated profile with health scores | No |
Branded Auth On Hold | A fully personalized experience | No |
Time Zone
The Time Zone add-on ensures that daily summary data is extracted and delivered based on each country’s local time zone.
This add-on is activated by default in ROOK Connect. Additional details are available in the Data Extraction section.
To set up the time zone of your users, check the following endpoint.
Data Cleaning
The Data Cleaning add-on prioritizes and cleans health data from multiple sources for the same user, ensuring the delivery of accurate and comprehensive data structures. This add-on is activated by default in ROOK Connect. For more details, visit the Data Processing section.
Activate Granular Data
The Activate Granular Data add-on enables access to detailed health metrics such as heart rate, heart rate variability, blood pressure, and additional minute-level readings. This option increases payload depth and provides a richer dataset for clients who need more precise insights.
The add-on is not activated by default. More information is available in the Granular Data section.
To activate Granular Data, contact the ROOK support team or your account manager.
Notification Webhook
The Notification Webhook add-on provides real-time updates about integration-specific actions, including user creation, data source connections, and failed notifications. This webhook does not deliver health data, but it provides essential updates for monitoring and troubleshooting.
User management notifications
Notifications are triggered by actions such as:
- New user creation
- Data source connections or disconnections
- Failed data extractions
Example notification for a user connection
{
"client_uuid": "123456789",
"user_id": "UserTest12345",
"data_source": "garmin",
"action": "user_connected",
"level": "info",
"message": "A new user has been successfully linked",
"action_datetime": "2024-06-03T19:10:43.419390",
"environment": "production"
}
For setup guidance, refer to the Data Delivery section.
To activate the Notification Webhook, contact the ROOK support team or your account manager.
Callback URL Setup
The Callback URL Setup add-on enables clients to define a redirect URL for users after completing data source authorization. This add-on improves the user flow by guiding users back to the client’s APP or another designated view.
Usage example:
https://api.rook-connect.com/api/v1/client_uuid/123456789/user_id/UserTest12345/data_sources/authorizers?redirect_url=https://www.yourapp.com
To activate the Callback URL Setup, contact the ROOK support team or your account manager.
Connections Page
The Connections Page simplifies user authorization by presenting a pre-configured interface with buttons for supported data sources. This tool is ideal for sandbox testing and rapid development, but it is not recommended for production environments.
Key capabilities
- Pre-configured interface: Provides a dynamic view of supported data sources using the
/authorizersendpoint. - Configuration in ROOK Portal: Allows adjustments to displayed data sources and testing connectivity.
Production considerations
For production environments, clients should create a custom authorization interface by directly using the /authorizer
endpoint for each data_source. This endpoint returns:
- Authorization status and URL — Returns the user’s authorization status and, if the user is not authorized, an authorization URL to start the process.
More information is available in the API documentation.
Important: About the pre-configured interface
- The previous
/data_sources/authorizersendpoint is deprecated and should not be used for production flows.
Pre-Existing Data
The Pre-Existing Data add-on retrieves prior health data from users upon their initial connection. This includes up to:
- 7 days of pre-existing data for API-based sources.
- 29 days of pre-existing data for mobile-based sources via SDKs.
Key benefits
- Immediate insights: Pre-existing data enables instant analysis of user health metrics upon connection.
- ROOK Score calculation: A ROOK Score is calculated for each day of extracted pre-existing data, resulting in up to 7 scores for API-based sources and up to 29 scores for SDK-based sources. These scores are delivered within 24 hours, ensuring all prior data is processed accurately.
- Seamless integration: Pre-existing data is delivered through the Data Webhook, using the same JSON structure as summaries and events, ensuring compatibility with existing systems.
Important notes
-
Source-specific variations:
- Polar: Does not provide physical or body summaries in pre-existing data.
- Whoop: Returns the same body summary for the past seven days, reflecting the most recent data available.
- Garmin: If the same user links twice within the same client account but with a different
user_id, pre-existing data is sent only on the first link. The second link receives no pre-existing data.
-
ROOK Score calculation: Each extracted day of pre-existing data contributes to a separate ROOK Score, ensuring comprehensive scoring and insights.
For additional details, visit the News Page.
In the Sandbox environment, Pre-Existing Data is activated by default, allowing teams to test the full flow without additional configuration. In Production, this add-on is not activated by default and must be activated manually before use. For activation and additional support, contact the ROOK support team.
Steps Events in API
The Steps Events in API add-on enables the extraction of time-based step events using API-based data sources, offering granularity similar to that obtained through SDK-based data sources. It operates through a polling system that automatically queries third-party APIs such as Whoop, Oura, Garmin, Fitbit, Withings, or Polar every hour, applying validation rules to ensure data consistency, ascending order, and deduplication.
To activate this add-on in production, contact the ROOK support team or your account manager.
Functionality
| Capability | Description |
|---|---|
| Hourly extraction | A polling system queries third-party APIs every hour to retrieve accumulated step counts. |
| Data consistency | Extraction logic mirrors SDK behavior, with harmonized structure and frequency. |
| Duplicity rules | Only ascending values are accepted. If multiple sources are connected, the highest value is selected. When step values are zero or null, they fall back to the last known valid value. |
| Data structure | The event is delivered in steps_event format, including datetime, user_id, data_source, and accumulated steps. |
| Webhook delivery | Step events are delivered exclusively through the Data Webhook and cannot be fetched through an API request. |
| Notification Webhook (optional) | If a fetch failure occurs (timeout, authentication error, quota limit), a notification is sent to the client's Notification Webhook, when one is configured. |
Steps events flow diagram

Payload structure
{
"version": 2,
"data_structure": "steps_event",
"client_uuid": "",
"user_id": "",
"document_version": 1,
"auto_detected": false,
"physical_health": {
"events": {
"steps_event": [
{
"metadata": {
"datetime_string": "2025-02-27T21:29:26.747000+05:00",
"user_id_string": "10053949724",
"sources_of_data_array": ["Garmin"],
"was_the_user_under_physical_activity_bool": false
},
"steps": {
"accumulated_steps_int": 8546
},
"non_structured_data_array": []
}
]
}
}
}
Lab Data Beta
Lab Data enables you to integrate laboratory results into your application through a single API. Submit a laboratory document in PDF or image format and receive structured results once processing is complete.
ROOK processes each document asynchronously through an extraction, normalization, and validation pipeline. Once processing is complete, the results are automatically delivered to the Data Webhook configured for your integration.
Lab Data simplifies the integration of clinical laboratory data into digital applications without requiring you to build your own document processing infrastructure.
What does Lab Data do?
Lab Data automates the processing of laboratory documents, transforming unstructured information into consistent, structured data that is ready for your application.
During processing, ROOK:
- Extracts biomarkers from the document.
- Identifies the clinical panels included in the report.
- Normalizes biomarker names, units, and values.
- Maps biomarkers to LOINC codes when available.
- Validates the consistency of each biomarker.
- Generates a structured response in either ROOK JSON or FHIR R4 format.
The entire processing pipeline runs within ROOK's infrastructure. Your application only needs to submit the document and receive the processed results through a Data Webhook.
How it works
Integrating Lab Data consists of four steps.
- Your application submits a laboratory document to the Lab Data endpoint.
- ROOK receives the document and places it into the processing queue.
- The document goes through the extraction, normalization, and validation pipeline.
- Once processing is complete, ROOK sends the structured results to your configured Data Webhook.
Lab Data processes documents asynchronously. The API response only confirms that the document has been successfully received. Processing results are delivered later through the configured Data Webhook.
Lab Data delivers processing results exclusively through a Data Webhook.
Before submitting your first laboratory document, make sure you have configured an HTTPS endpoint that is publicly accessible. ROOK sends an HTTP POST request to this endpoint each time a document is processed successfully.
If you have not configured a Data Webhook yet, see the Data Delivery section before continuing.
Use cases
Lab Data is designed for applications that need to incorporate laboratory results without building their own document extraction and normalization system.
Common use cases include:
- Digital health platforms.
- Wellness applications.
- Preventive care programs.
- Remote patient monitoring solutions.
- Clinical research platforms.
- Systems that consolidate laboratory data from multiple providers.
Document requirements
Before submitting a document, verify that it meets the following requirements.
Supported formats
Lab Data accepts the following file formats:
- JPEG
- PNG
If you submit a JPEG or PNG image, ROOK automatically converts it to PDF before processing begins.
Maximum file size
- The maximum supported file size is 10 MB.
- Requests that exceed this limit are rejected.
Sample collection date and time
- The document must include a visible sample collection date and time.
- This information is required to process the document.
- If either the date or time is missing or cannot be read, processing fails and no Data Webhook is sent.
Document quality
For the best processing results, we recommend that documents:
- Are complete.
- Are not cropped.
- Are clearly legible.
- Have sufficient image resolution.
- Do not contain shadows or reflections over the content.
- Are correctly oriented.
Integrate Lab Data
Once you have configured a Data Webhook and verified that your documents meet the processing requirements, you can begin submitting laboratory documents to Lab Data.
The integration exposes a single endpoint for document submission. Each request starts an asynchronous processing workflow and returns a unique identifier for the submitted document.
There is no endpoint to check the processing status. All processing results are delivered automatically through your configured Data Webhook.
Endpoint
Submit laboratory documents using the following endpoint.
POST https://api.lab.rook-connect.<com | review>/client_uuid/{client_uuid}/user_id/{user_id}
Path parameters
| Parameter | Description |
|---|---|
client_uuid | The client identifier assigned by ROOK during onboarding. |
user_id | The identifier of the user associated with the document. This value is defined by your application. |
Authentication
Lab Data supports two authentication methods.
Bearer token
Recommended for new integrations.
Authorization: Bearer <your_cognito_token>
Basic authentication
Supported for existing ROOK integrations.
Authorization: Basic <base64(username:password)>
Request format
Requests must be sent using multipart/form-data.
Form parameters
| Field | Type | Required | Description |
|---|---|---|---|
file | File | Yes | Laboratory document in PDF, JPEG, or PNG format. Maximum file size: 10 MB. |
timezone | String | Yes | UTC offset corresponding to the sample collection time. The value must use the ISO-8601 offset format. |
Example request
curl -X POST \
"https://api.lab.rook-connect.com/client_uuid/your-client-uuid/user_id/your-user-id" \
-H "Authorization: Bearer <your_token>" \
-F "file=@/path/to/laboratory_result.pdf" \
-F "timezone=-05:00"
Time zone
Use the timezone field to specify the time zone associated with the sample collection date and time when it cannot be determined directly from the document.
ROOK determines the time zone using the following priority:
- The time zone identified in the document.
- The value provided in the
timezonefield. - If neither is available, timestamps are returned without time zone information.
The value must be provided as an ISO-8601 UTC offset.
| Valid values | Invalid values |
|---|---|
-05:00 | UTC |
+01:00 | EST |
Z | -5:00 |
Response
If the request is valid, the endpoint returns an HTTP 200 OK response.
{
"document_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"status": "received"
}
The document_id uniquely identifies the submitted document.
Store this identifier to correlate the submitted document with the processing results delivered through the Data Webhook.
Response codes
| Status code | Description |
|---|---|
200 OK | The document was successfully received and processing has started. |
400 Bad Request | The request is invalid or required fields are missing. Verify that both file and timezone are included and correctly formatted. |
401 Unauthorized | Authentication failed. Verify the credentials provided in the Authorization header. |
403 Forbidden | Lab Data is not activated for your organization. Contact the ROOK team to activate the service. |
413 Payload Too Large | The uploaded file exceeds the maximum supported size of 10 MB. |
415 Unsupported Media Type | The request was not sent using multipart/form-data. |
500 Internal Server Error | An unexpected error occurred while receiving the document. Retry the request. If the issue persists, contact ROOK Support. |
After submitting a document
Once the document is received, ROOK starts processing it asynchronously.
During processing, ROOK extracts biomarkers, normalizes the data, and performs the required validations before generating the structured result.
There is no endpoint to check the processing status.
When processing completes successfully, ROOK automatically sends the results to your configured Data Webhook.
If a document cannot be processed or is identified as a duplicate, no Data Webhook is sent. If you need assistance investigating one of these cases, provide the document_id returned when the document was submitted.
To activate Lab Data, contact the ROOK support team or your account manager.
Clinical Ready Beta
The EHR/EMR Clinical Ready add-on transforms your users' normalized health summaries into a FHIR R4-compliant document, annotated with LOINC codes and UCUM units. Every time a new summary is generated or updated, ROOK consolidates the available health data and delivers a FHIR Bundle through your existing Data Webhook — no additional integration required.
How it works
ROOK reads from three summary types and maps each metric that has a LOINC code into an Observation resource. Metrics without a LOINC code are excluded.
| Source | Clinical data included |
|---|---|
body_summary | Weight, height, BMI, blood pressure, resting HR, SpO₂, caloric intake |
physical_summary | Steps, distance, average HR, VO₂max, SpO₂ |
sleep_summary | Sleep duration and stages, breathing rate, SpO₂, time to fall asleep |
Each document is versioned: a new version is generated only when the clinical content changes. If no new data arrives, the existing document is preserved.
Payload structure
The FHIR Bundle is delivered through the Data Webhook with data_structure: "clinical_ready". The bundle follows the FHIR R4 collection type and includes one Patient resource and one Observation per mapped metric.
{
"version": 1,
"document_version": 1,
"data_structure": "clinical_ready",
"user_id": "user123",
"client_uuid": "client456",
"clinical_ready": {
"metadata": {
"datetime_string": "2025-10-13T18:00:00.000Z",
"user_id": "user123",
"sources_of_data_array": ["Apple Health"],
"fhir_export_ready": true,
"fhir_export_completed_at": "2025-10-13T08:00:00.000Z"
},
"clinical_ready_data": {
"resourceType": "Bundle",
"id": "rook-clinical-bundle-user123",
"type": "collection",
"timestamp": "2025-10-13T18:00:00.000Z",
"meta": {
"profile": ["http://hl7.org/fhir/StructureDefinition/Bundle"],
"source": "rook-clinical-normalization-engine",
"tag": [
{
"system": "https://api.tryrook.io/fhir/tags",
"code": "clinical_ready_export",
"display": "client=client456 user=user123 fhir_export_ready=true"
}
]
},
"entry": [
{
"fullUrl": "urn:uuid:patient-user123",
"resource": {
"resourceType": "Patient",
"id": "patient-user123",
"identifier": [
{
"system": "https://api.tryrook.io/users",
"value": "user123"
}
],
"meta": { "source": "rook-clinical-normalization-engine" }
}
},
{
"fullUrl": "urn:uuid:obs-heart-rate-avg",
"resource": {
"resourceType": "Observation",
"id": "obs-heart-rate-avg",
"status": "final",
"category": [
{
"coding": [
{
"system": "http://terminology.hl7.org/CodeSystem/observation-category",
"code": "vital-signs"
}
]
}
],
"code": {
"coding": [
{
"system": "http://loinc.org",
"code": "8867-4",
"display": "Heart rate"
}
]
},
"subject": { "reference": "urn:uuid:patient-user123" },
"effectivePeriod": {
"start": "2025-10-13T00:00:00.000Z",
"end": "2025-10-13T23:59:59.999Z"
},
"meta": { "source": "rook-clinical-normalization-engine" },
"extension": [
{
"url": "https://api.tryrook.io/fhir/extensions/observation-context",
"valueString": "daily_average"
}
],
"valueQuantity": {
"value": 94,
"unit": "beats/min",
"system": "http://unitsofmeasure.org",
"code": "/min"
}
}
},
{
"fullUrl": "urn:uuid:obs-steps",
"resource": {
"resourceType": "Observation",
"id": "obs-steps",
"status": "final",
"category": [
{
"coding": [
{
"system": "http://terminology.hl7.org/CodeSystem/observation-category",
"code": "activity"
}
]
}
],
"code": {
"coding": [
{
"system": "http://loinc.org",
"code": "55423-8",
"display": "Number of steps in unspecified time Pedometer"
}
]
},
"subject": { "reference": "urn:uuid:patient-user123" },
"effectivePeriod": {
"start": "2025-10-13T00:00:00.000Z",
"end": "2025-10-13T23:59:59.999Z"
},
"meta": { "source": "rook-clinical-normalization-engine" },
"valueQuantity": {
"value": 11701,
"unit": "steps",
"system": "http://unitsofmeasure.org",
"code": "{steps}"
}
}
},
{
"fullUrl": "urn:uuid:obs-sleep-duration",
"resource": {
"resourceType": "Observation",
"id": "obs-sleep-duration",
"status": "final",
"category": [
{
"coding": [
{
"system": "http://terminology.hl7.org/CodeSystem/observation-category",
"code": "survey"
}
]
}
],
"code": {
"coding": [
{
"system": "http://loinc.org",
"code": "93832-4",
"display": "Sleep duration"
}
]
},
"subject": { "reference": "urn:uuid:patient-user123" },
"effectivePeriod": {
"start": "2025-10-12T23:09:16.916Z",
"end": "2025-10-13T05:17:17.486Z"
},
"meta": { "source": "rook-clinical-normalization-engine" },
"valueQuantity": {
"value": 21145,
"unit": "s",
"system": "http://unitsofmeasure.org",
"code": "s"
}
}
}
]
}
}
}
The full bundle includes one Observation per mapped metric across all available summaries. The preceding examples illustrate the three Observation categories used: vital-signs (body metrics), activity (physical data), and survey (sleep data).
To activate Clinical Ready, contact the ROOK support team or your account manager.
Device Metadata Beta
The Medical Devices add-on is an optional module that, once activated, enriches supported events with a device_source_data_array object appended at the top level of each event. This object provides metadata about the physical device that captured the measurement.
Supported sources and events
| Data Source | Supported Events |
|---|---|
| Apple Health | body_blood_glucose_event, body_blood_pressure_event, body_oxygenation_event, body_temperature_event, body_ecg_event |
| Withings | blood_pressure_event, temperature_event, oxygenation_event, ecg_event |
| Dexcom | blood_glucose_event |
| Health Connect | body_blood_glucose_event, body_blood_pressure_event, body_oxygenation_event, body_temperature_event |
| Samsung Health | body_blood_glucose_event, body_blood_pressure_event, body_oxygenation_event, body_temperature_event |
device_source_data_array structure
When the add-on is active, every supported event includes the following field at its top level:
"device_source_data_array": [
{
"device_type_string": "Activity Tracker",
"manufacturer_string": "Withings",
"medical_grade_bool": null,
"model_string": "ScanWatch 2",
"source_type_string": "wearable/sdk"
}
]
| Field | Type | Description |
|---|---|---|
device_type_string | string | Category of the device (for example, "Activity Tracker") |
manufacturer_string | string | Device manufacturer name |
medical_grade_bool | boolean | null | Whether the device is medical-grade certified |
model_string | string | Specific model name of the device |
source_type_string | string | Data source type (for example, "wearable/sdk") |
To activate Device Metadata, contact the ROOK support team or your account manager.
User Health Profile
The User Health Profile add-on transforms synchronized wearable data into a structured health profile.
Instead of processing individual wearable metrics, your application receives a consolidated profile organized into five health domains: activity, sleep, cardio, recovery, and body.
Each profile includes normalized metrics, health scores, trends, and personalized insights generated from the user's recent wearable data.
The profile is generated on demand and delivered asynchronously through your configured Data Webhook.
How it works
The integration follows an asynchronous workflow.
- Your application requests a User Health Profile.
- ROOK analyzes the user's synchronized wearable data.
- ROOK generates the User Health Profile.
- ROOK delivers the generated profile to your configured Data Webhook.
Profiles are generated only when your application requests one. ROOK does not regenerate a profile automatically when new wearable data arrives — request a new profile to pick up the new data.
The same applies after a user connects a data_source: request the profile once their Pre-Existing Data has been synchronized.
User Health Profile delivers generated profiles exclusively through a Data Webhook. The endpoint does not return the profile.
If you have not configured a Data Webhook yet, see the Data Delivery section before continuing.
Requirements
Before requesting a User Health Profile, make sure that:
- The user has connected at least one supported data_source through ROOK Connect.
- The user's wearable data has been synchronized.
- A Data Webhook is configured.
- User Health Profile is activated for your organization.
Generate a User Health Profile
Request a profile using the following endpoint. The endpoint validates the request and immediately starts asynchronous processing.
Endpoint
POST https://api.rook-connect.<com | review>/api/v2/user_profile
Authentication
User Health Profile supports the authentication method basic authentication, supported for existing ROOK integrations.
Authorization: Basic <base64(client_uuid:password)>
ROOK resolves the client_uuid from these credentials. Do not send it in the request body.
Request body
Requests must be sent using application/json.
| Field | Type | Required | Description |
|---|---|---|---|
user_id | String | Yes | The identifier of the user associated with the profile. This value is defined by your application. |
{
"user_id": "user-12345"
}
Example request
curl -X POST \
"https://api.rook-connect.com/api/v2/user_profile" \
-H "Authorization: Basic <base64(client_uuid:password)>" \
-H "Content-Type: application/json" \
-d '{"user_id": "user-12345"}'
The generated profile is not returned by the endpoint. Results are delivered later through the configured Data Webhook.
Response
If the request is valid, the endpoint returns an HTTP 202 Accepted response.
{
"message": "User profile request queued",
"request_id": "6df0d4fd-c5d8-4e16-8e0d-xxxxxxxxxxxx"
}
The request_id uniquely identifies the profile generation request.
Store this identifier to correlate the request with the profile delivered through the Data Webhook. The same value arrives in the payload as metadata.request_id_string.
Response codes
| Status code | Description |
|---|---|
202 Accepted | The request was successfully queued for asynchronous processing. The response includes a request_id that can be used to correlate the request with the profile delivered later by webhook. |
400 Bad Request | The request body is not valid JSON, or user_id is missing or empty. The response uses the standard error format, with exception indicating that user_id is required. |
401 Unauthorized | Authentication failed. The exception field is "The client_uuid or password are incorrect" when the Authorization header is absent or the Basic credentials are invalid, and "Unsupported authorization type" when an unsupported authentication scheme is used. |
403 Forbidden | User Health Profile is not activated for your organization. The response returns feature_not_included in the exception field. Contact the ROOK team to activate the add-on. |
422 Unprocessable Entity | The request body is valid JSON but cannot be processed. The exception field is "request body must be a JSON object" when the body is not a JSON object, or "user_id must be a string" when user_id is present but is not a string. |
429 Too Many Requests | The request exceeded the applicable rate limit described in Rate limits. The response returns rate_limit_exceeded in the exception field and includes rate-limit headers indicating the remaining quota and how long to wait before retrying. |
500 Internal Server Error | An internal error prevented the request from being accepted or queued for processing. Retry the request. If the issue persists, contact ROOK Support. |
Profile generation
ROOK analyzes the user's synchronized wearable data, primarily from the previous seven days, and generates five health domains.
Each domain may contain:
- Aggregated metrics
- Health score
- Health level
- Trend
- Data coverage
The generated profile also contains an overall score and personalized insights.
Health levels
Every score is classified into a health level.
| Score | Level |
|---|---|
| 80–100 | Optimal |
| 65–79 | Good |
| 50–64 | Moderate |
| 30–49 | Poor |
| Below 30 | Critical |
Health domains expose this value as level_string. The overall object exposes the same concept as category_string.
Scores and data confidence
Each domain reports two independent values:
score_int— how good the available data looks, from 0 to 100.confidence_score_int— how complete and reliable the data behind that score is, from 0 to 100.
Because the two values are independent, a high score can come with low confidence:
{
"score_int": 85,
"level_string": "Optimal",
"confidence_score_int": 35
}
In this example the available metrics look healthy, but they cover only a small part of the analysis window. Read a low confidence_score_int as a signal to avoid strong conclusions, not as a poor result.
Missing metrics lower confidence_score_int, never score_int. See Missing data.
Receive the User Health Profile
When processing is complete, ROOK sends the generated profile to your configured Data Webhook as an HTTP POST request with a JSON payload.
Your endpoint should respond with one of the following status codes:
200 OK201 Created202 Accepted
If delivery fails, ROOK retries the webhook automatically. Retry intervals match the ones described in the Data Delivery section.
Payload structure
The payload contains the generated User Health Profile together with metadata that identifies the request.
{
"version": 1,
"document_version": 1,
"data_structure": "user_profile",
"user_id": "user",
"client_uuid": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"user_profile_data": {
"metadata": {
"datetime_string": "2026-08-01T00:00:00.000000-05:00",
"user_id_string": "user",
"request_id_string": "6df0d4fd-c5d8-4e16-8e0d-xxxxxxxxxxxx"
},
"demographics": {},
"profiles": {},
"overall": {},
"insights": []
}
}
Root object
| Field | Description |
|---|---|
version | Payload version. |
document_version | Version of the generated profile. This value increases each time ROOK recalculates the profile. |
data_structure | Always user_profile. |
user_id | External user identifier. |
client_uuid | ROOK client identifier. |
user_profile_data | Generated User Health Profile. |
metadata
The metadata object identifies the generated profile.
| Field | Description |
|---|---|
datetime_string | Date of the generated profile, set to 00:00:00 in the user's UTC offset. This is the date the profile covers, not the time the request was made. When no UTC offset is available for the user, ROOK uses +00:00. |
user_id_string | External user identifier. |
request_id_string | Identifier of the profile generation request. |
demographics
The demographics object contains the demographic information available for the user. It may include sex, birth year, country, and UTC offset.
profiles
The profiles object groups the generated health information into five domains.
| Domain | Description |
|---|---|
| Activity | Daily movement and activity metrics. |
| Sleep | Sleep duration and quality metrics. |
| Cardio | Cardiovascular health metrics. |
| Recovery | Recovery and readiness metrics. |
| Body | Body measurements and body composition metrics. |
Each domain object has the following structure.
| Field | Description |
|---|---|
metrics | Aggregated metrics for the domain, together with their data coverage. |
score_int | Domain score, from 0 to 100. null when there is not enough data. |
level_string | Health level derived from score_int. null when there is not enough data. |
trend_string | Change compared with the previous profile. null when no comparison is possible. |
overall
The overall object summarizes the user's health using the available health domains.
| Field | Description |
|---|---|
health_score_int | Overall score, from 0 to 100, combining the available health domains. |
category_string | Health level derived from health_score_int. Health domains express the same concept as level_string. |
confidence_score_int | Confidence in the data behind the overall score, from 0 to 100. |
trend_string | Change compared with the previous profile. null when no comparison is possible. |
insights
The insights array contains personalized observations generated from the available wearable data. Insights may identify positive patterns, trends, risks, and relationships between health domains.
Each insight exposes two fields.
| Field | Description |
|---|---|
text_string | The observation, in English. |
confidence_int | Data coverage behind this insight, from 0 to 100. It reflects the quality of the data that triggered the observation, not diagnostic certainty. |
"insights": [
{ "text_string": "Your activity patterns are consistent", "confidence_int": 80 },
{ "text_string": "Your sleep schedule is consistent", "confidence_int": 85 }
]
There is no maximum number of insights. ROOK returns every insight whose conditions are met, after removing duplicates and resolving conflicting observations. Use confidence_int to apply your own visibility threshold.
Missing data
User Health Profile does not interpret missing metrics as poor health.
If a metric is unavailable, ROOK uses the remaining available metrics whenever possible.
If there is not enough information to calculate a domain, the corresponding values are returned as null.
{
"score_int": null,
"level_string": null,
"trend_string": null
}
If there is not enough data to generate any domain, ROOK does not generate or deliver a User Health Profile.
Rate limits
The User Health Profile endpoint applies the following limits per user and client. The daily window is a rolling 24-hour period starting from the user's first request, not a calendar-day reset.
| Limit | Value |
|---|---|
| Requests per hour | 3 |
| Requests per 24-hour window | 30 |
Requests that exceed these limits return 429 Too Many Requests with the body:
{
"error": "Too Many Requests",
"exception": "rate_limit_exceeded",
"path": "/api/v2/user_profile",
"method": "POST"
}
When a request is rejected with 429, the response includes the following headers.
| Header | Description |
|---|---|
X-RateLimit-Limit-Hour | Maximum requests allowed per hour. |
X-RateLimit-Remaining-Hour | Requests still available in the current hour. |
X-RateLimit-Limit-Day | Maximum requests allowed per day. |
X-RateLimit-Remaining-Day | Requests still available in the current day. |
Retry-After | Seconds to wait before retrying. Points to the end of whichever window is blocking the request. |
To activate User Health Profile, contact the ROOK support team or your account manager.
Branded Auth On Hold
The Branded Auth add-on lets you customize the data source connection interface, removing ROOK's visual identity and replacing it with your own company's. This ensures that the end user perceives a native, consistent synchronization process within a trusted environment aligned with your brand.
By default, when users link their health devices or apps, they go through a standardized authentication flow. By activating Branded Auth, you can:
- Replace the ROOK logo with your own on all connection screens.
- Maintain visual consistency at every step of the process, from selecting the data source to confirming synchronization.
To activate Branded Auth on your instance or request details about the technical customization requirements, contact the ROOK support team or your account manager.
This process can take several weeks and partly depends on the timelines of the respective data sources. We strongly recommend starting early to avoid any delays to your launch.