billing
internal

Cancel subscription

In-app cancel modal endpoint. Sets Stripe cancel_at_period_end, stashes the canonical Scanopy reason in subscription metadata, returns the period end so the modal can render the retention disclosure.

post/api/billing/cancel

Request body

commentstring nullable
reason_code'too_expensive' | 'missing_features' | 'switched_service' | 'unused' | 'customer_service' | 'low_quality' | 'too_complex' | 'other' required

Cancellation reason captured in SubscriptionCancelled / CancellationInitiated events. Mirrors the values surfaced in the in-app cancel flow (Phase 5).

save_offer_redeemed'pause' | 'discount' | 'downgrade'

Save-offer choices presented during in-app cancellation (Phase 5).

save_offer_shownSaveOffer[]

Response

Cancellation initiated

errorstring nullable
successboolean required

Example response

{
  "meta": {
    "api_version": 1,
    "server_version": "0.16.2"
  }
}

Changes