HotCodePush

Privacy and device data

Every field the HotCodePush SDK sends from a device, where it is stored and for how long, plus ready-to-paste answers for Apple and Google Play.

The HotCodePush SDK sends an anonymous per-install id, the versions your app is running and the outcome of each update, and nothing else. No vendor or advertising identifier is read, and nothing about how a person uses your app leaves the device. Only the attributes your app sets depend on you.

What the SDK sends

The SDK talks to files.hotcodepush.com and updates.hotcodepush.com and to nothing else. The device fetches its channel index with the app id, the channel id and the platform, and nothing else (How an update reaches a device).

Everything below goes to POST /v1/apps/{appId}/events in batches of at most 200 events. A batch carries the device report, when a fact changed or a new month began, and the outcome events since the last batch. A device nothing happened to reports once a month.

FieldWhat it isApple categoryGoogle category
deviceIdIs a UUIDv4 the SDK generates on first start and keeps for the life of the install.Identifiers › Device IDDevice or other IDs
attributesAre the string labels your app sets through setAttributes, an opaque userId among them.Identifiers › User ID, only if one of them is an id you can resolve to a personPersonal info › User IDs, under the same condition
platform, sdkVersion, binaryVersion, binaryBuild, osVersion, fingerprintAre the versions the install is running and the fingerprint of its native layer.Diagnostics › Other Diagnostic DataApp info and performance › Diagnostics
channelId, channelSource, releaseId, embeddedBundleIdSay which channel the device follows and whether the app set it at runtime, the running release and the bundle the binary shipped.Diagnostics › Other Diagnostic DataApp info and performance › Diagnostics
checked, downloaded, applied, confirmed, failedAre one event per release the device saw: a check's status and reason, a download's size, and a failure's reason, a rollback's included, with the reason text your app passed to rollbackUpdate.Diagnostics › Other Diagnostic DataApp info and performance › Diagnostics
countryIs derived on HotCodePush's servers from the request's network address, and the device never sends it.Location › Coarse LocationLocation › Approximate location

The CLI's own telemetry is about commands, never about devices.

What never leaves the device

  • The advertising identifier, the vendor identifier and the Android id: no SDK reads one.
  • The SDK's own log: the debug screen reads it from memory, and the share sheet is the only way out.
  • Your app's storage, your users' content, contacts, photos, files and location: the SDK reads its own keys and its own directory.

HotCodePush's product analytics receive no device id and no per-device event.

The device id and attributes

The device id is a UUIDv4 the SDK generates on first start and keeps for the life of the install. A reinstall is a new device, and two of your apps on one phone are two devices. Attributes are the labels your app sets through setAttributes for targeting, an opaque userId among them and never an email address.

  • The id is an identifier. Yes, under both stores: a device-level identifier in Apple's sense and a device id in Google's, anonymous or not.
  • It is linked to a user only if your app links it. HotCodePush holds no name, email or account for your end users. A userId you can resolve to a person is a User ID, and the device id becomes data linked to the user.
  • It is not used for tracking. Nothing is linked with third-party data or shared with a data broker, and the SDK reads no advertising identifier. Every "Used for tracking" answer is No, and no App Tracking Transparency prompt is needed.

Where the data is stored

Everything a device reports is stored in the European Union.

DataWhere
The device registry, the audit log, usage and every other recordThey live in a database in Frankfurt, Germany.
Bundles, files and packsThey live in object storage in the EU, served at files.hotcodepush.com.
BackupsThey are encrypted and stay in the EU.
Product analytics about HotCodePush's own customers, never about devicesIt lives in Frankfurt, Germany.

A device's check is answered from a location near it, and what the device reports is stored in Frankfurt and nowhere else. Every organization is created in the eu region and cannot move.

If your organization sets a telemetry export, HotCodePush posts its audit events, which name your members by email where an event is about them, to the OpenTelemetry backend you chose. That backend is your own processor, not a subprocessor of ours, and your privacy policy names it.

Retention

The 90 days are a published number on Limits and fair use.

DataKept
Device rows: the id, the attributes, the country, the versions and the last report timeThey are kept 90 days from the device's last report, the organization's retentionDays, and longer only on an Enterprise term.
Outcome rows per device and release: checked, applied, confirmed and failed, with the reasonThey are kept as long as the release's bundle.
Monthly active device rows: the device id, once per app and monthThey are kept until the end of the second month after the month they count.
Raw event batchesThey are not stored beyond those rows, and the counters and aggregates carry no device id.
Bundles, files and packsThey are kept as Limits says, and never deleted while a device still runs them. The update a channel serves is never deleted.
Audit rows, with the country, the IP address and the user agent of the callerThey are kept 12 months.
Webhook and telemetry export deliveries, with the truncated response bodyThey are kept 30 days.
SessionsThey last 30 days, sliding with use.
The account and the organizationThey are kept for the life of the account and hard-deleted 7 days after a deletion.
Usage aggregates per app and month, the MAU and the data transferThey are kept, and no device id survives in them.

Erasure requests

An erasure request is one command, which deletes the device's record at once.

hotcodepush device delete --device 6b1e9d37-2f5c-4a80-9c46-d8e3a1f7b259

The same delete is DELETE /v1/apps/{appId}/devices/{deviceId} in the API (device has the CLI's options), and it writes a device.deleted row to the audit log. The install keeps its id and reports again with its next check of the month, and only uninstalling the app ends it.

The device id stays in the device's outcome rows and monthly active device rows until their retention ends.

HotCodePush holds no name or email to search by. Find the device by the attributes your app set, with hotcodepush device list, and run the delete.

Deleting an organization is for its Owner alone. It goes with everything under it after the retention window above, restorable by support until then.

Apple App Privacy answers

Answer these in App Store Connect › App Privacy, in addition to whatever the rest of your app collects.

Data typeCollectedLinked to the userUsed for trackingPurposes
Identifiers › Device IDYesNo, unless your app sets a resolvable attribute (see above)NoApp Functionality, Analytics
Identifiers › User IDOnly if your app sets userId or another id you can resolve to a personYesNoApp Functionality
Diagnostics › Other Diagnostic DataYesThe same answer as the Device IDNoApp Functionality, Analytics
Location › Coarse LocationYes, derived from the request's network address on HotCodePush's serversThe same answer as the Device IDNoApp Functionality, Analytics

No Usage Data row: the SDK reports update outcomes, never app launches, taps or screens. No Crash Data row: a rollback reports that a start failed and its reason, never a crash report, a stack or a log.

The iOS SDK ships its own PrivacyInfo.xcprivacy, so App Store submission needs nothing extra from you. It declares no tracking and the two collected data types above. Its required-reason APIs are user defaults CA92.1 for its own keys, file timestamps C617.1 for its bundle directory and disk space E174.1 for the free-space check.

Google Play Data safety answers

Data typeCollectedSharedEphemeralRequired or optionalPurposes
Device or other IDsYesNoNoRequiredApp functionality, Analytics
App info and performance › DiagnosticsYesNoNoRequiredApp functionality, Analytics
Personal info › User IDsOnly if your app sets one as an attributeNoNoRequired, once your app sets itApp functionality
Location › Approximate locationYesNoNoRequiredApp functionality, Analytics

Shared is No on every row: Google's definition of sharing excludes a transfer to a service provider processing the data on your instructions. The data processing agreement makes HotCodePush that provider. The security section takes the same three answers for every customer.

QuestionAnswer
Is all of the user data collected by your app encrypted in transit?Yes. Every request the SDK makes is HTTPS.
Do you provide a way for users to request that their data is deleted?Yes. You delete a device with hotcodepush device delete or DELETE /v1/apps/{appId}/devices/{deviceId}, and every device row falls away by itself after your retention window, 90 days by default.
Do you follow the Families policy?Give your own answer. Nothing in the SDK changes it.

Wording for your privacy policy

A starting point for your counsel, in the voice of your own policy. If your app sets a user id as an attribute, add that the identifier is linked to the account the app signs in with.

This app uses HotCodePush to deliver updates to its JavaScript and web content. For this purpose the app sends an anonymous identifier generated on the device at first start, the versions of the app and of the update it is running, and the outcome of each update to HotCodePush, which derives an approximate country from the network address of the request. No advertising identifier or vendor identifier is read, and no data about how you use the app is sent. HotCodePush processes this data on our behalf as a processor under a data processing agreement, stores it in the European Union, and deletes a device's record 90 days after its last report.

What the public index says

A device fetches its update before any account exists on it, so what a device reads is public by design. The channel index carries each release's notes, bundle version label, rollout percentage, mandatory flag and conditions. Anyone holding your app id and one channel id can fetch it, and both ids ship inside your binary, every QA build included.

Write release notes for the people running your app, or leave the field empty. A channel flagged discoverable adds its id and name to the app's channels index, fetchable with the app id alone. No channel is discoverable until you flag it.

Attribute values and targeted device ids appear only as hashes. The values themselves, the device registry, the MAU and the release history stay behind a credential. Sign your bundles makes a device apply only what you signed.

Subprocessors

The subprocessor list and the data processing agreement are on the legal page. The agreement makes HotCodePush your processor for this data, and the list names who processes it for HotCodePush. PostHog is in the privacy policy's recipient table, as it processes data about you. No device data reaches it, so it is not a subprocessor.

Last updated on

On this page