Trang này cung cấp thông tin tổng quan về các quy ước API REST, cùng với một chỉ mục về các tác vụ phổ biến của Google Health API và ví dụ về từng tác vụ.
Quy ước về API REST
Google Health API tuân theo các tiêu chuẩn Đề xuất cải tiến API của Google (AIP), cụ thể là AIP-127 (Chuyển mã HTTP và gRPC) và AIP-131 đến AIP-135 (Phương thức chuẩn). Các tiêu chuẩn này xác định cách dữ liệu được ánh xạ từ một thông báo giao thức sang một yêu cầu HTTP.
Tham số truy vấn
Tham số truy vấn được dùng khi dữ liệu là một phần của URL. Điều này chủ yếu dành cho các yêu cầu GET (tìm nạp tài nguyên) hoặc các yêu cầu LIST (lọc/phân trang), nhưng cũng được dùng cho các thao tác DELETE.
- Vị trí: Được thêm vào URL sau dấu
?. - Cú pháp: Các cặp khoá-giá trị được phân tách bằng
&. - Ánh xạ: Mọi trường trong thông báo yêu cầu không thuộc mẫu đường dẫn URL đều được ánh xạ đến một tham số truy vấn.
- Phù hợp nhất với: Các loại đơn giản (chuỗi, số nguyên, enum) và các trường lặp lại.
Ví dụ về cú pháp:
GET https://health.googleapis.com/v4/users/me/dataTypes/data-type/dataPoints?page_size=10&filter=data_type.interval.start_time >= "2025-10-01T00:00:00Z"
Nội dung yêu cầu
Nội dung yêu cầu được dùng khi dữ liệu sửa đổi trạng thái của một tài nguyên hoặc có kích thước quá lớn đối với một URL. Nội dung thường là một biểu thị JSON của chính tài nguyên đó. Thường được dùng cho các thao tác POST, PATCH và PUT.
- Vị trí: Bên trong tải trọng HTTP (không xuất hiện trong URL).
- Cú pháp: Được định dạng dưới dạng đối tượng JSON.
- Ánh xạ: Được xác định trong chú giải
google.api.http.body: "*"có nghĩa là toàn bộ thông báo là nội dung.body: "resource_name"có nghĩa là chỉ một trường cụ thể trong proto là phần nội dung.
- Phù hợp nhất với: Các đối tượng phức tạp, thông báo lồng nhau và dữ liệu nhạy cảm.
Ví dụ về cú pháp:
POST https://health.googleapis.com/v4/users/me/dataTypes/data-type/dataPoints:rollUp
Content-Type: application/json
{
"range": {
"startTime": "2025-11-05T00:00:00Z",
"endTime": "2025-11-13T00:00:00Z"
},
"windowSize": "3600s"
}Trường hợp kết hợp
Trong phương thức Update tuân thủ AIP-134 hoặc thao tác PATCH, cả hai đều được sử dụng.
URL chứa tên tài nguyên, nội dung chứa dữ liệu tài nguyên đã cập nhật và một tham số truy vấn (thường là update_mask) chỉ định những trường cần thay đổi.
PATCH https://health.googleapis.com/v4/projects/project-id/subscribers/subscriber-id
Content-Type: application/json
{
"endpointUri": "https://myapp.com/new-webhooks/health"
}
Tổng quan về những điểm khác biệt chính
| Tính năng | Tham số truy vấn | Nội dung yêu cầu |
|---|---|---|
| Hướng dẫn về AIP | Được dùng cho các thao tác tìm kiếm, lọc và đọc. | Dùng cho các thao tác ghi. |
| Chế độ hiển thị | Xuất hiện trong nhật ký trình duyệt và nhật ký máy chủ. | Bị ẩn khỏi URL. |
| Độ phức tạp | Chỉ giới hạn ở các cấu trúc phẳng hoặc lặp lại. | Hỗ trợ các đối tượng JSON lồng nhau. |
| Mã hoá | Phải được mã hoá URL (ví dụ: khoảng trắng sẽ trở thành %20). |
Mã hoá JSON tiêu chuẩn. |
Ngày
Tất cả ngày tháng trong Google Health API đều được hiển thị ở định dạng YYYY-MM-DD. Nutrition API hỗ trợ tiêu chuẩn ISO-8601 cho các giá trị ngày với các điều kiện sau:
- Năm có 4 chữ số
YYYY - Giá trị năm trong khoảng từ 0000 đến 9999
- Không áp dụng các quy tắc hạn chế về ngày bắt đầu theo tiêu chuẩn ISO-8601 hoặc kỷ nguyên khác
Tiêu đề
Để thực thi các điểm cuối Google Health API, bạn cần sử dụng tiêu đề và mã truy cập phù hợp. Bạn nên dùng tiêu đề sau cho cả yêu cầu GET và POST:
Authorization: Bearer access-token Accept: application/json
Chỉ mục tác vụ API
Phần này cung cấp một chỉ mục về các tác vụ thường gặp của Google Health API và ví dụ về từng tác vụ.
Lấy mã nhận dạng người dùng Fitbit hoặc Google
Sau khi người dùng đồng ý thông qua Google OAuth 2.0, phản hồi mã thông báo sẽ không chứa mã nhận dạng người dùng Fitbit hoặc Google. Để lấy mã nhận dạng người dùng, hãy gọi điểm cuối getIdentity. getIdentity trả về cả mã nhận dạng người dùng cũ của Fitbit và mã nhận dạng người dùng của Google.
Bạn nên gọi điểm cuối getIdentity và lưu trữ cả hai mã nhận dạng người dùng ngay khi người dùng mới đồng ý thông qua OAuth. Điều này giúp bạn có khả năng tương thích ngược và tương thích xuôi trong quá trình tích hợp.
Ví dụ:
Yêu cầu
GET https://health.googleapis.com/v4/users/me/identity Authorization: Bearer access-token Accept: application/json
Phản hồi
{
"name": "users/me/identity",
"legacyUserId": "A1B2C3",
"healthUserId": "111111256096816351"
}Nhận dữ liệu trong ngày hoặc dữ liệu chi tiết được thu thập trong suốt một ngày
Sử dụng list
điểm cuối cho một loại dữ liệu cụ thể để nhận dữ liệu trong ngày hoặc dữ liệu chi tiết được thu thập trong suốt cả ngày theo các khoảng thời gian được hỗ trợ cho loại dữ liệu đó.
Ví dụ:
Yêu cầu
GET https://health.googleapis.com/v4/users/me/dataTypes/steps/dataPoints Authorization: Bearer access-token Accept: application/json
Phản hồi
{
"dataPoints": [
{
"dataSource": {
"recordingMethod": "PASSIVELY_MEASURED",
"device": {
"manufacturer": "",
"displayName": "Charge 6"
},
"platform": "FITBIT"
},
"steps": {
"interval": {
"startTime": "2026-03-04T07:05:00Z",
"startUtcOffset": "0s",
"endTime": "2026-03-04T07:06:00Z",
"endUtcOffset": "0s",
"civilStartTime": {
"date": {
"year": 2026,
"month": 3,
"day": 4
},
"time": {
"hours": 7,
"minutes": 5
}
},
"civilEndTime": {
"date": {
"year": 2026,
"month": 3,
"day": 4
},
"time": {
"hours": 7,
"minutes": 6
}
}
},
"count": "40"
}
},
...
],
"nextPageToken": "Xm5h-6L0viZxIlRuWjx5bmvy98zj85uG34tuMn16mu2pntsnZI32iqhq"
}Xem dữ liệu khoảng thời gian đã được đối chiếu
Để truy xuất dữ liệu khoảng thời gian mà không có các bản ghi trùng lặp hoặc xung đột giữa nhiều thiết bị, hãy gọi điểm cuối reconcile. Điểm cuối điều chỉnh tự động loại bỏ các khoảng thời gian trùng lặp trên các lô đồng bộ hoá và nhiều thiết bị ghi, trả về một luồng liên tục, có thẩm quyền phù hợp để hiển thị dòng thời gian hoạt động và tính toán thời lượng.
Để biết thông tin cơ bản về lý do các thiết bị được kết nối tạo ra các khoảng thời gian trùng lặp và so sánh hoạt động giữa list và reconcile, hãy xem Hướng dẫn quản lý dữ liệu.
Ví dụ sau đây so sánh phản hồi của list (trả về cả hai bản ghi trùng lặp) với reconcile (giải quyết xung đột bằng cách trả về bản ghi có thẩm quyền) cho một người dùng có hai phiên tập thể dục trùng lặp:
Danh sách thô
GET https://health.googleapis.com/v4/users/me/dataTypes/exercise/dataPoints Authorization: Bearer access-token Accept: application/json
{
"dataPoints": [
{
"name": "users/111111256096816351/dataTypes/exercise/dataPoints/7797422996486764704",
"exercise": {
"interval": {
"startTime": "2026-09-03T11:20:00Z",
"endTime": "2026-09-03T11:50:00Z"
},
"exerciseType": "RUNNING"
}
},
{
"name": "users/111111256096816351/dataTypes/exercise/dataPoints/4389052750481144696",
"exercise": {
"interval": {
"startTime": "2026-09-03T11:00:00Z",
"endTime": "2026-09-03T11:30:00Z"
},
"exerciseType": "RUNNING"
}
}
]
}Đã đối chiếu
GET https://health.googleapis.com/v4/users/me/dataTypes/exercise/dataPoints:reconcile Authorization: Bearer access-token Accept: application/json
{
"dataPoints": [
{
"dataPointName": "users/111111256096816351/dataTypes/exercise/dataPoints/7797422996486764704",
"exercise": {
"interval": {
"startTime": "2026-09-03T11:20:00Z",
"endTime": "2026-09-03T11:50:00Z"
},
"exerciseType": "RUNNING"
}
}
]
}Quá trình đối chiếu sẽ giải quyết các phiên xung đột bằng cách loại bỏ dữ liệu trùng lặp và chọn bản ghi có thẩm quyền thay vì tổng hợp một khoảng thời gian nhân tạo (chẳng hạn như 11:00:00Z đến 11:50:00Z). Phản hồi đã đối chiếu sẽ trả về điểm dữ liệu chiến thắng (7797422996486764704) cùng với khoảng thời gian được ghi lại ban đầu (11:20:00Z đến 11:50:00Z), duy trì tính toàn vẹn của số liệu đo từ xa và chỉ số được đo của phiên đó.
Lọc dữ liệu
Để truy xuất các tập hợp con cụ thể của bản ghi điểm dữ liệu khớp với các tiêu chí như khoảng thời gian, ngày hoặc thời gian quan sát, hãy sử dụng điểm cuối list hoặc reconcile với tham số filter.
Để biết các nguyên tắc chi tiết, quy tắc định dạng, lỗi xác thực và ví dụ về truy vấn, hãy xem Hướng dẫn lọc dữ liệu.
Lọc theo họ nguồn dữ liệu
Để tách biệt hoặc tổng hợp dữ liệu từ các loại nguồn cụ thể (ví dụ: thiết bị đeo thực tế so với mục nhập thủ công), hãy sử dụng tham số dataSourceFamily.
Để biết hướng dẫn chi tiết, các họ được hỗ trợ, cũng như ví dụ về yêu cầu và phản hồi cho reconcile, rollUp và dailyRollUp, hãy xem phần Lọc theo họ nguồn dữ liệu trong hướng dẫn Lọc dữ liệu.
Lọc dữ liệu theo thời gian bắt đầu dân sự của khoảng thời gian
Sử dụng điểm cuối list với tham số filter để lọc dữ liệu theo thời gian dân sự hoặc một khoảng thời gian.
Ví dụ:
Yêu cầu
GET https://health.googleapis.com/v4/users/me/dataTypes/steps/dataPoints?filter=steps.interval.civil_start_time >= "2026-03-04T00:00:00" Authorization: Bearer access-token Accept: application/json
Phản hồi
{
"dataPoints": [
{
"dataSource": {
"recordingMethod": "PASSIVELY_MEASURED",
"device": {
"manufacturer": "",
"displayName": "Charge 6"
},
"platform": "FITBIT"
},
"steps": {
"interval": {
"startTime": "2026-03-04T07:05:00Z",
"startUtcOffset": "0s",
"endTime": "2026-03-04T07:06:00Z",
"endUtcOffset": "0s",
"civilStartTime": {
"date": {
"year": 2026,
"month": 3,
"day": 4
},
"time": {
"hours": 7,
"minutes": 5
}
},
"civilEndTime": {
"date": {
"year": 2026,
"month": 3,
"day": 4
},
"time": {
"hours": 7,
"minutes": 6
}
}
},
"count": "40"
}
...
],
"nextPageToken": "Xm5h-6L0viZxIlRuQjp5bml1bZ4ve2dhNmZvMnt4Yn7qIGQhbHN3YQ"
}Lọc dữ liệu theo thời gian thực của một mẫu quan sát
Sử dụng điểm cuối list với tham số filter để lọc dữ liệu theo thời gian thực quan sát mẫu.
Ví dụ:
Yêu cầu
GET https://health.googleapis.com/v4/users/me/dataTypes/body-fat/dataPoints?filter=body_fat.sample_time.physical_time >= "2026-03-01T00:00:00Z" Authorization: Bearer access-token Accept: application/json
Phản hồi
{
"dataPoints": [
{
"name": "users/123456789/dataTypes/body-fat/dataPoints/1234567890",
"dataSource": {
"recordingMethod": "UNKNOWN",
"application": {
"packageName": "",
"webClientId": "",
"googleWebClientId": "google-web-client-id"
},
"platform": "GOOGLE_WEB_API"
},
"bodyFat": {
"sampleTime": {
"physicalTime": "2026-03-10T10:00:00Z",
"utcOffset": "0s",
"civilTime": {
"date": {
"year": 2026,
"month": 3,
"day": 10
},
"time": {
"hours": 10
}
}
},
"percentage": 20
}
}
"nextPageToken": ""
}Lọc và tổng hợp theo họ nguồn dữ liệu
Nhóm nguồn dữ liệu là một nhóm nguồn dữ liệu hợp lý (chẳng hạn như đồng hồ thông minh, ứng dụng di động hoặc mục nhập thủ công). Nhờ đó, bạn có thể tách biệt hoặc tổng hợp dữ liệu từ các loại nguồn cụ thể (ví dụ: thiết bị đeo thực tế so với mục nhập thủ công).
Các điểm cuối reconcile, rollUp và dailyRollUp đều hỗ trợ tham số dataSourceFamily. Cơ chế truyền phụ thuộc vào điểm cuối:
| Điểm cuối (phương thức HTTP) | Cơ chế |
|---|---|
reconcile (GET) |
Truyền dataSourceFamily dưới dạng tham số truy vấn URL. |
rollUp (POST) |
Truyền dataSourceFamily dưới dạng một trường trong nội dung yêu cầu JSON. |
dailyRollUp (POST) |
Truyền dataSourceFamily dưới dạng một trường trong nội dung yêu cầu JSON. |
Các nhóm nguồn dữ liệu được hỗ trợ
Bảng sau đây mô tả các giá trị dataSourceFamily được hỗ trợ:
| Phương thức | Mô tả |
|---|---|
users/me/dataSourceFamilies/all-sources |
Giá trị mặc định. Trả về các điểm dữ liệu được đối chiếu trên tất cả các nguồn dữ liệu đã đăng ký của bên thứ nhất (1P) và bên thứ ba (3P). Dữ liệu ứng dụng của bên thứ ba sẽ được trả về bằng lựa chọn này (chẳng hạn như số bước của đồng hồ thông minh + số bước của ứng dụng bên thứ ba + số bước của điện thoại di động + số bước nhập thủ công). |
users/me/dataSourceFamilies/google-wearables |
Bao gồm dữ liệu do các thiết bị theo dõi của Google và Fitbit ghi lại (chẳng hạn như thiết bị theo dõi đeo được của Fitbit và Pixel Watch). Không bao gồm dữ liệu được ghi nhật ký theo cách thủ công và dữ liệu do điện thoại ước tính. Hãy sử dụng lựa chọn này khi quá trình tích hợp của bạn yêu cầu dữ liệu đo từ xa thô của cảm biến được phần cứng thiết bị đeo ghi lại trực tiếp. |
users/me/dataSourceFamilies/google-sources |
Bao gồm các nguồn của bên thứ nhất là Google và Fitbit. Dữ liệu này bao gồm hồ sơ thiết bị theo dõi thể chất, dữ liệu từ Health Connect và mọi mục nhập thủ công được ghi lại thông qua các ứng dụng của bên thứ nhất (chẳng hạn như ứng dụng Fitbit hoặc Google Fit). |
Để nhận một luồng dữ liệu đã đối chiếu từ một nhóm nguồn dữ liệu cụ thể, hãy gọi điểm cuối reconcile bằng tham số truy vấn dataSourceFamily.
Ví dụ: yêu cầu GET sau đây sẽ tìm nạp giấc ngủ được thiết bị theo dõi ghi lại cho ngày sau ngày 2026-03-03:
Yêu cầu
GET https://health.googleapis.com/v4/users/me/dataTypes/sleep/dataPoints:reconcile?dataSourceFamily=users/me/dataSourceFamilies/google-wearables&filter=sleep.interval.civil_end_time >= "2026-03-03" Authorization: Bearer access-token Accept: application/json
Phản hồi
{
"dataPoints": [
{
"name": "users/2515055256096816351/dataTypes/sleep/dataPoints/2724123844716220216",
"dataSource": {
"recordingMethod": "DERIVED",
"device": {
"displayName": "Charge 6"
},
"platform": "FITBIT"
},
"sleep": {
"interval": {
"startTime": "2026-03-03T20:57:30Z",
"startUtcOffset": "0s",
"endTime": "2026-03-04T04:41:30Z",
"endUtcOffset": "0s"
},
"type": "STAGES",
"stages": [
{
"startTime": "2026-03-03T20:57:30Z",
"startUtcOffset": "0s",
"endTime": "2026-03-03T20:59:30Z",
"endUtcOffset": "0s",
"type": "AWAKE",
"createTime": "2026-03-04T04:43:40.937183Z",
"updateTime": "2026-03-04T04:43:40.937183Z"
},
{
"startTime": "2026-03-04T04:07:30Z",
"startUtcOffset": "0s",
"endTime": "2026-03-04T04:41:30Z",
"endUtcOffset": "0s",
"type": "AWAKE",
"createTime": "2026-03-04T04:43:40.937183Z",
"updateTime": "2026-03-04T04:43:40.937183Z"
}
],
"metadata": {
"stagesStatus": "SUCCEEDED",
"processed": true,
"main": true
},
"summary": {
"minutesInSleepPeriod": "464",
"minutesAfterWakeUp": "0",
"minutesToFallAsleep": "0",
"minutesAsleep": "407",
"minutesAwake": "57",
"stagesSummary": [
{
"type": "AWAKE",
"minutes": "56",
"count": "12"
},
{
"type": "LIGHT",
"minutes": "198",
"count": "19"
},
{
"type": "DEEP",
"minutes": "114",
"count": "10"
},
{
"type": "REM",
"minutes": "94",
"count": "4"
}
]
},
"createTime": "2026-03-04T04:43:40.337983Z",
"updateTime": "2026-03-04T04:43:40.937183Z"
}
}
],
"nextPageToken": ""
}Để tổng hợp các điểm dữ liệu trong một khoảng thời gian cụ thể bị giới hạn ở một họ nguồn dữ liệu cụ thể, hãy gọi điểm cuối rollUp và truyền trường dataSourceFamily vào nội dung yêu cầu JSON.
Yêu cầu POST sau đây truy vấn số bước đi trong ngày theo khoảng thời gian hằng giờ (3600s), được tổng hợp riêng từ các thiết bị đeo:
Yêu cầu
POST https://health.googleapis.com/v4/users/me/dataTypes/steps/dataPoints:rollUp
Authorization: Bearer access-token
Accept: application/json
{
"range": {
"startTime": "2026-07-29T00:00:00Z",
"endTime": "2026-07-29T23:59:59Z"
},
"windowSize": "3600s",
"dataSourceFamily": "users/me/dataSourceFamilies/google-wearables"
}Phản hồi
{
"rollupDataPoints": [
{
"startTime": "2026-07-29T08:00:00Z",
"endTime": "2026-07-29T09:00:00Z",
"steps": {
"countSum": "1200"
}
},
{
"startTime": "2026-07-29T09:00:00Z",
"endTime": "2026-07-29T10:00:00Z",
"steps": {
"countSum": "3450"
}
}
]
}Để tổng hợp các điểm dữ liệu hằng ngày cho một họ nguồn cụ thể, hãy gọi điểm cuối dailyRollUp và truyền trường dataSourceFamily vào nội dung yêu cầu.
Ví dụ: yêu cầu sau đây tính toán các bản tổng hợp hằng ngày cho số bước của người dùng, bao gồm tất cả các nguồn của Google và Fitbit (thiết bị đeo + mục nhập thủ công):
Yêu cầu
POST https://health.googleapis.com/v4/users/me/dataTypes/steps/dataPoints:dailyRollUp
Authorization: Bearer access-token
Accept: application/json
{
"range": {
"start": {
"date": {
"year": 2026,
"month": 7,
"day": 28
},
"time": {
"hours": 0,
"minutes": 0,
"seconds": 0,
"nanos": 0
}
},
"end": {
"date": {
"year": 2026,
"month": 7,
"day": 30
},
"time": {
"hours": 0,
"minutes": 0,
"seconds": 0,
"nanos": 0
}
}
},
"windowSizeDays": 1,
"dataSourceFamily": "users/me/dataSourceFamilies/google-sources"
}Phản hồi
{
"rollupDataPoints": [
{
"civilStartTime": {
"date": {
"year": 2026,
"month": 7,
"day": 28
},
"time": {}
},
"civilEndTime": {
"date": {
"year": 2026,
"month": 7,
"day": 28
},
"time": {
"hours": 23,
"minutes": 59,
"seconds": 59
}
},
"steps": {
"countSum": "8430"
}
},
{
"civilStartTime": {
"date": {
"year": 2026,
"month": 7,
"day": 29
},
"time": {}
},
"civilEndTime": {
"date": {
"year": 2026,
"month": 7,
"day": 29
},
"time": {
"hours": 23,
"minutes": 59,
"seconds": 59
}
},
"steps": {
"countSum": "11245"
}
}
]
}Tổng hợp các điểm dữ liệu trong một khoảng thời gian
Sử dụng điểm cuối rollUp để trả về tổng hợp các điểm dữ liệu dựa trên một khoảng thời gian tính bằng giây, trong phạm vi datetime dựa trên thời gian thực của người dùng (theo giờ UTC).
Khi gọi điểm cuối rollUp, hãy cung cấp nội dung yêu cầu đại diện cho phạm vi thời gian bắt buộc và windowSize. Xin lưu ý những yêu cầu sau đối với windowSize:
- Kích thước cửa sổ tối thiểu: Thời lượng
windowSizephải ít nhất là 1 giây ("1s"). Thời lượng dưới một giây, bằng 0 hoặc âm sẽ bị từ chối bằng400 Bad Request(INVALID_ROLLUP_WINDOW). - Căn chỉnh độ phân giải bộ nhớ: Để tránh phân phối không đồng đều dữ liệu tổng hợp trên các nhóm nhỏ, hãy chọn
windowSizebằng hoặc lớn hơn độ phân giải bộ nhớ cơ bản của loại dữ liệu (chẳng hạn như"60s"cho khoảng thời gian 1 phút). Để biết thông tin chi tiết, hãy xem phần Kích thước cửa sổ tổng hợp và độ phân giải bộ nhớ cơ bản.
Ví dụ: để tổng hợp số bước theo khoảng thời gian 1 phút (60s):
Yêu cầu
POST https://health.googleapis.com/v4/users/me/dataTypes/steps/dataPoints:rollUp
Authorization: Bearer access-token
Accept: application/json
{
"range": {
"startTime": "2026-02-17T17:00:00Z",
"endTime": "2026-02-17T17:59:59Z"
},
"windowSize": "60s"
}Phản hồi
{
"rollupDataPoints": [
{
"startTime": "2026-02-17T17:55:00Z",
"endTime": "2026-02-17T17:56:00Z",
"steps": {
"countSum": "72"
}
},
{
"startTime": "2026-02-17T17:54:00Z",
"endTime": "2026-02-17T17:55:00Z",
"steps": {
"countSum": "85"
}
},
...
]
}Tổng hợp dữ liệu trong một ngày hoặc nhiều ngày
Bạn nên sử dụng dailyRollUp
điểm cuối khi muốn tổng hợp dữ liệu trong một hoặc nhiều ngày, còn gọi là windowSize. Cung cấp khoảng thời gian dân sự đóng-mở cho khoảng thời gian bắt buộc trong nội dung yêu cầu. Tuỳ thuộc vào loại dữ liệu, bạn sẽ nhận được tổng hoặc giá trị trung bình trong khoảng thời gian đó.
Ví dụ:
Yêu cầu
POST https://health.googleapis.com/v4/users/me/dataTypes/steps/dataPoints:dailyRollUp
Authorization: Bearer access-token
Accept: application/json
{
"range": {
"start": {
"date": {
"year": 2026,
"month": 2,
"day": 26
},
"time": {
"hours": 0,
"minutes": 0,
"seconds": 0,
"nanos": 0
}
},
"end": {
"date": {
"year": 2026,
"month": 2,
"day": 26
},
"time": {
"hours": 23,
"minutes": 59,
"seconds": 59,
"nanos": 0
}
}
},
"windowSizeDays": 1
}Phản hồi
{
"rollupDataPoints": [
{
"civilStartTime": {
"date": {
"year": 2026,
"month": 2,
"day": 26
},
"time": {}
},
"civilEndTime": {
"date": {
"year": 2026,
"month": 2,
"day": 26
},
"time": {
"hours": 23,
"minutes": 59,
"seconds": 59
}
},
"steps": {
"countSum": "3822"
}
}
]
}Phân nhóm khi phạm vi không phải là bội số của kích thước cửa sổ
Nếu phạm vi được yêu cầu không phải là bội số chính xác của windowSize (hoặc windowSizeDays), thì nhóm cuối cùng theo thứ tự thời gian sẽ bị cắt bớt tại điểm cuối trên của phạm vi và sẽ có thời lượng ngắn hơn kích thước cửa sổ. API chấp nhận yêu cầu của bạn mà không sửa đổi, đồng thời không thực hiện bất kỳ thao tác làm tròn, thay đổi thời gian hoặc nội suy dữ liệu nào.
Để bao gồm toàn bộ phạm vi được yêu cầu, API này sử dụng phép chia làm tròn lên để tính tổng số cửa sổ tổng hợp:
Number of windows = ceiling(Range duration / Window size)
Mỗi nhóm bắt đầu tuần tự từ đầu dải ô. Nếu việc thêm một cửa sổ có kích thước đầy đủ khác sẽ kéo dài quá thời gian kết thúc bạn yêu cầu, thì cửa sổ cuối cùng sẽ bị cắt (giới hạn) tại thời gian kết thúc phạm vi.
Cách hoạt động của tính năng phân giỏ
Khi yêu cầu tổng hợp với các dải không chia hết, API sẽ áp dụng các quy tắc sau:
- Việc phân nhóm bắt đầu từ đầu dải ô mà bạn yêu cầu (
range.startTimehoặcrange.start) và tiến về phía trước theo kích thước cửa sổ (windowSizehoặcwindowSizeDays). - Nhóm thời gian theo trình tự cuối cùng được cố định ở cuối phạm vi bạn yêu cầu (
range.endTimehoặcrange.end), tức là nhóm này có thời lượng ngắn hơn so với kích thước cửa sổ được yêu cầu. - Các đối tượng
RollupDataPointhoặcDailyRollupDataPointđược trả về sẽ chỉ định rõ dấu thời gian bắt đầu và kết thúc của riêng chúng. Bạn có thể dùng các đối tượng này để kiểm tra thời lượng thực tế của vùng chứa bị cắt bớt. - Vì API trả về dữ liệu tổng hợp theo thứ tự thời gian đảo ngược (mới nhất trước), nên nhóm thời gian cuối cùng (là nhóm bị cắt ngắn) sẽ xuất hiện dưới dạng phần tử đầu tiên (
index 0) trong danh sách được trả về.
Tình huống: Phạm vi 12 phút với cửa sổ 5 phút
Giả sử một ứng dụng yêu cầu tổng hợp trong khoảng thời gian 12 phút với windowSize là 5 phút:
range.startTime:10:00:00range.endTime:10:12:00(Tổng thời lượng: 12 phút)windowSize:5 minutes
Vì 12 phút không phải là bội số của 5 phút (12 = 5 * 2 + 2), nên API sẽ chấp nhận yêu cầu và tính số lượng cửa sổ là ceiling(12 / 5) = 3.
Thao tác này tạo ra 3 nhóm thời gian theo thứ tự thời gian sau:
- Nhóm 1:
[10:00:00, 10:05:00)– Thời lượng: 5 phút (toàn bộ cửa sổ) - Nhóm 2:
[10:05:00, 10:10:00)– Thời lượng: 5 phút (toàn bộ cửa sổ) - Nhóm 3 (Bị cắt):
[10:10:00, 10:12:00)– Thời lượng: 2 phút (bị cắt tạirange.endTime)
Tác động đến các giá trị tổng hợp
Vì khoảng thời gian của cửa sổ cuối cùng ngắn hơn, nên các chỉ số cộng (chẳng hạn như tổng số hoặc số bước) sẽ thấp hơn trong nhóm bị cắt chỉ do thời gian theo dõi ngắn hơn.
Nếu người dùng đi bộ với tốc độ ổn định là 100 bước mỗi phút trong toàn bộ khoảng thời gian 12 phút này:
- Nhóm 1 (10:00 – 10:05): 500 bước (5 phút × 100 bước/phút)
- Nhóm 2 (10:05 – 10:10): 500 bước (5 phút × 100 bước/phút)
- Nhóm 3 (10:10 – 10:12): 200 bước (2 phút × 100 bước/phút)
Ví dụ về phản hồi API cho thấy thứ tự
Vì API trả về kết quả theo thứ tự thời gian đảo ngược, nên nhóm bị cắt sẽ xuất hiện dưới dạng phần tử đầu tiên trong danh sách được trả về:
{
"rollupDataPoints": [
{
"startTime": "2026-08-20T10:10:00Z",
"endTime": "2026-08-20T10:12:00Z",
"steps": {
"countSum": "200"
}
},
{
"startTime": "2026-08-20T10:05:00Z",
"endTime": "2026-08-20T10:10:00Z",
"steps": {
"countSum": "500"
}
},
{
"startTime": "2026-08-20T10:00:00Z",
"endTime": "2026-08-20T10:05:00Z",
"steps": {
"countSum": "500"
}
}
]
}
Kích thước cửa sổ tổng hợp và độ phân giải của bộ nhớ cơ bản
Mặc dù điểm cuối rollUp chấp nhận mọi windowSize từ 1 giây trở lên, nhưng các loại dữ liệu khác nhau sẽ ghi lại và duy trì các phép đo ở các tốc độ lấy mẫu hoặc khoảng thời gian khác nhau trong bộ nhớ cơ bản. Ví dụ: các chỉ số hoạt động thể chất của thiết bị đeo như steps, distance, active-minutes và active-energy-burned thường được ghi lại theo khoảng thời gian 1 phút (60s).
Khi tổng hợp các loại dữ liệu theo khoảng thời gian, điểm cuối rollUp sẽ đặt từng điểm dữ liệu đã ghi vào nhóm chứa startTime của điểm dữ liệu. API này không phân đoạn, nội suy hoặc phân phối dữ liệu khoảng thời gian trên các nhóm khoảng thời gian phụ.
Nếu bạn chỉ định một windowSize nhỏ hơn khoảng thời gian lưu trữ dữ liệu cơ bản (ví dụ: yêu cầu một khoảng thời gian 10 giây cho steps được lưu trữ trong khoảng thời gian 1 phút):
- Nhóm phụ đầu tiên khớp với
startTimecủa khoảng thời gian (ví dụ:10:00:00đến10:00:10) sẽ nhận được toàn bộ số lượt đếm tích luỹ trong phút đó (ví dụ: tất cả 100 bước được ghi lại trong phút đó). - Các nhóm nhỏ còn lại trong cùng một phút đó (
10:00:10đến10:00:20,10:00:20đến10:00:30, v.v.) không nhận được điểm dữ liệu nào, vì không có khoảng thời gian nào bắt đầu trong các cửa sổ đó.
Điều này dẫn đến dữ liệu "đột biến" khi giá trị của toàn bộ khoảng thời gian tập trung vào cửa sổ phụ đầu tiên.
Để thu được các giá trị tổng hợp có ý nghĩa và được phân phối đồng đều, hãy luôn đặt windowSize thành khoảng thời gian bằng hoặc lớn hơn độ phân giải bộ nhớ cơ bản của loại dữ liệu đích (ví dụ: 60s hoặc lớn hơn cho steps). Để biết độ phân giải bộ nhớ và cửa sổ tổng hợp tối thiểu được đề xuất cho từng loại dữ liệu, hãy xem tài liệu tham khảo các loại dữ liệu của Google Health API.
Cập nhật dữ liệu sức khoẻ của người dùng
Sử dụng điểm cuối patch để cập nhật dữ liệu sức khoẻ của người dùng.
Điểm cuối patch sẽ cập nhật một bản ghi hiện có dựa trên giá trị nhận dạng được chỉ định trong URL yêu cầu. Cung cấp giá trị nhận dạng của một điểm dữ liệu đã được chèn trước đó. API sẽ ghi đè bản ghi hiện có.
Chủ sở hữu bản ghi cũng có thể cập nhật dấu thời gian khoảng thời gian của một điểm dữ liệu (startTime và endTime) hoặc được truyền từ các nền tảng nguồn như Health Connect. Để biết thông tin chi tiết về khả năng thay đổi dấu thời gian, hãy xem Hướng dẫn quản lý dữ liệu. Để xem ví dụ về cách cập nhật dấu thời gian của khoảng thời gian, hãy xem phần Cập nhật dấu thời gian của khoảng thời gian cho dữ liệu hiện có.
Trường hợp sử dụng giá trị nhận dạng điểm dữ liệu
Mã nhận dạng điểm dữ liệu là yếu tố cần thiết trong các trường hợp sau:
- Thông tin cập nhật có mục tiêu: Để cập nhật một chỉ số cụ thể, hãy cung cấp giá trị nhận dạng của chỉ số đó trong yêu cầu
patch. - Xoá: Việc giữ lại giá trị nhận dạng cho phép ứng dụng của bạn xoá bản ghi sau này bằng cách sử dụng điểm cuối
batchDelete.
Sau đây là ví dụ về trường hợp người dùng cập nhật lượng mỡ trong cơ thể trên một chiếc cân có tên là "HumanScale" của công ty "Scales R Us". Chỉ số lượng mỡ trong cơ thể mới của người dùng là 20% cho ngày 10/3/2026:
Yêu cầu
PATCH https://health.googleapis.com/v4/users/me/dataTypes/body-fat/dataPoints/1234567890
Authorization: Bearer access-token
Content-Type: application/json
{
"name": "users/me/dataTypes/body-fat/dataPoints/1234567890",
"dataSource": {
"recordingMethod": "ACTIVELY_MEASURED",
"device": {
"formFactor": "SCALE",
"manufacturer": "Scales R Us",
"displayName": "HumanScale"
}
},
"bodyFat": {
"sampleTime": {
"physicalTime": "2026-03-10T10:00:00Z"
},
"percentage": 20
}
}Phản hồi
{
"done": true,
"response": {
"@type": "type.googleapis.com/google.devicesandservices.health.v4main.DataPoint",
"name": "users/123456789/dataTypes/body-fat/dataPoints/1234567890",
"dataSource": {
"recordingMethod": "ACTIVELY_MEASURED",
"device": {
"formFactor": "SCALE",
"manufacturer": "Scales R Us",
"displayName": "HumanScale"
},
"application": {
"googleWebClientId": "618308034039.apps.googleusercontent.com"
},
"platform": "GOOGLE_WEB_API"
},
"bodyFat": {
"sampleTime": {
"physicalTime": "2026-03-10T10:00:00Z"
},
"percentage": 20
}
}
}Cập nhật dấu thời gian của khoảng thời gian cho dữ liệu hiện có
Để cập nhật startTime hoặc endTime của một điểm dữ liệu khoảng thời gian hiện có, hãy gửi yêu cầu PATCH đến URI tài nguyên của điểm dữ liệu. Chỉ người tạo hoặc chủ sở hữu ban đầu của bản ghi mới có thể sửa đổi các trường của bản ghi đó. Các ứng dụng không thể chỉnh sửa những điểm dữ liệu mà chúng không tạo.
Để biết thông tin cơ bản về khả năng thay đổi dấu thời gian, các bản cập nhật từ Health Connect và các tác động của việc lưu vào bộ nhớ đệm, hãy xem Hướng dẫn quản lý dữ liệu.
Ví dụ sau đây minh hoạ một ứng dụng chủ sở hữu cập nhật dấu thời gian theo khoảng thời gian của nhật ký dữ liệu hiện có bằng cách sử dụng điểm cuối patch:
Yêu cầu
PATCH https://health.googleapis.com/v4/users/me/dataTypes/hydration-log/dataPoints/4093039283164890826
Authorization: Bearer access-token
Content-Type: application/json
{
"hydrationLog": {
"interval": {
"startTime": "2026-09-03T10:05:00Z",
"endTime": "2026-09-03T10:19:59Z"
},
"amountConsumed": {
"milliliters": 350
}
}
}Phản hồi
{
"done": true,
"response": {
"@type": "type.googleapis.com/google.devicesandservices.health.v4.DataPoint",
"name": "users/111111256096816351/dataTypes/hydration-log/dataPoints/4093039283164890826",
"hydrationLog": {
"interval": {
"startTime": "2026-09-03T10:05:00Z",
"endTime": "2026-09-03T10:19:59Z",
"civilStartTime": {
"date": {
"year": 2026,
"month": 9,
"day": 3
},
"time": {
"hours": 10,
"minutes": 5
}
},
"civilEndTime": {
"date": {
"year": 2026,
"month": 9,
"day": 3
},
"time": {
"hours": 10,
"minutes": 19,
"seconds": 59
}
}
},
"amountConsumed": {
"milliliters": 350
}
}
}
}Ghi nhật ký về một đồ ăn
Để ghi lại một mặt hàng thực phẩm, hãy gửi yêu cầu POST đến điểm cuối nutrition-log dataPoints. Nội dung yêu cầu chứa một DataPoint có đối tượng nutritionLog.
Để biết thêm thông tin, hãy xem Hướng dẫn về dinh dưỡng.
Ví dụ:
Yêu cầu
POST https://health.googleapis.com/v4/users/me/dataTypes/nutrition-log/dataPoints
Authorization: Bearer access-token
Content-Type: application/json
{
"nutritionLog": {
"interval": {
"startTime": "2026-06-16T12:00:00Z",
"endTime": "2026-06-16T12:30:00Z"
},
"foodDisplayName": "Banana",
"mealType": "LUNCH",
"energy": {
"kcal": 105
},
"totalCarbohydrate": {
"grams": 27
},
"totalFat": {
"grams": 0.3
}
}
}Phản hồi
{
"done": true,
"response": {
"@type": "type.googleapis.com/google.devicesandservices.health.v4.DataPoint",
"name": "users/123456789/dataTypes/nutrition-log/dataPoints/567890",
"dataSource": {
"recordingMethod": "ACTIVELY_MEASURED",
"platform": "GOOGLE_WEB_API"
},
"nutritionLog": {
"interval": {
"startTime": "2026-06-16T12:00:00Z",
"startUtcOffset": "0s",
"endTime": "2026-06-16T12:30:00Z",
"endUtcOffset": "0s"
},
"energy": {
"kcal": 105
},
"totalCarbohydrate": {
"grams": 27
},
"totalFat": {
"grams": 0.3
},
"mealType": "LUNCH",
"foodDisplayName": "Banana"
}
}
}Xoá dữ liệu sức khoẻ của người dùng
Sử dụng phương thức batchDelete để xoá một mảng dữ liệu ứng dụng Fitbit của người dùng.
Sau đây là ví dụ về trường hợp người dùng đã từng ghi lại lượng mỡ trong cơ thể trên cân nhưng muốn xoá bản ghi đó. Sử dụng user-id và data-point-id từ thao tác chèn ban đầu:
Yêu cầu
POST https://health.googleapis.com/v4/users/me/dataTypes/body-fat/dataPoints:batchDelete
Authorization: Bearer access-token
Accept: application/json
content-length: 93
{
"names": [
"users/123456789/dataTypes/body-fat/dataPoints/1234567890"
]
}Phản hồi
{
"done": true,
"response": {
"@type": "type.googleapis.com/google.devicesandservices.health.v4main.BatchDeleteDataPointsResponse"
}
}Tìm thông tin về thiết bị
Sử dụng điểm cuối list để truy xuất danh sách các thiết bị được ghép nối với tài khoản của người dùng. Thông tin này bao gồm thông tin về kiểu máy của thiết bị (deviceVersion) và lần gần đây nhất thiết bị đồng bộ hoá với ứng dụng di động Google Health (lastSyncTime).
Thông tin cấu hình danh sách và thông tin đồng bộ hoá rất hữu ích cho việc khắc phục sự cố đồng bộ hoá hoặc tìm nạp dữ liệu cũ kể từ lần đồng bộ hoá gần nhất.
Ví dụ:
Yêu cầu
GET https://health.googleapis.com/v4/users/me/pairedDevices Authorization: Bearer access-token Accept: application/json
Phản hồi
{
"pairedDevices": [
{
"name": "users/me/pairedDevices/123456",
"deviceType": "TRACKER",
"batteryStatus": "High",
"batteryLevel": 88,
"lastSyncTime": "2026-03-04T07:05:00Z",
"deviceVersion": "Charge 6",
"macAddress": "00:11:22:33:44:55",
"features": [
"STEPS",
"HEART_RATE"
]
}
]
}Truy vấn dữ liệu trong quá khứ
Một trong những lợi ích chính của Google Health API là khả năng theo dõi hiệu suất của người dùng và giám sát các chỉ số sức khoẻ của họ trong thời gian dài. Bạn có thể truy vấn dữ liệu của người dùng từ thời điểm dữ liệu được ghi lại; API không áp đặt bất kỳ giới hạn hoặc quy định hạn chế nào về lượng dữ liệu trong quá khứ mà ứng dụng của bạn có thể sử dụng.
Tuy nhiên, việc truy vấn dữ liệu cũ vẫn phải chịu sự điều chỉnh của giới hạn tốc độ tiêu chuẩn. Để quản lý độ ổn định của hệ thống và ngăn chặn tải trọng quá mức, Google Health API sử dụng tính năng phân trang tự động với kích thước trang dành riêng cho từng điểm cuối. Hãy lưu ý các ranh giới và hành vi sau:
- Phân trang tự động: Nếu bạn truy vấn một khoảng dữ liệu dài, API sẽ chỉ trả về trang kết quả đầu tiên (tối đa là giới hạn kích thước trang) cho điểm cuối đó, cùng với
nextPageToken. Bạn phải sử dụngnextPageTokenđể yêu cầu các trang tiếp theo. - Kích thước trang thay đổi: Giới hạn tối đa phụ thuộc vào điểm cuối và loại dữ liệu. Đối với hầu hết các loại dữ liệu, kích thước trang được giới hạn tối đa là 10.000.
Tuy nhiên, đối với một số kiểu dữ liệu như
exercisevàsleep, kích thước trang mặc định và tối đa được giới hạn ở mức 25. Ví dụ: nếu một ứng dụng yêu cầu tất cả dữ liệu giấc ngủ trong 10 năm qua, thì API vẫn chỉ trả về 25 phiên ngủ trên trang đầu tiên. - Các quy định hạn chế về phạm vi ngày tổng hợp: Đối với các điểm cuối tổng hợp và tổng kết dữ liệu (chẳng hạn như
rollUpvàdailyRollUp), phạm vi ngày truy vấn sẽ bị hạn chế dựa trên loại dữ liệu:- Phạm vi tối đa là 14 ngày đối với
calories-in-heart-rate-zone,heart-rate,active-minutesvàtotal-calories. - Phạm vi tối đa là 90 ngày cho tất cả các loại dữ liệu tổng hợp khác.
- Phạm vi tối đa là 14 ngày đối với
Tuỳ thuộc vào lượng dữ liệu trước đây mà ứng dụng của bạn cần, việc truy xuất toàn bộ tập dữ liệu sẽ yêu cầu phân trang tuần tự qua các trang. Hãy lưu ý điều này khi thiết kế quy trình đồng bộ hoá dữ liệu của ứng dụng.
Để đảm bảo hiệu suất tối ưu và tránh lỗi API, hãy làm theo các nguyên tắc sau khi truy vấn dữ liệu cũ:
Đồng bộ hoá dữ liệu theo giai đoạn (tải nóng so với tải lạnh)
- Tải "nóng" ban đầu: Chỉ tìm nạp và hiển thị dữ liệu của 7 đến 14 ngày gần đây nhất trong trình tự tải chính. Điều này đảm bảo người dùng thấy dữ liệu ngay lập tức mà không cần chờ các truy vấn chạy trong thời gian dài.
- Tải "lạnh" trong nền: Uỷ quyền truy xuất dữ liệu cũ trong quá khứ cho một hàng đợi không đồng bộ, có mức độ ưu tiên thấp hơn hoặc quy trình trong nền sau khi giao diện người dùng chính được kết xuất.
Phân đoạn truy vấn để tổng hợp
- Vì các điểm cuối tổng hợp và tổng hợp hằng ngày áp dụng giới hạn tối đa về phạm vi ngày (14 hoặc 90 ngày, tuỳ thuộc vào loại dữ liệu), nên bạn phải chia các truy vấn tổng hợp lớn trong quá khứ thành các khoảng thời gian nhỏ hơn, tuần tự trong các giới hạn này.
- Xử lý hàng loạt hoặc theo trình tự các truy vấn phụ này một cách an toàn để tuân thủ giới hạn về mức độ đồng thời và duy trì các chỉ báo tiến trình ổn định trên giao diện người dùng.
Tận dụng các bản tổng hợp được tổng hợp trước
Cấu trúc lại trang tổng quan và biểu đồ xu hướng để sử dụng các điểm cuối tóm tắt được tổng hợp trước (chẳng hạn như DailyRollUpDataPoints). Điều này sẽ giảm đáng kể chi phí tính toán ở phần phụ trợ và thời gian truyền mạng cho máy khách.
Xử lý lỗi linh hoạt (thử lại thông minh)
- Triển khai quy trình xử lý thời gian đợi luỹ thừa nghiêm ngặt khi gặp phải giới hạn về tốc độ (
429 Too Many Requests) và thời gian chờ của cổng máy chủ (504 Gateway Timeout). Đừng bao giờ thử lại ngay lập tức các tải trọng lớn không thành công. Việc thử lại ngay lập tức sẽ làm tăng tình trạng tắc nghẽn ở phần phụ trợ và làm trầm trọng thêm tình trạng suy giảm hệ thống.