Conventions
Daily Summary Data
Activities serve both as an event and a daily aggregation of data. The difference is the summary flag. For items where the summary flag is enabled, the date associated with that item should be midnight UTC. The data should be the daily summary. Only one summary per day is allowed. When uploading, you must send the entire data not just the delta.
Character Sets
All requests to FitnessSyncer should be in the UTF-8 character set.
Language
FitnessSyncer accepts and supports the Accept-Language header and will produce the appropriate content for the user. FitnessSyncer currently supports the following languages.
- cs: Czech
- da: Danish
- de: German
- el: Greek
- en: English
- es: Spanish
- fi: Finnish
- fr: French
- hr: Croatian
- hu: Hungarian
- id: Indonesian
- it: Italian
- ja: Japanese
- ko: Korean
- nl: Dutch
- no: Norwegian
- pl: Polish
- pt-BR: Portuguese (Brazil)
- pt-PT: Portuguese (Portugal)
- ro: Romanian
- ru: Russian
- sk: Slovak
- sl: Slovenian
- sv: Swedish
- th: Thai
- tr: Turkish
- uk: Ukrainian
- zh: Chinese (Simplified)
- zh-Hant: Chinese (Traditional)
Please contact us if you would like us to add additional languages.
Compression
To save on bandwidth, you may request GZIP content. For downloads, include the Accept-Encoding: gzip header and include Content-Encoding: gzip header for uploads.
Edge Cases
You should URL encode the itemId that is sent as part of a URL in the cases that there are spaces, slashes, or other characters in it.
Rate Limits
FitnessSyncer may enforce rate limits based on your use-case. When a rate limit is exceeded, an HTTP Error Code of 429 will be returned; this response may include a Retry-After but is not guaranteed to, and if it is missing, you should retry after some time.
If you encounter regular rate limits, please contact us and we can assist in you adjusting your code to not encounter the issue or raise the limit.
Errors
The Error type is returned with each error, which includes an error_description. Here is a sample error:
{
"item": "sampleItemId",
"error_description": "Item was not found.",
"id": "sampleId",
"error": "NotFound",
"request_id": "sampleRequestId"
}Every error response carries this same body, whatever the status code. The status codes you may encounter are:
- 400: The request could not be understood because of a missing or malformed parameter, an unparsable body, or a value outside the range we accept.
- 401: The token is missing, invalid, or expired. Refresh the token or reauthenticate.
- 403: The token is valid, but this operation is not permitted; for example, updating a source your application was not granted, or modifying a Leaderboard you do not organize.
- 404: The source, destination, item, or Leaderboard referenced by the request does not exist.
- 406: The format requested through the Accept header is not available for this resource.
- 409: The request conflicts with the current state, such as a sync that is already in progress.
- 410: The resource existed but is no longer available, such as an expired Dashboard session.
- 429: A usage rate has been exceeded. See Rate Limits.
- 500: An unexpected failure on our side.
- 503: Servers are unavailable. Should very rarely if ever happen, but should be handled.
If you encounter regular problems with a request, you should send us the date and x-fs-srvr-id headers so that we can investigate.
All 500 errors should be retried with exponential backoff. A 400, 403, 404, or 406 will not succeed if retried unchanged.
FitnessSyncer changes DNS configuration to control certain aspects of our availability. Please ensure that your system does not cache DNS entries beyond our DNS TTL configuration. Failure to do so may result in request failures which are not covered by our SLA.
API Versions
FitnessSyncer API prefers to not do extensive versioning by instead append new data to our API. There are times which the changes that need to be done would result in misunderstanding of the data and in such cases, we apply some versioning.
The versions available are as follows:
- 2014-09-12: This is the original version
- 2026-08-09: This version changes the definition of sleep stages (adds
DEEP_SLEEPandRESTLESS), removes duration and offset from SleepEvent (earlier renamed to durationMinutes and offsetMinutes) and removes l2Minutes, l3Minutes from Sleep. - 2026-10-25: This version renames the
Cholesterolitem type toBloodPaneland carries the whole panel rather than the four lipids: aresultsarray of every analyte the laboratory reported, each with its own unit, reference range and flag, pluslabandreported. The four lipid properties are still sent beside it, so nothing that read them stops working. It also renames the unit preferenceglucoseMetrictobloodChemistryMetric, which is one stored value under both names rather than two: exactly one of them is read or emitted per version.
A request that names no version receives the oldest, which is what makes these renames safe for a client that has not been updated: on 2014-09-12 a blood panel still arrives as Cholesterol carrying only the four lipids, with no results, no performing laboratory and no reported date.
Every registered application declares which version of the API it understands. Prefer to use the latest version of the API.
This documentation describes the latest version, 2026-10-25, and every example in it is what that version sends.
Removed and Deprecated Fields
These fields are still sent to a client on an earlier version, so that it keeps working, and are not described anywhere else in this documentation. A field with no version is deprecated and will be removed in the next version.
| Field | Use Instead | Not Sent From |
|---|---|---|
SyncStatus.status | queueStatus | The next version |
SleepEvent.offset | offsetMinutes | 2026-08-09 |
SleepEvent.duration | durationMinutes | 2026-08-09 |
Sleep.l2SleepMinutes | lightSleepMinutes | 2026-08-09 |
Sleep.l3SleepMinutes | deepSleepMinutes | 2026-08-09 |
Future Proofing
This API will change over time. In general, the API will be augmented with new functionality and parameters. You should ignore any data that your application does not presently understand, such as new fields or new enumeration values.
In the event that the API must be changed in a non-backwards compatible way, you will be notified via the e-mail address registered with us.
It should also be noted that validation might change over time, which may introduce new errors in your application. Regular testing is encouraged.