v62

latestOpenAPI 3.1.0Dual (AGPL3.0, Commercial License Available)raw.githubusercontent.com2026-08-03211303932.5 KB
billing
internal

Cancel subscription

In-app cancel modal endpoint. Sets Stripe cancel_at to the current period end (via Stripe's MaxPeriodEnd sentinel), 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

Free-text detail the customer added to their cancellation reason.

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

Whether the retention discount was offered during this flow.

Response

Cancellation initiated

errorstring nullable

Human-readable failure message. Omitted on success.

successboolean required

true when the request succeeded. false responses carry error instead of data.

Example response

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