---
title: "Create Monthly Switch Portal"
method: POST
path: "/api/billing/monthly-switch-portal"
tags: ["billing"]
---

# Create Monthly Switch Portal

`POST /api/billing/monthly-switch-portal`

Switch an annual Team subscription to monthly.

Paid annual subscribers get Stripe's confirmation UI: the server does not
mutate the subscription; Stripe shows the exact unused-time credit and
applies the update only after the customer explicitly confirms it.

TRIALING annual subscribers (deal-link 30-day opt-out window) are switched
directly with `trial_end="now"`: monthly has no trial by policy, so the
switch ends the window and charges the first $499 immediately. The console
button states the charge; `error_if_incomplete` keeps the subscription
unchanged if the card declines.

## Request body

- MonthlySwitchPortalRequest
  - `deal_code` string, required

## Response `200`

Successful Response

- MonthlySwitchPortalResponse
  - `portal_url` string, required
  - `status` string, required

## Other responses

- `422` — Validation Error

## Changes

- **2026-08-18** `64da737bcc9e` — 1 breaking, 3 info
  - added the pattern `^[A-Za-z0-9_-]+$` to the request property `deal_code`
  - api operation id `monthly_switch_portal_api_billing_monthly_switch_portal_post` removed and replaced with `create_monthly_switch_portal_api_billing_monthly_switch_portal_post`
  - the response property `portal_url` became required for the status `200`
  - response property `portal_url` list-of-types was narrowed by removing types `null` from media type `application/json` of response `200`
- **2026-08-16** `44d8ea826f48` — 2 breaking, 2 info
  - the response property `portal_url` became optional for the status `200`
  - response property `portal_url` list-of-types was widened by adding types `null` to media type `application/json` of response `200`
  - api operation id `create_monthly_switch_portal_api_billing_monthly_switch_portal_post` removed and replaced with `monthly_switch_portal_api_billing_monthly_switch_portal_post`
  - removed the pattern `^[A-Za-z0-9_-]+$` from the request property `deal_code`
- **2026-08-13** `d80008a9efc6` — 1 info
  - endpoint added
- **2026-08-12** `8540ec6c1778` — 1 breaking
  - api path removed without deprecation
- **2026-08-06** `a2c84c9154da` — 1 info
  - endpoint added

[Change history](https://skmtc.dev/codag/apis/infra-logs-templater/changes/api/billing/monthly-switch-portal/post.md)

---

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