---
title: "Redeem With Cancel"
method: POST
path: "/api/v1/billing/trial-codes/redeem-with-cancel"
tags: ["trial-codes"]
---

# Redeem With Cancel

`POST /api/v1/billing/trial-codes/redeem-with-cancel`

## Request

- Base URL: `http://localhost:8000`
- URL: `http://localhost:8000/api/v1/billing/trial-codes/redeem-with-cancel`
- Auth: none declared

Redeem a trial code for an existing paying customer.

TECH-657: Cancels the Stripe subscription (triggers prorated credit),
then applies the trial with the target plan.

Transaction Safety (order prevents data loss):
1. Validate code
2. Record redemption (marks code as used)
3. Update subscription to trial with target plan
4. Clear Stripe IDs in DB
5. COMMIT DB FIRST (ensures trial is active before touching Stripe)
6. Cancel Stripe subscription (external call, may fail)

Why commit before Stripe cancel:
- If DB commit fails: Customer keeps Stripe subscription (safe rollback)
- If Stripe cancel fails after commit: Customer has trial + Stripe sub
  (recoverable via manual cancellation, customer is not left without access)
- Previous approach risk: If Stripe succeeds but commit fails, customer
  loses Stripe sub AND doesn't get trial (unrecoverable data loss)

## Headers

- `Authorization` string

## Request body

- RedeemWithCancelRequest: Request to redeem a trial code with subscription cancellation (TECH-657). For existing paying customers: cancels Stripe subscription and applies trial.
  - `code` string, required: Trial code to redeem

## Response `200`

Successful Response

- StandardResponse: Standard API response wrapper.
  - `success` boolean, required
  - `data` unknown
  - `message` string, nullable
  - `error` string, nullable
  - `meta` object, nullable

## Other responses

- `422`: Validation Error

---

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