Change subscription plan/quantity for a product.
const url = 'https://api.siteqwality.com/billing/change-plan';const options = { method: 'POST', headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'}, body: '{"product":"uptime","pack_id":"2489E9AD-2EE2-8E00-8EC9-32D5F69181C0","billing_interval":"example","idempotency_key":"2489E9AD-2EE2-8E00-8EC9-32D5F69181C0"}'};
try { const response = await fetch(url, options); const data = await response.json(); console.log(data);} catch (error) { console.error(error);}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.
Authorizations
Section titled “Authorizations ”Request Body required
Section titled “Request Body required ”object
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.
Responses
Section titled “ Responses ”Plan changed, change scheduled, or payment required
object
Retained so an already-cached frontend bundle keeps working.
One of updated, requires_payment, requires_payment_method,
scheduled, scheduled_change_cancelled. See [change_plan_status].
For scheduled: when the change takes effect (the end of the current
billing period).
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