Billing
Quote and pay renewals, upgrade to a larger plan and switch auto-renew on or off.
A server is paid in advance for a period of 1, 3, 6 or 12 months. expiresAt on the instance marks the end of the paid period. All amounts are in Rupiah and are taken from the key owner's wallet.
Renewal options
/vps/:id/renewal-optionscurl https://api.helipod.io/api/vps/1f757fd5-98d1-490a-81a0-58b5798a5815/renewal-options \
-H "Authorization: Bearer hel_your_key"{
"success": true,
"data": {
"instanceId": "1f757fd5-98d1-490a-81a0-58b5798a5815",
"planName": "VPS S - Jakarta",
"currentBillingMonths": 1,
"currentExpiresAt": "2026-11-15T08:22:12.000Z",
"priceMonthly": 64900,
"options": [
{ "billingPeriod": "monthly", "months": 1, "discount": 0, "monthlyPrice": 64900, "totalPrice": 64900, "savings": 0 },
{ "billingPeriod": "3month", "months": 3, "discount": 5, "monthlyPrice": 64900, "totalPrice": 184965, "savings": 9735 },
{ "billingPeriod": "6month", "months": 6, "discount": 10, "monthlyPrice": 64900, "totalPrice": 350460, "savings": 38940 },
{ "billingPeriod": "yearly", "months": 12, "discount": 15, "monthlyPrice": 64900, "totalPrice": 661980, "savings": 116820 }
]
}
}| Field | Description |
|---|---|
priceMonthly | What your account pays for one month of this plan. |
options[].billingPeriod | Value to send to renew. |
options[].discount | Percent off applied to this period. |
options[].monthlyPrice | Monthly rate before the period discount. |
options[].totalPrice | Amount charged for the whole period. |
options[].savings | Difference with paying the monthly rate for every month. |
These quotes use the plan's current price. A renewal for the same period length as the current one (currentBillingMonths) charges the price you locked in when you bought or last renewed (priceSnapshot on the instance), which can differ from the quote if the catalogue price has changed since.
Renew
/vps/:id/renewcharges your walletProp
Type
curl -X POST https://api.helipod.io/api/vps/1f757fd5-98d1-490a-81a0-58b5798a5815/renew \
-H "Authorization: Bearer hel_your_key" \
-H "Content-Type: application/json" \
-d '{ "billingPeriod": "3month" }'{
"success": true,
"data": {
"id": "1f757fd5-98d1-490a-81a0-58b5798a5815",
"status": "running",
"billingPeriod": 3,
"priceSnapshot": "184965.00",
"expiresAt": "2027-02-13T08:22:12.000Z",
"lastJobType": "vps:renew",
"lastJobStatus": "pending"
}
}- The server must be
runningorstopped. - The wallet is charged at once. The same period length as now costs
priceSnapshot; a different length is priced fresh, as in renewal options. expiresAtmoves forward by 30, 90, 180 or 365 days, counted from the currentexpiresAt, or from now if that date has passed. Once the renewal is confirmed in the background,expiresAtcan be adjusted slightly to the confirmed date.- The new period length and price become the instance's
billingPeriodandpriceSnapshot, used by the next renewal. - If the renewal fails in the background, the charge is refunded to the wallet once, the previous
expiresAt,billingPeriodandpriceSnapshotare restored, andlastJobErrorexplains why. The server keeps its status: a failed renewal never puts it inerror.
Renewing is not blocked by VPS_BUSY: you can renew while a backup or another action is running. Errors: 400 INVALID_BILLING_PERIOD when billingPeriod is not monthly, 3month, 6month or yearly, 402 INSUFFICIENT_BALANCE when the wallet cannot cover the renewal, and 400 REQUEST_ERROR for a wrong status. Nothing is charged when the call fails.
Upgrade options
/vps/:id/upgrade-optionscurl https://api.helipod.io/api/vps/1f757fd5-98d1-490a-81a0-58b5798a5815/upgrade-options \
-H "Authorization: Bearer hel_your_key"{
"success": true,
"data": {
"current": {
"planId": "4db565ff-782f-46c8-9324-e4670517233f", "planName": "VPS 2",
"cpuCores": 2, "ramMb": 4096, "diskGb": 60,
"billingPeriodMonths": 1, "expiresAt": "2026-11-15T08:22:12.000Z", "remainingDays": 29
},
"currency": "IDR",
"available": [
{
"planId": "8e1d3b2a-6c4f-4a7e-b9d0-2f3a4b5c6d7e", "name": "VPS 4", "slug": "vps-4",
"cpuCores": 4, "ramMb": 8192, "diskGb": 80, "bandwidthGb": null,
"priceMonthly": 129900, "upgradeCost": 58000,
"region": { "name": "Jakarta", "code": "jkt" }
}
]
}
}upgradeCost is what POST /vps/:id/upgrade charges now for the rest of the current period; the expiry date does not change. Servers that the API cannot upgrade answer 409 FEATURE_NOT_AVAILABLE.
Upgrade to a larger plan
/vps/:id/upgradecharges your walletProp
Type
curl -X POST https://api.helipod.io/api/vps/1f757fd5-98d1-490a-81a0-58b5798a5815/upgrade \
-H "Authorization: Bearer hel_your_key" \
-H "Content-Type: application/json" \
-d '{ "planId": "8e1d3b2a-6c4f-4a7e-b9d0-2f3a4b5c6d7e" }'{
"success": true,
"data": {
"id": "1f757fd5-98d1-490a-81a0-58b5798a5815",
"planId": "8e1d3b2a-6c4f-4a7e-b9d0-2f3a4b5c6d7e",
"status": "provisioning",
"cpuCores": 4,
"ramMb": 8192,
"diskGb": 80,
"priceSnapshot": "129900.00",
"expiresAt": "2026-11-15T08:22:12.000Z",
"lastJobType": "vps:upgrade",
"lastJobStatus": "pending"
}
}Rules
- The server must be
runningorstopped, and not busy. - The new plan must be in the same region and the same plan family (
type), and larger in at least one of CPU, RAM or disk. Downgrades are not possible. - The upgrade changes the size only. It does not extend
expiresAtand keeps the current period length.
Charge. You pay the difference in monthly price for the whole days left in the current period:
charge = (newMonthly - currentMonthly) / 30 × daysLeftcurrentMonthly is what you paid for the current period divided by its months, and newMonthly is the new plan's price for your account. When the result is zero (for example on the last day of the period) the upgrade is refused; renew first. After the upgrade, priceSnapshot is the new plan's price for your period length, so the next renewal charges the new price.
The status becomes provisioning while the server is resized and settles on running (or stopped, if it was stopped) when done. If the resize fails, the prorated charge is refunded to the wallet once, the old plan, CPU, RAM, disk and priceSnapshot are restored, the server goes back to the status it had before the call, and lastJobError explains why.
Errors: 409 VPS_BUSY, 402 INSUFFICIENT_BALANCE when the wallet cannot cover the charge, and 400 REQUEST_ERROR for a wrong status, a plan in another region or family, a plan that is not larger or a zero charge.
Auto-renew
/vps/:id/auto-renew-togglecurl -X POST https://api.helipod.io/api/vps/1f757fd5-98d1-490a-81a0-58b5798a5815/auto-renew-toggle \
-H "Authorization: Bearer hel_your_key"{ "success": true, "data": { "autoRenew": false } }The call takes no body and flips the current value; the response gives the new one. Read autoRenew on the instance first if you need a specific state.
New servers start with auto-renew on. Shortly before expiresAt, a server with auto-renew on is renewed from the wallet for its current period length. If auto-renew is off, or the wallet cannot cover the renewal, the server expires and is terminated after a short grace period.