settings
sync
ai

User Delete

GDPR account deletion request (COUNSEL-09 + F11 2026-04-30 PM; R-RESCIND OWNER 2026-09-25).

Two-phase deletion:

  1. NOW (this handler): mark deletion_requested_at THEN set every Stripe subscription to cancel AT PERIOD END (mark first since 2026-09-24: the eventual .deleted webhook reads the mark to suppress the Developer-plan final overage invoice). A trial holds no subscription and runs out on its own.
  2. +30 days (services/automation.py daily cron): HARD-cancel every subscription (nothing renews past the window), then cascade-delete user_billing / credit_purchases / portfolios / pg_watchlist / api_keys and DELETE FROM users.

The 30-day window is GDPR Article 17-aligned and is a real grace window: POST /api/settings/cancel-deletion (routes_settings_erasure_fastapi.py, which records why it did not exist before R-RESCIND) rescinds inside it and lifts the period-end cancel.

Failure modes (defense-in-depth)

  • Stripe API down: deletion_requested_at is still set so the cron eventually processes the user. Stripe failure is logged + Sentry- breadcrumbed but does NOT block the request; the purge's hard cancel is the backstop.
  • No Stripe subscription (free tier / trial): nothing to schedule.
post/api/user/delete

Request

  • Base URL: https://www.oxfordledge.com (the document declares no server; this is the origin it was published from)
  • URL: https://www.oxfordledge.com/api/user/delete
  • Auth: none declared

Response

Successful Response

UserDataResponse required

Loose response_model for user-data routes (export, delete, consent, preferences). Multiple shape variants per action.

Changes

No recorded changes to this operation across all 1 revision of this API.