Upgrade the service's config options
POST/services/:id/upgrade
Upgrades the service's configurable options (resource-role groups like RAM/CPU/disk) to new values. The WHMCS UpgradeProduct action is called with type=configoptions; the prorata difference is calculated on the WHMCS side.
Two modes:
quote_only=true→ with WHMCScalconly=1returns ONLY a price quote (no order/invoice is created,quote=true).quote_only=false(default) → the real upgrade is applied. A difference invoice is created, and the reseller's credit is applied automatically (same as the OrderService ApplyCredit pattern:pending_provision/pending_payment/payment_failed).
Lock guard: Only role=resource groups (RAM/CPU/disk) can be changed via upgrade. Other groups (fixed, old location, or those with no metadata → safe default locked) CANNOT BE CHANGED; if a selection in these groups is changed it returns 422 location_locked. Leaving it at the same value is valid.
Full config (merge): The FULL config is always sent to WHMCS (all of the service's current selections + the reseller's deltas). Because WHMCS resets an unsent config option to the product's default (1st) value (which would give the wrong location + wrong prorata), no selection — including location — is reset.
Downgrade forbidden: If WHMCS returns negative prorata (credit/refund) it returns 409 downgrade_not_allowed.
Conflict: If there is a previous unpaid upgrade invoice for the service, or WHMCS reports upgradeinprogress, 409 upgrade_conflict.
Idempotency-Key: REQUIRED (POST — 24h replay protection).
Rate limit: services_changes bucket (120 rpm).
Body: config_options = { "<whmcs_config_option_id>": <selection_id_or_quantity> } (cannot be empty, int=>int). quote_only optional bool (default false).
Request
Responses
- 200
- 400
- 401
- 403
- 404
- 409
- 422
- 429
- 502
Upgrade applied or quote returned (depending on quote_only)
Response Headers
The per-minute limit defined for this key
Number of requests remaining in the current window
Unix epoch of the start of the next window (UTC seconds)
Invalid upgrade request (invalid_upgrade_request) or missing Idempotency-Key
Authentication failed — missing header, wrong credential, outside the IP whitelist, or a revoked key. No detail is leaked; all cases return a single message.
Response Headers
RFC 7617 Basic Auth challenge
Insufficient authorization — the reseller tried to access another reseller's service_id, or has insufficient scope for an endpoint requiring admin scope. The message is kept generic (ServiceOwnershipMiddleware prevents leakage).
Service not found
Downgrade forbidden (downgrade_not_allowed) or upgrade conflict (upgrade_conflict)
Locked config option group cannot be changed (location_locked)
Per-minute limit exceeded
Response Headers
Seconds to wait before retrying after a 429 (RFC 7231 §7.1.3)
The per-minute limit defined for this key
Unix epoch of the start of the next window (UTC seconds)
WHMCS API upstream error (whmcs_upstream_error)