Skip to content

Privacy & Consent

Elo handles GDPR, CCPA, COPPA, and other privacy regulations automatically. There are only two things you may need to configure.

Section titled “1. Set up a Consent Management Platform (CMP)”

If your users are in jurisdictions that require consent (e.g., EU/EEA for GDPR), integrate a CMP such as OneTrust, Cookiebot, or Quantcast Choice. The CMP writes standard IAB consent signals to localStorage (web) or SharedPreferences (Android), and the Elo SDK reads them automatically on initialization.

If your app targets children under 13 or users under the age of consent, set the appropriate flags when configuring the SDK:

Elo.configure(with: EloConfiguration(
elo: EloNetworkConfiguration(
publisherId: "YOUR_PUBLISHER_ID",
adUnitId: "YOUR_AD_UNIT_ID"
),
coppa: true, // Content directed at children under 13
tfua: true, // Users under the age of consent
))
FlagWhen to set
coppaYour app is directed at children under 13 (US COPPA)
tfuaUsers should be treated as under the age of consent

The iOS and Android SDKs can attach a coarse device location to ad requests to improve relevance. It is strictly passive — the SDK only ever reads an already-authorized last-known location and never prompts for the location permission itself.

It is on by default on both platforms. Opt out at configuration time or at runtime with Elo.setShareGeoLocation(false):

Elo.configure(
publisherId: "YOUR_PUBLISHER_ID",
adUnitId: "YOUR_AD_UNIT_ID",
shareGeoLocation: false, // opt out; default is true
geoLocationPrecision: 2 // round coordinates to ~1.1 km (default)
)

For any geo to flow, your app must already hold an authorized location permission (ACCESS_COARSE_LOCATION / ACCESS_FINE_LOCATION on Android; a “When In Use” or “Always” CoreLocation authorization on iOS) with a last-known fix. Coordinates are rounded to geoLocationPrecision decimal places (clamped 0–6); the default of 2 (~1.1 km) is a privacy-conscious choice. COPPA / TFUA suppress geo entirely regardless of this setting.

The opt-out covers coordinates only: the settings-derived country (device.geo.country) and UTC offset (device.geo.utcoffset) come from locale/time-zone settings — not GPS — and are sent regardless of shareGeoLocation. See the EloConfiguration reference (iOS · Android) for details.

Beyond the signals you configure, Elo’s backend detects and enforces privacy regulations on its own:

  • GDPR & CCPA - automatically detected via consent signals or visitor geolocation. When restrictions apply, personal data is removed or anonymized before reaching ad exchanges.
  • COPPA & TFUA - the strictest data handling: no IP, no device ID, no geolocation, and visitor IDs are hashed.
  • Limit Ad Tracking (LMT) - respected automatically when the device signals it (e.g., iOS App Tracking Transparency).

In all cases, sensitive headers like cookie, authorization, and referer are stripped before data leaves Elo’s servers.

Publishers who know their signed-in user can share age, gender, email, and phone with ad requests for upcoming targeting features. Call setUserData on the iOS, Android, or Web SDK:

  • Hashed on receipt, never stored plain. Contact details travel to the ad server over HTTPS and are SHA-256 hashed there before anything is written, so only digests reach Elo’s request logs, analytics store, and archives. You don’t need to hash them yourself.
  • Store-only today. The data is stored alongside the ad request; it is not forwarded to ad exchanges.
  • Consent-suppressed. The server discards user data entirely on requests flagged COPPA or TFUA, and on any request where GDPR applies.
  • Stored differently per platform. The Web SDK holds it in memory for the page, so re-set it per page load. The iOS and Android SDKs persist it on the device alongside the publisher user identifier, encrypted at rest — iOS in the Keychain as a ThisDeviceOnly item, Android sealed with AES-GCM under a non-exportable Keystore key — so a relaunch that resumes a signed-in session keeps sending it. Nothing is ever written in plaintext; if the platform store is unavailable the SDK keeps the data in memory for that process instead. It never joins tracking pings.
  • Clear it on sign-out. On mobile the stored record outlives a sign-out you don’t signal, so setUserData(nil) on iOS and setUserData(null) on Android is an obligation rather than a convenience: without it the next person on that device inherits the previous account’s details. Set it and the user identifier from one auth-state hook, which is also what keeps a stored copy from going stale when the user changes their email or phone. shutdown() erases the record.

Elo shows conversation-targeted ads, which means chat text leaves the device when you call loadAd / preloadAd — and only then; the SDK never sends requests on its own. Before shipping, account for the following in your App Store submission and privacy policy:

  • The App Store nutrition label is yours to fill in. The SDK bundles a PrivacyInfo.xcprivacy manifest, but that does not auto-populate your app’s nutrition label. Declare at minimum: User Content (chat text), Device ID, Coarse Location (Precise if you disable rounding), and Product Interaction — used for Third-Party Advertising.
  • Chat content is forwarded verbatim (roles plus full message text, truncated but not redacted, and each message’s id and time when you set them) to Elo. Disclose conversation sharing in your privacy policy.
  • Taps inside an Elo-served ad are measured. Every tap inside an Elo-served card or strip is reported to Elo for analytics, with the position expressed as a fraction of the ad view’s own size and never as a screen coordinate, alongside the region tapped, whether it opened the destination, and the time since the impression. No chat content rides along. It falls under Product Interaction, used for Third-Party Advertising and Analytics.
  • Time spent in your in-app browser is measured if you report it. When you call Elo.trackBrowserOpened and Elo.trackBrowserClosed, the SDK sends when the browser opened and closed for that ad and how long it stayed open. Nothing from the page itself is collected. It falls under Product Interaction, used for Third-Party Advertising and Analytics.
  • The ad’s position on screen is reported once it becomes viewable. After an Elo-served ad has been at least 50% visible for one second, the SDK sends the ad view’s size and position in the window, the window size, the visible fraction, and the time since render, so Elo can verify that ads render in the SDK’s own view. Nothing about the surrounding app is sent. It falls under Product Interaction, used for Third-Party Advertising and Analytics.
  • Consent signals pass through. The SDK reads IAB TCF v2 (IABTCF_*) and GPP (IABGPP_*) keys from UserDefaults.standard and forwards them along with your coppa / tfua flags. It does not collect or interpret consent — your app (with its CMP) remains the data controller.
  • The SDK never: shows the ATT prompt, requests location permission, sends the advertising identifier without ATT authorization and consent, or writes to your app’s standard UserDefaults.
  • Some demand sources’ tracking URLs are requested by the device. A few demand sources only count a render, impression, or click when the device that showed the ad requests their URL. When a creative carries such a URL, the SDK requests it directly, at most once per showing. The request carries none of the SDK’s headers or session data, but like any web request it reaches that demand source with the device’s IP address and user agent.
  • Other ad networks are your own surface. The SDK sends chat content to Elo only. A network you request from your own fallback code collects data independently under its own policies — account for it separately in your nutrition label.
  • If you share first-party user data (age, gender, email, phone; see above), also declare Email Address, Phone Number, and any demographic data you pass. Hashing on our side doesn’t change this: the data still leaves the device, and a digest is still that data type under Apple’s rules. The SDK also keeps what you set in the Keychain, encrypted and device-only, so it survives a relaunch — worth a line in your privacy policy.
  • Child-directed apps: set coppa / tfua (above) and have the integration legally reviewed.

The full host-app privacy guide (PRIVACY.md) ships with the SDK source and includes suggested privacy-policy language and the complete signal-by-signal disclosure table.

The same data flow applies on Android — chat text leaves the device only when you call loadAd / preloadAd. Account for the following in your Play Console submission and privacy policy:

  • The Data safety form is yours to fill in. Data the SDK sends off-device counts as collected (and shared) under Play’s rules. Declare at minimum: in-app messages (chat text), Device or other IDs, Approximate location (Precise if you disable rounding), and App interactions — used for Advertising or marketing.
  • Chat content is forwarded verbatim (roles plus full message text, truncated but not redacted, and each message’s id and time when you set them) to Elo. Disclose conversation sharing in your privacy policy.
  • Taps inside an Elo-served ad are measured. Every tap inside an Elo-served card or strip is reported to Elo for analytics, with the position expressed as a fraction of the ad view’s own size and never as a screen coordinate, alongside the region tapped, whether it opened the destination, and the time since the impression. No chat content rides along. It falls under App interactions, used for Advertising or marketing and Analytics.
  • Time spent in your in-app browser is measured if you report it. When you call Elo.trackBrowserOpened and Elo.trackBrowserClosed, the SDK sends when the browser opened and closed for that ad and how long it stayed open. Nothing from the page itself is collected. It falls under App interactions, used for Advertising or marketing and Analytics.
  • The ad’s position on screen is reported once it becomes viewable. After an Elo-served ad has been at least 50% visible for one second, the SDK sends the ad view’s size and position in the window, the window size, the visible fraction, and the time since render, so Elo can verify that ads render in the SDK’s own view. Nothing about the surrounding app is sent. It falls under App interactions, used for Advertising or marketing and Analytics.
  • Consent signals pass through. The SDK reads IAB TCF v2 (IABTCF_*) and GPP (IABGPP_*) keys from your app’s default SharedPreferences and forwards them along with your coppa / tfua flags. It does not collect or interpret consent — your app (with its CMP) remains the data controller.
  • The AD_ID permission arrives via manifest merge. The SDK declares com.google.android.gms.permission.AD_ID; the advertising ID itself is consent-gated and honors the system’s ad-personalization limit. Child-directed apps should remove the permission with tools:node="remove".
  • The SDK never: requests location permission (or any runtime permission), shows a consent prompt, sends ad requests outside your loadAd / preloadAd calls, or writes to your app’s default SharedPreferences.
  • Some demand sources’ tracking URLs are requested by the device. A few demand sources only count a render, impression, or click when the device that showed the ad requests their URL. When a creative carries such a URL, the SDK requests it directly, at most once per showing. The request carries none of the SDK’s headers or session data, but like any web request it reaches that demand source with the device’s IP address and user agent.
  • Other ad networks are your own surface. The SDK sends chat content to Elo only. A network you request from your own fallback code collects data independently under its own policies — account for it separately in your Data safety form.
  • If you share first-party user data (age, gender, email, phone; see above), also declare Email address, Phone number, and any demographic data you pass. Hashing on our side doesn’t change this: the data still leaves the device, and a digest is still that data type under Play’s rules. The SDK also keeps what you set in its own SharedPreferences, encrypted under a Keystore key, so it survives a relaunch — worth a line in your privacy policy.
  • Child-directed apps: set coppa / tfua (above) and have the integration legally reviewed.

The Android PRIVACY.md ships with the SDK source and includes suggested privacy-policy language, the complete signal-by-signal breakdown, and the Data safety table.