Cancel Subscription
Cancel one product’s subscription for this organization.
Per-product, not per-org: à la carte means an org can hold four
independent subscriptions (§12), so cancelling monitoring must not touch
OTA. The row is found via the "plan_code:organization_id" composite in
subscriptions.product_code — built here from PLAN_CODE_FOR_PRODUCT,
the same mapping entitlement_projection._resolve_org_and_product parses
that column back out with.
The gateway is called before any local write, so a refusal leaves no
record of a cancellation that did not happen. The reverse gap — gateway
cancelled, local commit lost — is self-healing: the gateway’s own
customer.subscription.deleted webhook re-projects the same absolute
state.
Authorizations
Parameters
Query Parameters
Request Body required
POST /api/billing/cancel.
product is the à la carte product whose subscription to cancel
(‘ota’ | ‘monitoring’ | ‘crash_reporting’ | ‘remote_ssh’) — NOT the
subscriptions.product_code column, which is the composite
“plan_code:organization_id” (§3.1). Naming it product keeps it in the
same vocabulary as organization_entitlements.product and
ProductEntitlementItem above; the route resolves the plan_code and the
composite from it.
object
Responses
200
Successful Response
422
Validation Error