HelipodDocs

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

GET/vps/:id/renewal-options
Quote every renewal period for this server.
curl 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 }
    ]
  }
}
FieldDescription
priceMonthlyWhat your account pays for one month of this plan.
options[].billingPeriodValue to send to renew.
options[].discountPercent off applied to this period.
options[].monthlyPriceMonthly rate before the period discount.
options[].totalPriceAmount charged for the whole period.
options[].savingsDifference 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

POST/vps/:id/renewcharges your wallet
Pay for another period and move expiresAt forward.

Prop

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 running or stopped.
  • The wallet is charged at once. The same period length as now costs priceSnapshot; a different length is priced fresh, as in renewal options.
  • expiresAt moves forward by 30, 90, 180 or 365 days, counted from the current expiresAt, or from now if that date has passed. Once the renewal is confirmed in the background, expiresAt can be adjusted slightly to the confirmed date.
  • The new period length and price become the instance's billingPeriod and priceSnapshot, used by the next renewal.
  • If the renewal fails in the background, the charge is refunded to the wallet once, the previous expiresAt, billingPeriod and priceSnapshot are restored, and lastJobError explains why. The server keeps its status: a failed renewal never puts it in error.

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

GET/vps/:id/upgrade-options
The plans this server can move to, with what each upgrade costs today.
curl 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

POST/vps/:id/upgradecharges your wallet
Move the server to a larger plan, paying the difference for the days left.

Prop

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 running or stopped, 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 expiresAt and 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 × daysLeft

currentMonthly 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

POST/vps/:id/auto-renew-toggle
Switch auto-renew on or off.
curl -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.

On this page