Skip to content

Suspend, ban, reactivate

Three actions, three purposes. Get the choice right the first time: reactivating is easy, but pattern-of-bans matters for legal defense in disputes.

Temporary account freeze. Use for:

  • Behavioral warnings (spam, low-effort comments)
  • Payment fraud investigations in progress
  • User-requested cooldown (“delete my account for 30 days”)

Fields:

  • Reason: required, 3–500 chars. Shown to the user on their next login attempt.
  • Until: optional ISO datetime. If absent, suspension is indefinite until reactivated.

Effect:

  • Mobile API returns 403 account_suspended on protected endpoints.
  • Read endpoints still work for guest-like actions (browse the catalog) but any personalized surface (wallet, my-list, unlocks) is blocked.
  • Existing unlocks are preserved: nothing burns.

Permanent account termination. Use for:

  • Confirmed fraud (multi-account chargeback rings)
  • Terms-of-service violations serious enough to justify no comeback
  • Regulatory holds (sanctions, minors detected)

Fields:

  • Reason: required, 5–500 chars (longer minimum than suspend, forces intent).
  • Typed confirmation: type the user’s email/phone or ID to unlock the Confirm button.

Effect:

  • Full API lockout. Every authenticated endpoint returns 403 account_banned.
  • User cannot reset password or log in again. Signup on the same email returns “unavailable”.
  • Existing unlocks and wallet are preserved but frozen: cannot spend or top up.
  • Multi-device fingerprints from this user are tagged in the fraud graph for future signup gating.

Banning is not GDPR deletion. Use Anonymize for that.

Undoes suspend or ban. Use for:

  • False positives
  • User completed appeal
  • Manual test cleanup

Fields:

  • Note: optional, ≤500 chars. Appears in the audit trail.

Effect:

  • Status returns to active.
  • suspended_until and ban_reason are cleared (kept in AuditLog before/after diff for history).
  • No coin refunds or unlock rollbacks happen: the user just gets their account back.

The comment moderation system runs its own suspend flow:

  • 3 confirmed strikes on user_strikes (kind=comment) → automatic comment suspension (not full account suspension). User can still watch and pay, but not comment.
  • This is handled by the moderation service on strike creation. You do not need to manually suspend for comment strikes.
  • Full-account suspension for comment behavior requires an explicit POST /admin/users/:id/suspend.

Every suspend/ban/reactivate writes:

  • AuditLog entry with action='user.suspend|ban|reactivate', before (previous status), after (new status + reason).
  • admin_id, ip, user_agent.
  • Banning a user with an active subscription does not cancel the subscription: the store or card MID keeps billing. Cancel the subscription separately (or let it lapse), or refund proactively.
  • Suspending an “in-flight” purchase: if a webhook lands for a payment they made pre-suspension, we still credit the wallet (money is money). The user just can’t spend it while suspended.
  • suspended_until in the past: the mobile API auto-reactivates on the next request. But the admin panel status column may lag until the check runs.
ActionEndpoint
SuspendPOST /v1/admin/users/:id/suspend
BanPOST /v1/admin/users/:id/ban
ReactivatePOST /v1/admin/users/:id/reactivate
Force logout all devicesPOST /v1/admin/users/:id/devices/logout-all

Full details in API: Users.