All routes require an authenticated Medusa Admin user. Unauthenticated requests return
401.Status values
| Value | Meaning |
|---|---|
requested | Customer has requested cancellation |
evaluating_retention | Case is open and under admin review |
retention_offered | A retention offer has been proposed |
retained | Customer accepted a retention offer |
paused | Subscription was paused as a retention outcome |
canceled | Case is finalized as cancelled |
retained, paused, canceled.
Offer decision status values: proposed, accepted, rejected, applied, expired.
Reason category values: price, product_fit, delivery, billing, temporary_pause, switched_competitor, other.
GET /admin/cancellations
Returns the paginated cancellation queue for Admin DataTable views.Query parameters
Number of results per page.
Zero-based result offset for pagination.
Free-text search across subscription reference, customer name, and product title.
Field to sort by. Database-backed:
created_at, updated_at, status, final_outcome, reason_category, finalized_at. In-memory: subscription_reference, customer_name, product_title.Sort direction. One of
asc or desc.Filter by case status. Accepts a single value or an array.
Filter by final outcome. Accepts a single value or an array.
Filter by churn reason category. Accepts a single value or an array.
Filter by retention offer type. Accepts a single value or an array.
Filter to cases for a specific subscription.
ISO datetime lower bound for
created_at.ISO datetime upper bound for
created_at.Response
Array of cancellation case list items.
Total matching records.
Page size used.
Result offset used.
Response example
Errors
| Code | Error | Meaning |
|---|---|---|
400 | invalid_data | Invalid query parameter shape, unsupported query value, or unsupported sort field |
GET /admin/cancellations/:id
Returns the full detail payload for a single cancellation case, including offer history, subscription context, and linked renewal or dunning summaries.Path parameters
Cancellation case ID.
Response
Response example
Errors
| Code | Error | Meaning |
|---|---|---|
404 | not_found | Cancellation case does not exist |
POST /admin/cancellations/:id/apply-offer
Applies a retention action to an open case. Creates aRetentionOfferEvent, updates the subscription, and closes the case as retained or paused. Returns the refreshed detail payload.
Path parameters
Cancellation case ID.
Body parameters
Type of retention offer. One of
pause_offer, discount_offer, or bonus_offer.Offer-specific configuration. Shape depends on
offer_type — see examples below.Actor ID of the admin user applying the offer.
Optional reason for applying the offer.
Pause offer example
Discount offer example
Bonus offer example
Validation rules:
pause_offer requires pause_cycles or resume_at; percentage discounts cannot exceed 50; discount_value must be positive; duration_cycles must be positive when provided; free_cycle and credit bonus types require value.Errors
| Code | Error | Meaning |
|---|---|---|
404 | not_found | Cancellation case does not exist |
409 | invalid_state | Case is terminal or cannot accept a new offer |
409 | offer_out_of_policy | Offer payload violates retention policy rules |
POST /admin/cancellations/:id/reason
Updates the churn reason, normalized category, and operator notes for an open case. Returns the refreshed detail payload.Path parameters
Cancellation case ID.
Body parameters
Free-text churn reason.
Normalized reason category.
Operator notes.
Actor ID of the admin user making the update.
Reason for the classification change.
Request example
Errors
| Code | Error | Meaning |
|---|---|---|
404 | not_found | Cancellation case does not exist |
409 | invalid_state | Case is terminal or cannot be edited |
POST /admin/cancellations/:id/finalize
Finalizes a case ascanceled, updates the subscription lifecycle, computes cancel_effective_at, and clears renewal eligibility. Returns the refreshed detail payload.
Path parameters
Cancellation case ID.
Body parameters
Churn reason for the final cancellation. Required by domain rules; if omitted, the workflow falls back to the existing case reason.
Normalized reason category.
Operator notes.
Actor ID of the admin user finalizing the case.
When the cancellation takes effect. One of
immediately or end_of_cycle.Request example
Errors
| Code | Error | Meaning |
|---|---|---|
400 | invalid_data | Reason is missing after resolving body and existing case data |
404 | not_found | Cancellation case does not exist |
409 | invalid_state | Case is terminal or not eligible for final cancellation |