A team shipped a recipe app with no health features. The upload failed:
Google Api Error: Invalid request - You must let us know whether your app includes any health features [10]
They had already filed the declaration saying the app has no health features. The problem was a library, added for something unrelated, that contributed android.permission.ACTIVITY_RECOGNITION to the merged manifest. That permission is in scope of Play’s health apps policy [3]. Their declaration and their binary disagreed, so the binary won.
That is the first thing to understand about Play’s health review, and the thing that makes it different from Apple’s: being a health app is determined by your manifest, not your intent.
The second thing is that there are two gates, and teams routinely conflate them. The architecture that put any of this in the binary is four authorization models.
Two gates
| Health apps declaration | Health Connect data type access | |
|---|---|---|
| Who files it | Every developer with an app on Google Play [2] | Only apps using Health Connect permissions |
| Including apps with no health features? | Yes — you declare that you have none [2] | No |
| Where | Play Console → Policy → App content → Health Apps [2] | Same form, per-permission justification [5] |
| Judged against | Whether the declaration matches the binary | Six approved use cases, per data type [1] |
| Failure looks like | Upload error, or “Inaccurate Health Apps Declaration” | Feedback in Play Console; revise and resubmit [1] |
| Covers testing tracks? | Closed, open and production, plus pregranted and preloaded apps [2] | Yes |
The declaration has been mandatory since Google’s April 2024 policy update, with accuracy enforced after 31 August 2024 [2]. Developers who used the old Google Health Connect API Request form had to migrate those declarations into Play Console by 22 January 2025 [5].
Gate one catches apps that never intended to be health apps. Gate two is where a genuine health product spends its time.
Gate one: the in-scope permission list
This is the list most teams have never read. Google considers these permissions in scope of the health apps policy, and says explicitly that it is not exhaustive [3]:
ACCESS_BACKGROUND_LOCATION · ACCESS_COARSE_LOCATION · ACCESS_FINE_LOCATION · ACTIVITY_RECOGNITION · BLUETOOTH_ADVERTISE · BLUETOOTH_CONNECT · BLUETOOTH_SCAN · BODY_SENSORS · BODY_SENSORS_BACKGROUND · CAMERA · READ_CALENDAR · READ_SMS · RECORD_AUDIO · SEND_SMS · WRITE_CALENDAR
A maps feature brings location. A QR scanner brings camera. A voice note brings microphone. A fitness SDK, an analytics SDK, or a step-counting dependency brings ACTIVITY_RECOGNITION without appearing anywhere in your code. Manifest merging means a transitive dependency’s permission is your permission.
AndroidManifest.xml and use the Merged Manifest view, or run ./gradlew :app:processReleaseManifest and read the merge report. It names the dependency that contributed each permission. Guessing from your own source is how teams spend a week on a one-line tools:node="remove". Developers in the fastlane thread reported the same shape repeatedly: an app with no health features, a declaration saying so, and a library that added ACTIVITY_RECOGNITION or RECORD_AUDIO. One noted that manual bundle uploads to an internal testing track still succeeded, and the inconsistency only surfaced when promoting to a wider track [10]. That is a bad failure mode, because it lands at the moment you are trying to release.
Two fixes, in order of preference. Remove the permission if the feature that needs it is not shipping — a merged-manifest remove node, or dropping the dependency. Otherwise amend the declaration to describe the feature honestly, which moves you into gate two if the data is health data.
Separately, if your app requires any in-scope permission, Play requires prominent disclosure of how the data will be used, a description of the data type accessed, and affirmative user consent [3]. That is the runtime dialog and the screen around it, not just the store listing.
Gate two: per-type justification against six use cases
If you touch Health Connect permissions, the declaration turns into a per-permission argument. Google:
Only request permissions and access data types that support the specific, user-facing health features you offer. Do not request broader access than necessary. [1]
And:
Accessing sensitive health and fitness data through Android permissions is strictly limited to apps providing clear user benefit within specific, approved use cases. Your declared use case(s) in the Play Console must accurately reflect your app’s functionality that requires health and fitness data. [1]
There are six [1]:
- Fitness, wellness and coaching — tracking, analysis, personalized coaching, companion apps for wearables. Explicitly includes sleep analysis, activity tracking, nutrition and lifestyle habits, guided sessions, and trend analysis that detects early signs of potential illness not intended for medical diagnosis.
- Rewards — incentives and progress toward health goals in exchange for financial rewards.
- Corporate wellness — employer-offered programs and challenges, aggregating consented activity data. The coverage math for those programs is in employee wellness and health data.
- Medical care — direct care, condition management including logging clinical symptoms, clinical measurements and vital signs, and medication management.
- Human-subjects research — IRB or ethics committee approved, with a specific five-part consent (nature/purpose/duration, procedures and risks, confidentiality and sharing, a contact point, the withdrawal process), and proof of board approval on request [1].
- Health-integrated games — gameplay driven by real-world activity. Google adds that the primary purpose must remain gaming and the app must not function as an unregulated medical tool. The mechanics side is gamification and behavioral nudges.
The justification, in Google’s own words
Google publishes examples of what passes and what does not [1]. This is the most useful thing on the page and almost nobody quotes it:
| Justification | |
|---|---|
| Passes | ”Our app provides personalized workout plans. Access to physical activity data allows us to tailor recommendations based on users’ current activity levels, enhancing their fitness journey.” |
| Passes | ”Our app provides real-time heart rate monitoring during workouts to provide feedback to the user and allow them to adjust their workout intensity.” |
| Fails | ”Needed for app functionality.” Google’s annotation: too broad and lacks specific justification. |
The pattern in the passing examples is feature, then data type, then user benefit, in that order. The failing one names none of the three.
What Google says a denial means
If your request is incomplete or denied, you will receive feedback through the Play Console. Common reasons for denial include:
- Lack of clear justification for the requested permissions.
- Misalignment with approved use cases.
- Requesting a bulk list of permissions when not necessary.
- Insufficient detail about data collection, usage, and sharing practices. [1]
“Requesting a bulk list of permissions when not necessary” is the one that catches aggregator-shaped products. Declaring every Health Connect type because your SDK supports every type is exactly the pattern. Request the types your screens render.
Heightened scrutiny
Four categories get a higher bar, and you must demonstrate the specific data point is required for a user-facing feature such as fertility tracking or chronic condition management [1]:
| Category | Example permission |
|---|---|
| Reproductive health | READ_MENSTRUAL_CYCLE_PHASE |
| Substance use | READ_ALCOHOL_CONSUMPTION |
| Clinical vitals | READ_BLOOD_PRESSURE, READ_SKIN_TEMPERATURE |
| Self-reported symptoms | READ_SYMPTOM_COUGH |
Symptom permissions are granular and there is no ALL_SYMPTOMS to fall back on [1]. If you want five symptoms you justify five permissions.
The two extra permissions
READ_HEALTH_DATA_HISTORY lifts the default window of roughly 30 days prior to first grant, and READ_HEALTH_DATA_IN_BACKGROUND lets you read outside the foreground [1] [11]. They are separate rows with separate justifications, and a user can decline either one on its own. What that does to a product with no wearable in the loop is Health Connect without a wearable.
The Matchmaking expectation, and why it lands on AI products
Buried in the same guidance is a sentence with real architectural weight:
Apps (especially AI Agents and multi-purpose tools) that support a wide range of data sources, should use the Matchmaking API to detect available data sources on the device before requesting access (permission prompts). [1]
The Matchmaking API cross-references your granted read permissions against what apps and devices on the handset can actually write, and shows the user only the sources that would produce data [6]. You call checkIfMatchmakingIsPossible() with a MatchmakingRequest, and launch createMatchmakingIntent(request) only when isMatchmakingPossible is true [6] [7]. recordTypes left empty means every type you can read; includedDataSources and excludedDataSources cannot both be set [7].
Note the status before you build a review argument on it. It is annotated @ExperimentalMatchmakingApi, arrived in 1.2.0-alpha06, and availability is checked through HealthConnectFeatures.getFeatureStatus with FEATURE_MATCHMAKING [7]. So this is Google naming a pattern, not a hard gate today — but “we request 40 types and let the user sort it out” is precisely the behaviour the sentence exists to discourage, and AI agents are named. If your product is an assistant over health data, read it alongside the licence restrictions on feeding wearable data to a model.
Prohibited uses
These are bans, not bars to clear [1]. Abbreviated, with the ones that surprise people first:
- Headless apps. “Do not access data obtained through Android health permissions using headless apps. Apps must display a clearly identifiable icon in the app tray, device app settings, notification icons, etc.” A background-only data collector is not a shape Play allows.
- Incompatible sync. “Do not use health and fitness data APIs with apps that sync data between incompatible devices or platforms.”
- Credit, insurance, employment, lending. Determining credit-worthiness, insurance eligibility or employment suitability is prohibited outright. The market context is wearable data and health insurance; the policy answer on Android is no.
- Advertising. Transferring or selling to ad platforms, data brokers or resellers, and using the data for ads including personalized or interest-based advertising.
- Apps solely targeting children.
- Unapproved medical devices, and any safety-critical use where failure “could reasonably be expected to lead to death, personal injury, harm to individuals, or environmental or property damage.”
- Sharing without explicit informed consent, and public or social display of sensitive data without it.
The advertising ban rhymes with Apple’s 5.1.2(vi) and 5.1.3(i), which the HealthKit review post quotes in full. A cross-platform team gets the same answer from both stores: health-derived events do not belong in the marketing SDK.
The privacy policy is a technical requirement
Play is specific, and it fails in ways that look like bugs [4] [5]:
- A privacy policy link in the designated Play Console field and a link or text inside the app.
- An active, publicly accessible, non-geofenced URL. No PDFs. Non-editable.
- The policy on your Play listing must be the same policy shown when a user taps the privacy policy link inside Health Connect [5].
- It must comprehensively disclose access, collection, use and sharing — and Google notes this is not limited to what you declared in Data safety [4].
- Data safety must be filled in too; it is a separate step from the health declaration [5].
Google’s guidance also asks the policy to cover retention and deletion policies and your security practices, and requires encryption at rest and in transit, access controls, and vulnerability management as a minimum [1].
https:// page Play Console has. Medical Records: the policy does not exist yet
Health Connect’s Medical Records APIs bring FHIR data in through twelve granular permissions — READ_MEDICAL_DATA_ALLERGIES_INTOLERANCES, READ_MEDICAL_DATA_CONDITIONS, READ_MEDICAL_DATA_LABORATORY_RESULTS, READ_MEDICAL_DATA_MEDICATIONS, READ_MEDICAL_DATA_PERSONAL_DETAILS, READ_MEDICAL_DATA_PRACTITIONER_DETAILS, READ_MEDICAL_DATA_PREGNANCY, READ_MEDICAL_DATA_PROCEDURES, READ_MEDICAL_DATA_SOCIAL_HISTORY, READ_MEDICAL_DATA_VACCINES, READ_MEDICAL_DATA_VISITS, READ_MEDICAL_DATA_VITAL_SIGNS — declared in both the manifest and Play Console, with a separate health records permission screen [8] [9].
The caveat is Google’s own:
The Play Policy for Medical Records access is still being developed, and apps may need to meet additional requirements before they can be released on the Play Store. [8]
The APIs are annotated ExperimentalPersonalHealthRecordApi, ship in Health Connect 1.1.0-beta02 in Jetpack, and require compiling against the Android 16 SDK [8]. Changelog-based APIs do not exist for Medical Records yet [8]. This is a partner-program-shaped risk wearing an API’s clothing: you can write the integration and still have no route to release. Put it behind a flag, not on a launch date.
Apple, as a coda
The mirror image of Apple’s coda in the HealthKit rejection post.
Apple gives you guideline numbers to argue with; Google gives you a form and a use-case list. Apple’s gate is a human reading a binary against section 5.1. Google’s gate is a declaration compared against your merged manifest, then a per-type justification compared against six approved use cases.
The practical difference for a cross-platform team: on iOS you can be surprised by how a reviewer reads your feature. On Android you can be surprised by whether you are in scope at all, because a dependency changed. Apple has no equivalent of “your analytics library made you a health app.”
What is the same on both: minimize the types, name the screen each one feeds, keep health data out of the ads stack, and make the privacy disclosure match the binary. The on-device permission mechanics either store puts you through are in HealthKit versus Health Connect.
What this is not
It is not HIPAA. Google names HIPAA, GDPR and SaMD regulation as the developer’s sole responsibility [1], which is a disclaimer, not a compliance program.
It is not FDA General Wellness. Play’s “detecting early signs of potential illness through trend analysis (not intended for medical diagnosis)” sits inside an approved use case [1] and still says nothing about whether your marketing claims make you a device.
It is not a reason to avoid Health Connect. It is the cost of the on-device model, and it is the only path to Galaxy Watch, on-device Fitbit and phone sensors on Android, which is most of the Android device base. Garmin’s pause is a reminder of what the alternative gate looks like when it closes.
A health data layer does not absorb this. If Sahha is in your binary, the Health Connect types the SDK requests are types on your declaration, justified by your screens, under your package name. What a layer removes is the schema work behind the permission, not the permission.
Before you submit
- Build the merged manifest and list every in-scope permission with the dependency that contributed it.
- Delete the ones you do not ship. A
tools:node="remove"is cheaper than a policy appeal. - File the declaration even if you have no health features. “My app doesn’t provide any health features” is a valid answer and the absence of an answer is not [2].
- Diff the requested Health Connect types against your screens. Each type has a screen or it comes out.
- Write each justification as feature, data type, user benefit — the shape of Google’s own passing examples [1].
- Justify history and background separately. They are their own rows and can be declined alone [11].
- Check the heightened-scrutiny four. Reproductive health, substance use, clinical vitals, symptoms — name the user-facing feature or drop them.
- Verify the privacy policy URL is
https://, public, non-geofenced, not a PDF, and identical to the one Health Connect renders [4] [5]. - Grep the ads and attribution SDKs for health-derived events, then do it again for anything derived from a score.
- Confirm you have a launcher icon. Headless access is prohibited [1].
- Refile only when the type set changes. Access is allow-listed per package name regardless of version [5].
References
- Google Play Console Help. Android Health Permissions: Guidance and FAQs. Approved use cases, prohibited uses, justification examples, denial reasons, heightened scrutiny, Matchmaking expectation, Wear OS scope. Retrieved 20 September 2026. https://support.google.com/googleplay/android-developer/answer/12991134
- Google Play Console Help. Provide information for the Health apps declaration form. April 2024 policy update; accuracy required after 31 August 2024; applies to closed, open and production tracks and to pregranted and preloaded apps. Retrieved 20 September 2026. https://support.google.com/googleplay/android-developer/answer/14738291
- Google Play Console Help. Health app categories and additional information — non-exhaustive list of permissions in scope of the health apps policy, and the prominent disclosure requirement. Retrieved 20 September 2026. https://support.google.com/googleplay/android-developer/answer/13996367
- Google Play Console Help. Health Content and Services policy — privacy policy URL requirements, unused permission removal, Health Connect data as personal and sensitive user data. Retrieved 20 September 2026. https://support.google.com/googleplay/android-developer/answer/12261419
- Android Developers. Publish your health app on Google Play — declaration process, per-permission justification, privacy policy parity with Health Connect, package-name allow-listing regardless of app version, 22 January 2025 migration deadline from the old API Request form. https://developer.android.com/health-and-fitness/health-connect/publish
- Android Developers. Matchmaking API — discovering apps and devices that can write types your app may read. https://developer.android.com/health-and-fitness/health-connect/ui/matchmaking
- Android Developers.
MatchmakingRequestandMatchmakingResponseAPI reference.@ExperimentalMatchmakingApi, added 1.2.0-alpha06;FEATURE_MATCHMAKINGviaHealthConnectFeatures.getFeatureStatus; included and excluded data sources are mutually exclusive. https://developer.android.com/reference/kotlin/androidx/health/connect/client/matchmaking/MatchmakingRequest - Android Developers. Medical Records — FHIR support,
ExperimentalPersonalHealthRecordApi, Health Connect 1.1.0-beta02 in Jetpack requiring the Android 16 SDK, and the statement that the Play policy for Medical Records access is still being developed. https://developer.android.com/health-and-fitness/health-connect/medical-records - Android Developers. Read medical data — the twelve
READ_MEDICAL_DATA_*permissions, declared in the manifest and in Play Console. https://developer.android.com/health-and-fitness/health-connect/medical-records/read-data - fastlane, GitHub issue #22204. “Google Api Error: Invalid request - You must let us know whether your app includes any health features.” Developers trace it to in-scope permissions such as
ACTIVITY_RECOGNITIONandRECORD_AUDIOarriving through a dependency, and report internal-track uploads succeeding while promotion to wider tracks fails. https://github.com/fastlane/fastlane/issues/22204 - Android Developers. Read data in Health Connect — the ~30-day default history window,
PERMISSION_READ_HEALTH_DATA_HISTORY, and background reads. https://developer.android.com/health-and-fitness/health-connect/read-data