Skip to content

Change subscription plan/quantity for a product.

POST
/billing/change-plan
curl --request POST \
--url https://api.siteqwality.com/billing/change-plan \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '{ "product": "uptime", "pack_id": "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0", "billing_interval": "example", "idempotency_key": "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0" }'

Upgrades apply now and are charged now for the prorated difference, and only once that charge is paid. Downgrades are scheduled for the end of the current billing period with no credit or refund; picking the current plan again cancels a scheduled downgrade.

Media type application/json
object
product
required
string
Allowed values: uptime synthetic telemetry incidents sms status_pages rum_observe rum_analyze session_replay partner
pack_id
required
string format: uuid
billing_interval
required
string
idempotency_key

Client-generated, stable across retries of ONE confirm attempt, so a double-click is one Stripe mutation.

Optional purely for backwards compatibility: a cached frontend bundle predating this field must keep working. A request without one gets no replay protection beyond the per-account advisory lock, which serializes concurrent requests but cannot recognise a client retry after a timeout.

string | null format: uuid

Plan changed, change scheduled, or payment required

Media type application/json
object
success
required

Retained so an already-cached frontend bundle keeps working.

boolean
status
required

One of updated, requires_payment, requires_payment_method, scheduled, scheduled_change_cancelled. See [change_plan_status].

string
client_secret
string | null
stripe_subscription_id
string | null
effective_at

For scheduled: when the change takes effect (the end of the current billing period).

string | null format: date-time
Example generated
{
"success": true,
"status": "example",
"client_secret": "example",
"stripe_subscription_id": "example",
"effective_at": "2026-04-15T12:00:00Z"
}

Invalid billing interval, or already on that plan

Missing or invalid authentication

Caller is not a super admin

The subscription is set to cancel; resume it first

Internal server error