---
title: "Cancel Subscription"
method: POST
path: "/api/billing/cancel"
tags: ["Billing"]
---

# Cancel Subscription

`POST /api/billing/cancel`

## Request

- Base URL: `https://api.soeru.biz` (the document declares no server; this is the origin it was published from)
- URL: `https://api.soeru.biz/api/billing/cancel`
- Auth: none declared. Required headers: `authorization`

Cancel the user's Stripe subscription.

Default behavior: cancel at end of current billing period (prorate=False).
The user retains access until `current_period_end`, then the webhook
`customer.subscription.deleted` automatically downgrades to free.

If immediate=True, cancel right away and prorate.

Phase 3 (2026-04-26 fix): brand_id を必須に近い形で受ける。multi-brand
owner で brand_id を渡さずに呼ぶと 400 で拒否 (どの sub をキャンセルする
か曖昧)。1-brand owner は legacy 互換で brand_id 省略可。Stripe 上は対象
の 1 sub のみ delete し、DB UPDATE も WHERE id = (target row id) で 1 行
限定 — owner_id 単条件で全 sub を巻き込む旧バグの再発を防ぐ。

## Headers

- `authorization` string, required: Bearer <token>

## Request body

- CancelRequest: Request body for subscription cancellation.
  - `immediate` boolean
  - `reason` string, nullable
  - `brand_id` string, nullable

## Response `200`

Successful Response

- unknown

## Other responses

- `422`: Validation Error

---

[API](https://skmtc.dev/soeru/apis/soeru-api.md) · [All operations](https://skmtc.dev/soeru/apis/soeru-api/llms.txt) · [OpenAPI document](https://skmtc.dev/soeru/apis/soeru-api/revisions/63f8d371abed?raw)
