District privacy sheet
What Doodle
actually sends.
This sheet follows the app source and the TelemetryDeck SDK the project pins, not the older privacy policy. Where the code and a public label disagree, both are stated.
01 / SHORT VERSION
A drawing stays
on the device.
On a narrow screen, scroll this table sideways. Column headers stay visible.
| Topic | What the code supports |
|---|---|
| Account | None. No sign-in, profile, or Doodle ID. |
| Ads | No advertising SDK and no ad-removal purchase in this app. |
| Drawing contents | Not attached to analytics signals. Doodle’s signal calls pass a name and no parameters. |
| Analytics | TelemetryDeck is initialized in production. Tests and Xcode previews turn it off. |
| Identifiers | The SDK hashes a vendor or install identifier before sending it. Doodle does not add its own salt or user ID. |
| Opt-out of analytics | No in-app switch. Declining a permission does not turn these signals off. |
| iCloud / CloudKit | No iCloud or CloudKit entitlement. No app-managed sync of the canvas. |
| Files | Editable drawings open and save through the system document picker when Pro or a seat allows it. |
| Diagnostics | MetricKit reports are stored on device until a person exports them. |
| Website | These pages do not load an analytics script or set a cookie. |
02 / ANALYTICS
Named signals,
plus SDK fields.
The app depends on TelemetryDeck’s Swift SDK 2.14.2. Production initialization sets the app ID and leaves the SDK defaults in place. Tests and SwiftUI previews set analyticsDisabled, turn off the automatic session signal, and turn off session statistics, so those runs do not send.
Doodle’s own helper only accepts a signal name. Its comment says parameter values are not hashed before they leave the device, so callers pass none. The four names the app sends are below. The SDK also sends TelemetryDeck.Session.started because sendNewSessionBeganSignal defaults to true and production does not change it.
On a narrow screen, scroll this table sideways. Column headers stay visible.
| Signal | When the app sends it |
|---|---|
| TelemetryDeck.Session.started | SDK default on a new session. On iPhone, iPad, and visionOS the SDK starts a session at cold launch and when the app returns from background after five minutes. |
| Pro.paywallShown | When the consumer plan screen is showing the button that opens the paywall. An organization seat does not open that paywall. |
| Purchase.completed | After a completed pack, subscription, or retention-offer purchase in the app. Organization seats are not bought in the app. |
| Drawing.saved | When an editable drawing is saved. |
| Drawing.exported | When an image of the drawing is exported. |
Every signal still carries the SDK’s default payload. In SDK 2.14.2 that payload includes app version and build, device model, architecture, operating system and version, screen size and scale, orientation, locale, region, language, time zone, whether the build is debug, TestFlight, simulator, or App Store, and the SDK version. With session statistics left on, it also includes first-session date, session counts, distinct days used, and average session length. On iOS, which is how iPhone, iPad, and this app’s Mac Catalyst build are compiled, it adds accessibility flags: reduce motion, bold text, invert colors, darker system colors, reduce transparency, differentiate without color, and the content-size category. The visionOS branch of that function does not add those accessibility keys. Calendar fields include day of week, hour, and whether the SDK treats the day as a weekend.
The signal body includes a session ID that is an unhashed UUID. The user identifier is separate and is hashed, described next. Drawing strokes, document names, and filenames are not fields in these calls.
03 / IDENTIFIERS
Hashed before
it is sent.
Doodle does not set defaultUser or a salt. The SDK then builds its own identifier and hashes it with SHA-256 and an empty salt. On iOS and visionOS that identifier is identifierForVendor when the system provides one. If it does not, the SDK substitutes a string that includes the words “unknown user,” the system version, and the build number. Mac in this project is Mac Catalyst, so it uses the iOS path rather than the native-macOS UUID stored in the SDK’s UserDefaults.
The SDK README for 2.14.2 says the ingestion service salts that hash and hashes it again. That second hash is TelemetryDeck’s server, not code in this repository. Doodle does not set a custom salt, which the same README describes as an optional extra.
There is no in-app control that sets analyticsDisabled for a person using the App Store build. There is no App Tracking Transparency prompt in the app source. Turning off pack-reminder notifications, or denying the microphone, does not stop these signals.
04 / ON THE DEVICE
Stored locally,
unless exported.
On a narrow screen, scroll this table sideways. Column headers stay visible.
| Store | What it holds |
|---|---|
| UserDefaults | Plan status, whether Pro has been offered, open count, what’s-new date, confirm-before-clear, hidden tool picker, appearance, and app icon. |
| Documents | Editable .doodle files and Apple drawing files, opened and saved through the system document interface. The Mac sandbox entitlement allows user-selected read and write. |
| Scratchpad recovery | The open canvas can be checkpointed on the device so returning to the window keeps the drawing. That checkpoint is not an iCloud sync. |
| Application Support/DoodleDiagnostics | MetricKit and failure reports, capped and pruned on device. The store’s comment says drawing data, document names, and arbitrary error text are not added. A person can export a report. The app does not upload that folder to TelemetryDeck. |
| Notifications | Optional local reminders about coloring packs. The app asks for alert and sound. The person can decline. |
| Microphone | The usage string says the microphone is for narrating while recording a drawing. Recording is a Pro control. |
The Mac sandbox entitlements include the photos library. A search of the app sources found no Photos framework calls. Why that entitlement is present is not established here. Do not read it as a claim that drawings are uploaded to Photos.
There is no CloudKit container and no iCloud entitlement. The App Store description says there is no app-managed cloud synchronization. Saving through a file provider does not mean the current canvas is synced by Doodle.
05 / OTHER PARTIES
Purchases, ads,
and this website.
Purchases go through StoreKit and Apple. The app does not run its own account system. Organization seats are assigned by Apple School Manager or Apple Business Manager. The network client entitlement is what lets the app reach Apple and TelemetryDeck.
No ad network, SKAdNetwork, or tracking-authorization API appears in the app target. The US listing’s privacy label, checked 12 November 2026, is headed “Data Not Collected.” That label does not match the signals above. The app’s own PrivacyInfo.xcprivacy in this repository also says tracking is false and lists no collected data types. The SDK’s privacy manifest for 2.14.2 declares product interaction and device ID, not linked to identity and not used for tracking, for analytics. A district should treat the label as out of date relative to this code.
The public policy at /privacy says it was last updated April 8, 2022. It describes accounts and generic usage data, including IP address, in template language. That page is not a description of the current app. This sheet is.
doodle.app is a Next.js site on Cloudflare Workers. The pages do not embed a third-party analytics script, and the site code does not set a cookie. A theme choice can be stored in localStorage under the key “theme.” The worker also has an endpoint that signs a consumer promotional offer after it receives a subscription transaction ID. Organization seats are not eligible for those offers, and opening this page does not call that endpoint. Whether Cloudflare keeps request logs is outside this repository.
06 / PAPERWORK
Still not
signed.
On a narrow screen, scroll this table sideways. Column headers stay visible.
| Document | Status |
|---|---|
| SDPC National DPA | Not signed. Coming soon. |
| COPPA statement | Not published. Available on request. |
| FERPA statement | Not published. Available on request. |
| VPAT accessibility report | Not completed. Coming soon. |
| IT deployment guide | Not published. Coming soon. |
Procurement contact is not published yet. Add a name, email, and phone before a district uses this page. Do not link a PDF until that file exists.
07 / NOT ESTABLISHED
Do not treat
these as known.
- TelemetryDeck’s retention period, whether an IP address is logged on their servers, and how a district would delete a hashed identifier. The SDK sends the payload. The vendor’s server policy is not in this repo.
- Whether the published App Store privacy label will be updated. Today it still says data is not collected.
- The purpose of the Mac photos-library entitlement.
- A COPPA or FERPA legal conclusion. Those statements are not written. The US listing’s age rating is 4+.
- That version 4.0.2’s public what’s-new text, which is about coloring packs, is the same build as the seat code in this checkout. The checkout’s marketing version is 4.0.1.
08 / QUESTIONS
For a privacy
review.
Does a student account exist inside Doodle?
No. There is no registration, profile, or login. A school seat is an Apple subscription assigned to an Apple Account.
Can a school turn analytics off?
Not from a setting in the app. Production does not set analyticsDisabled. Tests and previews do.
Is the vendor identifier sent in the clear?
No. The SDK hashes it before the request. The session UUID is not hashed. Doodle does not add a salt of its own.
Are drawings in the analytics payload?
No parameter is passed with Doodle’s signals. The SDK still adds the device, version, locale, and session fields listed above.
Does the seat include iCloud?
No. A seat unlocks Pro and the coloring packs. It does not turn on cloud sync, because the app does not implement that sync.
09 / SOURCES
Where this
sheet comes from.
- [1] App source: DoodleApp.swift (TelemetryDeck setup and the signal helper), PackStore.swift, RetentionOffer.swift, ShopView.swift, DoodleView.swift, and PlanView.swift for the signal names. PassIdentifiers.swift and Subscription.swift for seats. DiagnosticStore.swift and AppDiagnostics.swift for on-device reports. Doodle.entitlements and Info.plist for sandbox, microphone, and the absence of iCloud. PrivacyInfo.xcprivacy for the app’s manifest. The Xcode project pins TelemetryDeck SwiftSDK from 2.14.2. Checked 12 November 2026.
- [2] TelemetryDeck Swift SDK 2.14.2: TelemetryClient.swift (session signal and analyticsDisabled defaults), Signal.swift and Signal+Helpers.swift (default payload), SignalManager.swift (SHA-256 of the user identifier and the unhashed session UUID), PrivacyInfo.xcprivacy, and the README section on hashing and the second server-side salt. Checked 12 November 2026.
- [3] Doodle: Drawing Pad on the US App Store. The privacy label says data is not collected. Age rating 4+. Version 4.0.2 what’s new, current version date 9 November 2026. Checked 12 November 2026.
- [4] The website privacy policy page in this project, which still says last updated April 8, 2022. The site layout and worker do not add an analytics beacon. Checked 12 November 2026.

