HelipodDocs

Registration

Register, transfer and renew domains, and check the owner details the registry needs.

Registering, transferring and renewing a domain charge your wallet. Prices are the ones in the price list, VAT included. WHOIS protection is priced the same everywhere: the whois_protection price, currently Rp 20,000 per year.

Owner details

The registry needs real owner (registrant) details for every domain. Helipod never sends placeholder data, so registration and transfer are refused until these fields are filled in your account:

FieldLabel in messages
namenama
phonenomor telepon
addressLine1alamat
citykota
stateprovinsi
countryCodenegara
postalCodekode pos

Organization is optional (the name is used when it is empty). Set them once with PATCH /domains/registrant or in the Helipod dashboard. The current details are used for every new registration or transfer, so edits apply to domains you add afterwards.

GET/domains/registrant
Whether your owner details are complete.
curl https://api.helipod.io/api/domains/registrant \
  -H "Authorization: Bearer hel_your_key"
Response
{
  "success": true,
  "data": { "complete": false, "missing": ["phone", "postalCode"] }
}

missing lists the field names from the table above. It is empty when complete is true.

Set owner details

PATCH/domains/registrant
Fill in or change your owner details. Send only the fields you want to set.

Prop

Type

curl -X PATCH https://api.helipod.io/api/domains/registrant \
  -H "Authorization: Bearer hel_your_key" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Ana Putri",
    "phone": "+6281234567890",
    "addressLine1": "Jl. Sudirman No. 1",
    "city": "Jakarta Selatan",
    "state": "DKI Jakarta",
    "countryCode": "ID",
    "postalCode": "12190"
  }'
Response
{
  "success": true,
  "data": {
    "complete": true,
    "missing": [],
    "updated": ["name", "phone", "addressLine1", "city", "state", "countryCode", "postalCode"]
  }
}

The response never repeats the details themselves: updated names the fields you sent, and complete and missing say what is still needed. An empty body answers 422 VALIDATION_ERROR; a value the profile rejects answers 400 INVALID_REGISTRANT. Once the details are complete, any pending profile domain from a purchase is registered for you.

Check the price first

Register, transfer and renew accept ?dryRun=true. Nothing is charged or sent to the registry; the response shows the price and your wallet after it:

curl -X POST "https://api.helipod.io/api/domains/register?dryRun=true" \
  -H "Authorization: Bearer hel_your_key" \
  -H "Content-Type: application/json" \
  -d '{ "name": "example.com", "period": 1, "whoisProtection": true }'
Response
{
  "success": true,
  "data": {
    "dryRun": true,
    "price": 219000,
    "currency": "IDR",
    "billing": { "ppn": 21703, "registration": 199000, "whoisProtection": 20000, "total": 219000 },
    "walletBalance": 500000,
    "walletBalanceAfter": 281000,
    "enoughBalance": true
  }
}

A dry run makes the same checks as the real call (supported extension, name free, owner details complete), so it fails with the same codes. billing has the same fields as the real call's billing, without depositCharged; a transfer has ppn and charged, and a renewal also returns the domain and its current expiresAt.

Supported extensions

New registrations and transfers are accepted for these extensions:

.com .id .dev .app .net .in .biz .link .biz.id .my.id .web.id .ai.id

Any other extension returns 400 TLD_NOT_SUPPORTED. Subdomains (for example shop.example.com) cannot be registered.

Register a domain

POST/domains/registercharges your walletdryRun
Register a new domain for one year.

Prop

Type

curl -X POST https://api.helipod.io/api/domains/register \
  -H "Authorization: Bearer hel_your_key" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "example.com",
    "period": 1,
    "nameservers": ["ns1.example-dns.net", "ns2.example-dns.net"],
    "whoisProtection": false
  }'
Response (201)
{
  "success": true,
  "data": {
    "name": "example.com",
    "status": 1,
    "status_label": "Active",
    "nameserver_1": "ns1.example-dns.net",
    "nameserver_2": "ns2.example-dns.net",
    "expired_at": "2027-10-16 00:00:00",
    "created_at": "2026-10-16 09:12:44"
  },
  "billing": {
    "ppn": 18730,
    "registration": 199000,
    "whoisProtection": 0,
    "total": 199000,
    "depositCharged": 199000
  }
}

data describes the registration as reported by the registry (name, status, nameservers, expiry). It does not contain the Helipod domain id: call GET /domains/mine to get the id used by every other endpoint.

billing fieldDescription
ppnVAT included in registration.
registrationOne-year registration price, VAT included.
whoisProtectionAmount added for WHOIS protection (the whois_protection price), 0 when not requested.
totalTotal charged to your wallet.
depositChargedAmount taken from your deposit balance (equal to total).
special_pricetrue when the extension's special price was applied.
promoName of the promotion applied, when one was running.

What is checked, in order

  1. The name is not premium (400 PREMIUM_NOT_SUPPORTED when includePremium is true).
  2. The extension is supported (400 TLD_NOT_SUPPORTED otherwise).
  3. period is 1 (422 VALIDATION_ERROR otherwise).
  4. The name is not already held: 409 DOMAIN_UNAVAILABLE when it belongs to another account, 409 DOMAIN_ALREADY_IN_ACCOUNT when it is already in yours. Your own pending profile domain or failed transfer for the same name can be registered.
  5. A valid price exists for the extension (400 PRICE_UNAVAILABLE otherwise).
  6. Your owner details are complete (400 REGISTRANT_INCOMPLETE, with a missing list).
  7. Your wallet balance covers the total (402 INSUFFICIENT_BALANCE otherwise).

Nothing is charged when one of these fails. After the charge, the request goes to the registry. If the registry rejects it (for example the name was taken in the meantime, or it is a premium name), the response is 422 REGISTRAR_REJECTED; if the registry cannot be reached, it is 502 REGISTRAR_ERROR. In both cases the full amount is refunded to your wallet.

If the registry registered the domain but Helipod could not record it, the response is still 201, with code: "DOMAIN_SAVE_PENDING" and a message asking you to contact support. The domain is yours and nothing is refunded; do not retry. See Delivered but not yet recorded.

Owner details missing (400)
{
  "success": false,
  "error": "Lengkapi data pemilik domain dulu: nomor telepon, kode pos",
  "code": "REGISTRANT_INCOMPLETE",
  "missing": ["phone", "postalCode"]
}

Search the name first. A registration for a name that is not available is refused and refunded, but you still spend a request.

Transfer a domain

POST/domains/transfercharges your walletdryRun
Move a domain you own at another registrar to Helipod.

Prop

Type

curl -X POST https://api.helipod.io/api/domains/transfer \
  -H "Authorization: Bearer hel_your_key" \
  -H "Content-Type: application/json" \
  -d '{ "name": "example.net", "authCode": "Xy7#k2Lp9q", "period": 1 }'
Response (201)
{
  "success": true,
  "data": {
    "name": "example.net",
    "status": 5,
    "status_label": "Pending Transfer",
    "nameserver_1": "ns1.example-dns.net",
    "nameserver_2": "ns2.example-dns.net"
  },
  "billing": {
    "ppn": 20216,
    "charged": 214000,
    "depositCharged": 214000
  }
}

With "whoisProtection": true the response also carries a notice:

{
  "notice": "WHOIS protection is not included in a transfer. Enable it from the domain page once the transfer is complete."
}
  • Only the supported extensions can be transferred (400 TLD_NOT_SUPPORTED).
  • period must be 1 (400 PERIOD_NOT_SUPPORTED).
  • Your owner details must be complete (400 REGISTRANT_INCOMPLETE, with a missing list).
  • The name must not already be held: 409 DOMAIN_UNAVAILABLE or 409 DOMAIN_ALREADY_IN_ACCOUNT.
  • WHOIS protection is not included. Enable it once the transfer is complete.
  • The charge is the extension's one-year transfer price from the price list (billing.charged). 402 INSUFFICIENT_BALANCE when the balance is too low. Nothing is charged when one of these checks fails.
  • Before you start, unlock the domain at your current registrar and get its auth code.
  • A wrong auth code or a locked domain is refused by the registry: 422 REGISTRAR_REJECTED, and the charge is refunded. A registry outage is 502 REGISTRAR_ERROR, also refunded.
  • If the transfer was accepted but Helipod could not record it, the response is 201 with code: "DOMAIN_SAVE_PENDING". Contact support and do not retry.

The domain appears in GET /domains/mine with status pending_transfer. Its status is synced from the registry when you list or read your domains, and once a day, so it becomes active on its own when the transfer completes (or transfer_failed if it does not).

Renew a domain

POST/domains/{id}/renewcharges your walletdryRun
Extend a domain by one year.

{id} is the domain id from GET /domains/mine.

Prop

Type

curl -X POST https://api.helipod.io/api/domains/42/renew \
  -H "Authorization: Bearer hel_your_key" \
  -H "Content-Type: application/json" \
  -d '{ "period": 1 }'
Response
{
  "success": true,
  "message": "Domain renewed for 1 year(s)",
  "data": { "expiresAt": "2028-10-16T00:00:00.000Z" },
  "billing": {
    "ppn": 20216,
    "renewal": 214000,
    "whoisProtection": 0,
    "total": 214000,
    "depositCharged": 214000
  }
}
  • The charge is the one-year renewal price, plus the whois_protection price when protection is enabled on the domain.
  • data.expiresAt is the new expiry date. It is never earlier than the previous one.
  • While the renewal runs, the domain's status is renewing; a second renewal of the same domain answers 409 RENEW_IN_PROGRESS and charges nothing.
  • 402 INSUFFICIENT_BALANCE when the balance is too low, 400 DOMAIN_NOT_LINKED when the domain is not active at the registry yet (nothing charged in either case).
  • If the registry refuses the renewal, you get 422 REGISTRAR_REJECTED; if it cannot be reached, 502 REGISTRAR_ERROR. The charge is refunded in both cases.
  • If the renewal went through but Helipod could not record it, the response is 200 with code: "DOMAIN_SAVE_PENDING" and a message asking you to contact support. Do not retry.

Auto-renew

Domains with autoRenew: true (see GET /domains/mine) are renewed automatically:

  • The check runs every day at 09:00 WIB.
  • A domain that expires within the next 7 days is renewed for 1 year.
  • The charge is the same as a manual renewal: the normal renewal price, plus the whois_protection price when protection is on, taken from your wallet.
  • If the wallet cannot cover it, the domain is not renewed and you get a notification in the dashboard. The next day's run tries again, every day until the domain is renewed or a few days past its expiry.
  • A domain is never renewed twice for the same period, even when you also renew it by hand.

Top up your wallet before the 7 day window to make sure your domains renew on time.

Pending profile domains

A free domain that comes with a purchase (for example a VPS bundle) is created with status pending_profile when your owner details are not complete yet. It is reserved for you but not registered at the registry.

  • It is listed by GET /domains/mine and readable with GET /domains/{id}. The list includes bonusDeadline: the date by which it must be activated.
  • Every other endpoint on that domain (renew, DNS, nameservers, WHOIS protection, child nameservers) returns 409:
409 Conflict
{
  "success": false,
  "error": "Domain ini belum aktif: lengkapi data pemilik domain untuk mengaktifkannya.",
  "code": "DOMAIN_PENDING_PROFILE"
}

To activate it, complete your owner details with PATCH /domains/registrant or in the Helipod dashboard before bonusDeadline. After the deadline the reservation is released and the domain disappears from your list.

On this page