Skip to content

Buy an add-on, or move between tiers of one.

POST
/billing/addons
curl --request POST \
--url https://api.siteqwality.com/billing/addons \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '{ "pack_id": "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0", "billing_interval": "example", "idempotency_key": "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0" }'
Media type application/json
object
pack_id
required
string format: uuid
billing_interval
required

"month" or "year".

string
idempotency_key
required

Client-generated, stable across retries of ONE confirm attempt.

This is what makes a double-click safe: the same value twice is one Stripe mutation. A client that omits it gets no protection, which is why it is required rather than optional here (unlike change-plan, which has to keep accepting bodies from already-cached bundles).

string format: uuid
Example generated
{
"pack_id": "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0",
"billing_interval": "example",
"idempotency_key": "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0"
}

Add-on purchased or changed

Media type application/json
object
success
required

Retained for symmetry with change-plan, whose older clients read it.

boolean
status
required

"updated" when the change is live, "requires_payment" when the customer must confirm a payment before it takes effect.

string
client_secret
string | null
stripe_subscription_id
string | null
Example generated
{
"success": true,
"status": "example",
"client_secret": "example",
"stripe_subscription_id": "example"
}

Invalid interval, unknown pack, pack is not an add-on, or already on that tier

Missing or invalid authentication

Caller is not a super admin

Account has no Stripe customer

Internal server error