Requests and errors
The response envelope, status codes, rate limits, dry runs and idempotency, shared by every Helipod API.
Response envelope
Every response is JSON with the same shape.
{
"success": true,
"data": { "id": "6f1c0b8e-2d1f-4f7a-9a51-2b7f0c1d9e40", "name": "web" }
}Use the HTTP status and code in your code. The error text is written for people and may change; some messages are in Indonesian.
Status codes
| Status | Meaning |
|---|---|
200 | OK |
201 | Created |
202 | Accepted: the work continues in the background (a deploy, a restart, a deletion) |
400 | The request is invalid for a business reason, the message says why |
401 | Missing, unknown, revoked or expired API key (NO_API_KEY, INVALID_API_KEY, API_KEY_EXPIRED) |
402 | Your plan does not allow it (for example the service limit is reached) |
403 | The key was not given this product (SCOPE_NOT_ALLOWED) or the API needs a whole-account key (ACCOUNT_KEY_REQUIRED) |
404 | Not found, or not reachable with this key |
409 | Conflict, for example a deploy is already running or a request with the same Idempotency-Key is still running |
422 | The request body or query does not match the schema (VALIDATION_ERROR) |
429 | Too many requests (RATE_LIMITED), see below |
500 | Something went wrong on our side. Retry later; the message never contains internal details |
Rate limits
Each API key may send 10 requests per second to https://api.helipod.io. Every response carries:
X-RateLimit-Limit: the limit per secondX-RateLimit-Remaining: requests left in the current window
Over the limit, you get 429 with code: "RATE_LIMITED" and a Retry-After header in seconds. Wait that long, then retry.
Dry runs
Calls that cost money accept ?dryRun=true in the Container, Database, Domain and AI APIs and for email plan purchases. Nothing is created, changed or charged; the response shows the price instead:
curl -X POST "https://api.helipod.io/api/containers/services/SERVICE_ID/deployments?dryRun=true" \
-H "Authorization: Bearer hel_your_key"{
"success": true,
"data": { "dryRun": true, "currency": "IDR", "dailyCost": 4950, "note": "..." }
}Domain, email plan, database and AI dry runs also return your wallet balance after the charge and enoughBalance. The VPS API has no dry run: check plans and renewal options before a paid call.
Idempotency
Calls that create something or start paid work accept an Idempotency-Key header (8 to 128 characters: letters, digits, _ . : -) in the Container and Database APIs, and require it for email plan purchases and AI top-ups made with a key. Send a fresh unique value per logical operation, and the same value when you retry it:
curl -X POST https://api.helipod.io/api/containers/services/SERVICE_ID/deployments \
-H "Authorization: Bearer hel_your_key" \
-H "Idempotency-Key: deploy-2026-10-16-a1b2c3"- A retry with the same key within 24 hours returns the first response instead of doing the work again.
- While the first request is still running, a retry gets
409 REQUEST_IN_PROGRESS. - If the first request failed, the key is released and the retry runs normally.
Endpoints that support it are marked Idempotency-Key in the reference. The VPS and Domain APIs do not read it: look the resource up before retrying a create or a purchase.
Ids and pagination
Ids are UUIDs, except domain ids, which are numbers. List endpoints return the whole list unless the reference says otherwise; the few paginated lists document their limit / page parameters.