Arcqtype

Legal

Third-Party Subprocessors

Effective: Pending attorney review · Last updated July 29, 2026 (draft) · counsel-review draft

Draft — pending attorney review. This document reflects how Arcqtype is built today but has not yet received final legal sign-off. Wording may change before launch.

Purpose & scope

This document enumerates every external service that receives or processes Arcqtype user data, the categories of data each one receives, and where that data is processed. It is the engineering source-of-truth feed for the subprocessor list that appears in the public Privacy Policy and for any Data Processing Addendum (DPA) we sign with customers/guardians.

Two important framing facts that shape this whole list:

1. Backend is the single data hub. The iOS app never queries the database directly — all app data flows through the Arcqtype backend API. The iOS Supabase SDK is used only for authentication/session management, not for reading or writing app data (confirmed: grep for direct.from. This means most subprocessors receive data *from the backend*, not directly from the device. 2. Arcqtype does not train AI models on user data. Chat messages are sent to OpenAI's API to generate responses. Arcqtype has no model-training or fine-tuning pipeline; final provider-side no-training/retention wording must be verified against the executed OpenAI agreement and live settings.

Open question for counsel — classification: Some entities below are arguably independent controllers rather than processors/subprocessors (notably Apple for Sign in with Apple, and Google for Google Sign-In, each of which sets its own privacy terms with the end user). Counsel should confirm which entities belong on a "subprocessor" list versus a broader "third parties we share data with" disclosure. This draft lists all of them so nothing is missed; the legal classification is a human decision.

2026-07-29 provider correction

The Integrated Launch-Readiness Program locks these changes for counsel review:

  • OpenAI GPT-5-mini is the only active Coach runtime provider.
  • DeepSeek is a former processor. It has no active fallback, shadow, or rollback path; the former row below is retained solely as an audit trail.
  • Sentry is pending for S7 observability and must be configured with PII scrubbing before any user data is sent.
  • The public promise is "we never sell personal data". The subprocessor list is the enforcement artifact for that promise.
  • The shorter launch subprocessor register lives at shared-docs/reference/subprocessor-list.md; this document remains the detailed legal/source inventory.

---

Subprocessor inventory

1. OpenAI (current Coach runtime + utility AI provider)

  • Field — Detail
  • Service role — Current OpenAI-only AI Coach runtime provider; backend utility AI helper for specific non-Coach call sites.
  • Data received — Coach messages plus assembled prompt context. Utility call sites send task-specific text/media/context depending on the service.
  • Processing region — Counsel/vendor-contract question. The program selected OpenAI for stronger U.S.-aligned data-processing posture, no-training default for API data, DPA availability, and ZDR application path, but final publication must cite the executed contract/settings.
  • Training on user data — Draft posture: Arcqtype does not use user conversations to train or fine-tune AI models. OpenAI API no-training/ZDR language must be verified against the active contract and settings before publication.
  • How it's wired — Coach path: arcqtype-api/src/providers/openai-coach-client.ts through src/services/chat/model-provider-registry.service.ts. Utility path: src/services/openai.service.ts.
  • Minor-facing? — Yes, because Coach is available to minor users.

Open questions for counsel (OpenAI): - Execute/review DPA and ZDR paperwork, or document the retention posture if ZDR is not approved before launch. - Confirm final public wording for API no-training, retention, residency, and subprocessors. - Confirm whether Coach prompts may include HealthKit-derived or consumer-health data, and what separate consent is required.

2. Former processor: DeepSeek (historical audit record; inactive)

  • Field — Detail
  • Service role — Former Coach runtime provider. No current request path, fallback, shadow, or rollback path exists.
  • Data received — Historical only: Coach messages and assembled context were sent while this provider was active.
  • Processing region — Historical processing was associated with the People's Republic of China (PRC).
  • Training on user data — Provider-side historical terms remain a legal-record question; Arcqtype itself had no model-training pipeline.
  • How it's wired — Not wired in current source/config. Applied migration history and dated records retain the former name for audit integrity.
  • Minor-facing? — No current processing. Historical minor-facing use is retained for legal/audit review.

Historical counsel record: assess any disclosure, retention, deletion, or cross-border obligations arising from the period when DeepSeek processed Coach payloads. This is not a current subprocessor approval request.

3. Supabase (database, auth, file/session storage)

  • Field — Detail
  • Service role — Primary datastore (PostgreSQL) and authentication provider. Holds essentially all app data: users, athlete_profiles, chat conversations/messages, workouts, health/recovery metrics, body metrics, guardian consents, subscriptions, teams, recruiting data, etc.
  • Data received — All user-provided and derived data: identity/profile fields, chat message bodies, HealthKit-synced metrics (sleep, HRV, resting heart rate, steps, active calories, workout minutes, weight/body metrics — see HealthKit row), guardian consent records, subscription tier state, UGC/community content, recruiting/NIL data.
  • Processing region — Open question — not determinable from app code. The Supabase project region is set in the Supabase dashboard, not in this repo. The backend reads SUPABASE_URL from env; iOS reads it from build config. Counsel/engineering must confirm the actual Supabase project region from the Supabase dashboard before relying on a residency claim.
  • How it's wired — Backend: @supabase/supabase-js ^2.103.0, service-role client via getServiceClient() (bypasses RLS — backend only). iOS: supabase-swift SDK, auth/session only.
  • Minor-facing? — Yes — stores all minor user data including guardian consent records.

Open questions for counsel (Supabase): - Confirm the Supabase project region (data residency). Engineering can read it from the dashboard on request; it is not in source control. - Supabase BAA/DPA status and sub-processors of *its* own (Supabase runs on AWS) — a vendor-contract question. - The backend uses the service-role key, which bypasses Row-Level Security. Access control is enforced in application code, not the database. Counsel should note this when describing technical/organizational measures.

4. RevenueCat (subscription / purchase management)

  • Field — Detail
  • Service role — Manages subscription entitlements and purchase state for the free / tier1 / tier2 / tier3 tiers. Receives purchase/subscription webhooks server-side and is queried client-side for entitlement state.
  • Data received — Subscription and purchase metadata keyed to an app user identifier; entitlement/tier state. RevenueCat sits between the app and the Apple App Store billing system. Engineering note: the actual app-user-id mapping sent to RevenueCat should be confirmed (whether it's the Supabase user UUID or an anonymized RevenueCat ID) — see open question.
  • Processing region — Open question — not determinable from app code. RevenueCat is a US-based SaaS; specific region/DPA terms are a vendor-contract question.
  • How it's wired — iOS: purchases-ios (RevenueCat) SDK; client API key in Info.plist. Backend: server API key + webhook secret; trainer webhook handler tested at tests/revenuecat-trainer-webhook.test.ts.
  • Minor-facing? — Yes — minors can be on the free tier. Note: per arcqtype-api/CLAUDE.md "Temporary Beta Paywall Bypass", paid-tier enforcement is currently disabled for beta.

Open questions for counsel (RevenueCat): - What identifier Arcqtype sends to RevenueCat as the app-user-id, and whether that constitutes sharing a persistent identifier for a minor. - RevenueCat DPA / region terms — vendor-contract question.

5. Apple — Sign in with Apple (SIWA) + HealthKit + APNs + App Store billing

Apple appears in four distinct roles, which counsel may want to disclose separately:

  • Sub-role — Data received — Region / processing
  • Sign in with Apple — Authentication assertion; Apple-provided user identifier (and email relay if user shares it). The Apple user ID is cached in the device Keychain and used to detect revocation. SIWA is the primary auth method. Token is exchanged with Supabase via PKCE. — Apple (US/global).
  • HealthKit — On-device read only. HealthKit data (sleep, HRV, resting heart rate, steps, active calories, workout minutes, weight/body metrics) is read on the device from Apple Health and is *not* sent to Apple by us. Entitlement: com.apple.developer.healthkit; usage strings NSHealthShareUsageDescription / NSHealthUpdateUsageDescription. However — see the critical note below: the device then forwards selected HealthKit-derived metrics to our backend. — On-device (Apple).
  • APNs (push notifications) — Device push token + notification payloads (notification copy). The backend sends to api.push.apple.com / api.sandbox.push.apple.com. Configured via APNs key/team/bundle. — Apple (US/global).
  • App Store billing — Purchase/receipt data for subscriptions (mediated via RevenueCat). — Apple (US/global).

CRITICAL — HealthKit data leaves the device to our own backend (not to Apple). The iOS app reads HealthKit metrics on-device, then syncs a selected snapshot to the Arcqtype backend via POST /api/health/sync. The synced fields are explicitly: sleep_hours, sleep_quality, resting_heart_rate, hrv, active_calories, steps, workout_minutes, plus body metrics including weight via POST /api/health/body-metrics. Backend routes: health.routes.ts, recovery.routes.ts, sleep.routes.ts. This means HealthKit-derived health data is stored in Supabase and may appear in the Coach prompt context sent to OpenAI. Counsel must treat this as health-data sharing with our backend and downstream processors, not purely on-device use. Apple's HealthKit guidelines also restrict using Health data for advertising/data-mining — a compliance check for counsel.

Open questions for counsel (Apple): - Whether HealthKit-derived data is permitted to enter the OpenAI prompt context under Apple's HealthKit terms and applicable health-data law, especially for minors. Engineering can confirm/scope exactly which health fields, if any, reach the prompt builder if counsel needs the answer. - Whether Apple SIWA should be disclosed as an independent controller vs. a subprocessor.

6. Google — Google Sign-In

  • Field — Detail
  • Service role — Alternative social sign-in (auth only).
  • Data received — OAuth authentication assertion / Google account identifier and basic profile (per Google Sign-In SDK). Used for authentication; token exchanged with Supabase.
  • Processing region — Google (US/global).
  • How it's wired — iOS: GoogleSignIn-iOS SDK; client ID is in Info.plist:33-34 (non-secret, required by the Google SDK) with URL scheme at Info.plist:38-40.
  • Minor-facing? — Yes — available as a sign-in option for all users.

Open questions for counsel (Google Sign-In): - Independent-controller vs. subprocessor classification. - Whether allowing Google Sign-In for under-13 users raises COPPA/Google account-age issues (Google accounts have their own minimum-age terms).

7. Render (application hosting / compute / logs)

  • Field — Detail
  • Service role — Hosts the backend API and supporting services; processes all API traffic and emits server logs. Effectively the compute layer through which all user data transits.
  • Data received — All data in transit to/from the backend API (every request/response), plus whatever is written to server logs. Logging is structured via winston; the codebase generally logs identifiers (e.g., userId) and event metadata rather than raw message bodies, but counsel should treat log contents as a residency/retention surface.
  • Processing region — United States — Oregon. All Render services (dev/staging/prod web, render-worker, cron jobs) are pinned to region: oregon. Per arcqtype-api/CLAUDE.md Git & Deploy, only arcqtype1.onrender.com (the dev service) is live; the legacy prod service was retired 2026-05-20.
  • Minor-facing? — Yes — all minor data transits Render.

Open questions for counsel (Render): Render DPA status and log-retention period (vendor-contract question). Confirm whether any PII is written to logs beyond identifiers/metadata — engineering can audit log call sites if counsel needs a definitive answer.

8. Resend (transactional email)

  • Field — Detail
  • Service role — Sends transactional emails. Two confirmed uses.
  • Data received — (a) Guardian COPPA consent emails — sent to the guardian's email address, containing the guardian's name, the child's first name, and a verification link. (b) Trainer↔athlete message-notification fallback — sent to a recipient's email when an in-app message goes unread; contains the sender's display name and a preview of the message body.
  • Processing region — Open question — not determinable from app code. Resend is a US-based SaaS; specific region/DPA is a vendor-contract question.
  • How it's wired — resend ^6.9.3; new Resend(process.env.RESEND_API_KEY). Sender: noreply@contact.arcqtype.com.
  • Minor-facing? — Yes — the guardian-consent email is *by definition* part of the under-13 flow, and a minor's first name + the guardian's email/name are sent to Resend. Message-fallback previews could contain content from/to minors.

Open questions for counsel (Resend): - Sending a minor's first name and the guardian's email/name to Resend as part of the COPPA consent flow should be confirmed as permissible data minimization (it is arguably the minimum necessary to obtain consent, but counsel should bless it). - Sending message-body previews by email — counsel should confirm this is acceptable for any minor-to-minor or trainer-to-minor messaging, and that the unsubscribe/notification-preference link satisfies requirements.

---

Content-discovery / enrichment services (likely NOT user-data subprocessors — flagged for counsel)

These services are used by backend content pipelines, not per-user data flows. Engineering's read is that they receive search queries about sports/regions/events, not user PII — but counsel should confirm the classification.

9. Brave Search API

  • Field — Detail
  • Service role — Powers recruiting event discovery / enrichment — finds camps, showcases, and recruiting events.
  • Data received (engineering read) — Generic search query strings built from sport + region/state + event-type (e.g., region buckets like "Southeast: FL, GA, SC…"), not user PII. webSearch(query) → https://api.search.brave.com/res/v1/web/search?q=....
  • Processing region — Brave (US).
  • How it's wired — BRAVE_SEARCH_API_KEY.

Open question for counsel: Confirm Brave Search is correctly excluded from the user-data subprocessor list (it receives event-discovery queries, not user records). If any user-specific term ever gets into a query, this changes.

10. Google Places API — configured but not actively used

  • Field — Detail
  • Service role — Intended for place/location lookups.
  • Status — Configured in env but engineering found no call site in src/ or scripts/ that uses it (grep for placesApiKey / maps.googleapis / places.googleapis returns only the env definition). Treat as provisioned-but-dormant.
  • Processing region — Google (US/global) — if/when activated.

Open question for counsel: Because the Places key is dormant, it likely does not belong on the live subprocessor list yet. Engineering should remove the unused env var or document its intended use; counsel should be re-notified if it goes live (it would receive location/place queries that may be user-driven).

---

Supporting / infra notes (not separate subprocessors, but relevant)

  • Render document worker. A separate Render service runs Puppeteer/ExcelJS/docx to render trainer plan documents. It processes Arcqtype-originated plan data inside our own Render footprint — it is part of subprocessor #6 (Render), not a separate vendor. Counsel should note plan documents may contain athlete data.
  • iOS-bundled SDKs that do NOT receive user data (for completeness, so counsel doesn't mistake them for subprocessors): Nuke/NukeUI (on-device image caching), Lottie (on-device animation rendering), Pow (on-device SwiftUI transitions), SSCoachMarks (on-device coach-mark UI) — all from Arcqtype.xcodeproj/project.pbxproj:1139-1195. These are client libraries with no Arcqtype-controlled data egress.

Pending: Sentry (observability / error tracking)

  • Field — Detail
  • Service role — Pending S7 observability provider for error/crash monitoring.
  • Data received — Should receive only scrubbed, minimized error metadata after send_default_pii=false, recursive scrubbing, health-field denylist, and beforeSend stripping are implemented.
  • Processing region — Counsel/vendor-contract question.
  • How it's wired — Not live as of this draft; S7 launch-readiness lane.
  • Minor-facing? — Potentially yes if enabled, because errors can occur on minor accounts. Treat as a health-data surface until scrubbing is verified.

Open questions for counsel (Sentry): DPA, retention window, subprocessor list, and whether a self-hosted Relay is required before any health-adjacent/minor data can be sent.

---

Summary table (for the public-facing subprocessor list draft)

  • # — Subprocessor — Purpose — Data categories — Region — Minor data?
  • 1 — OpenAI — Current OpenAI-only Coach runtime + utility AI — Coach messages/context; utility task payloads — TBD by contract/settings — Yes
  • 2 — DeepSeek (former) — Historical Coach processing; no current path — Historical chat messages + assembled context — Historical PRC processing — No current processing
  • 3 — Supabase — Database + auth — All app data (profile, chat, health metrics, consent, subscription, UGC, recruiting) — TBD — confirm from dashboard — Yes
  • 4 — RevenueCat — Subscriptions — Purchase/entitlement state + app-user-id — TBD (US SaaS) — Yes
  • 5 — Apple — SIWA / HealthKit / APNs / billing — Auth ID; push token + payloads; purchase data (HealthKit read on-device, then forwarded to our backend) — Apple (US/global) — Yes
  • 6 — Google — Google Sign-In — OAuth auth assertion + basic profile — Google (US/global) — Yes
  • 7 — Render — Hosting / compute / logs — All data in transit + server logs — US — Oregon — Yes
  • 8 — Resend — Transactional email — Guardian consent emails (child first name, guardian email/name); message previews — TBD (US SaaS) — Yes
  • 9 — Sentry — Pending observability — Scrubbed error/crash metadata only after S7 — TBD — Potentially
  • 10 — Brave Search — Event discovery — Sport/region/event query strings (no PII per eng. read) — Brave (US) — No (confirm)
  • 11 — Google Places — (dormant) — None currently — key configured, no call site — Google (US) — N/A

---

Maintenance rule

Per legal/README.md:17: every legal-relevant product change — including adding/removing a third-party processor — must update this doc in the same unit of work. When a new external service that touches user data is wired in, add a row here and notify counsel before it goes to production. When Google Places is activated, promote it from "dormant" to a full row.

PrivacyTermsHealth dataDeletionSubprocessorsCommunityLicensesSupport© 2026 Arcqtype, Inc.