---
title: "Cancel With Refund"
method: POST
path: "/api/billing/cancel"
tags: ["billing"]
---

# Cancel With Refund

`POST /api/billing/cancel`

Self-serve cancel-and-refund within the 14-day money-back window.

Both sides happen immediately: the Stripe subscription is canceled now
(not at period end) and the original charge is refunded in full now.
Access ends immediately — there is no grace period. A cancellation
reason is required (see `_CANCEL_REASON_PATTERN`) so we have a record of
why customers are refunding.

Order matters on failure: refund first, then cancel. If the refund call
fails we stop — the customer keeps their subscription and we haven't
taken an action we can't undo. If cancel fails *after* a successful
refund, the org is left as-is (still paid) rather than silently losing
access with no subscription to show for it; that case needs a human
follow-up, which the audit row surfaces.

## Request body

- SelfServeCancelRequest
  - `reason` string, required
  - `reason_detail` string, nullable

## Response `200`

Successful Response

- SelfServeCancelResponse
  - `plan_tier` string, required
  - `subscription_status` string, required
  - `refunded` boolean, required
  - `refund_amount_cents` integer, nullable
  - `subscription_canceled` boolean, required

## Other responses

- `422` — Validation Error

---

[API](https://skmtc.net/codag/apis/infra-logs-templater.md) · [All operations](https://skmtc.net/codag/apis/infra-logs-templater/llms.txt) · [OpenAPI document](https://skmtc-service-staging.skmtc.workers.dev/v1/apis/codag/infra-logs-templater/revisions/64da737bcc9e/schema)
