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.

App Store id 1503601939 · Reviewed 12 November 2026

01 / SHORT VERSION

A drawing stays
on the device.

On a narrow screen, scroll this table sideways. Column headers stay visible.

Privacy summary for the current app source.
TopicWhat the code supports
AccountNone. No sign-in, profile, or Doodle ID.
AdsNo advertising SDK and no ad-removal purchase in this app.
Drawing contentsNot attached to analytics signals. Doodle’s signal calls pass a name and no parameters.
AnalyticsTelemetryDeck is initialized in production. Tests and Xcode previews turn it off.
IdentifiersThe SDK hashes a vendor or install identifier before sending it. Doodle does not add its own salt or user ID.
Opt-out of analyticsNo in-app switch. Declining a permission does not turn these signals off.
iCloud / CloudKitNo iCloud or CloudKit entitlement. No app-managed sync of the canvas.
FilesEditable drawings open and save through the system document picker when Pro or a seat allows it.
DiagnosticsMetricKit reports are stored on device until a person exports them.
WebsiteThese 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.

Signals Doodle sends by name. None of these calls adds a parameter dictionary.
SignalWhen the app sends it
TelemetryDeck.Session.startedSDK 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.paywallShownWhen the consumer plan screen is showing the button that opens the paywall. An organization seat does not open that paywall.
Purchase.completedAfter a completed pack, subscription, or retention-offer purchase in the app. Organization seats are not bought in the app.
Drawing.savedWhen an editable drawing is saved.
Drawing.exportedWhen 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.

On-device storage found in the app source.
StoreWhat it holds
UserDefaultsPlan status, whether Pro has been offered, open count, what’s-new date, confirm-before-clear, hidden tool picker, appearance, and app icon.
DocumentsEditable .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 recoveryThe 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/DoodleDiagnosticsMetricKit 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.
NotificationsOptional local reminders about coloring packs. The app asks for alert and sound. The person can decline.
MicrophoneThe 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.

District paperwork. None of these documents is signed or published.
DocumentStatus
SDPC National DPANot signed. Coming soon.
COPPA statementNot published. Available on request.
FERPA statementNot published. Available on request.
VPAT accessibility reportNot completed. Coming soon.
IT deployment guideNot published. Coming soon.
Placeholder — owner to fill

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. [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. [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. [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. [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.