Services
Create services from an image, a Git repository or a Dockerfile, and manage their settings.
The service object
{
"id": "9a8b7c6d-5e4f-4a3b-9c2d-1e0f9a8b7c6d",
"name": "api",
"description": null,
"projectId": "3b0cd5ac-ac26-4012-9b28-17466f73788c",
"environmentId": "e1d4a0f2-6c11-4a9e-8a0e-5f2b7d1c9a33",
"status": "running",
"source": { "kind": "git", "repo": "https://github.com/acme/api", "branch": "main", "rootDirectory": "apps/api" },
"startCommand": null,
"healthcheck": { "path": "/health", "timeout": 300 },
"dependsOn": ["5d4c3b2a-1f0e-4d9c-8b7a-6f5e4d3c2b1a"],
"resources": { "cpu": 250, "ram": 512, "replicas": 1, "storageMb": 1024 },
"domains": [
{ "id": "…", "kind": "helipod", "domain": "api.helipod.app", "port": 3000, "protocol": "http", "status": "active", "url": "https://api.helipod.app" }
],
"latestDeployment": { "id": "…", "status": "success", "createdAt": "2026-10-16T09:12:03.000Z" },
"dailyCost": 1100,
"createdAt": "2026-10-01T02:00:00.000Z"
}Prop
Type
List services
/containers/environments/{environmentId}/servicescurl https://api.helipod.io/api/containers/environments/$ENV/services \
-H "Authorization: Bearer hel_your_key"Create a service
/containers/environments/{environmentId}/servicescharges your walletdryRunIdempotency-KeyCreates the service and, unless deploy is false, starts its first deploy.
Prop
Type
Sources
A public image from Docker Hub, GitHub Container Registry or any registry:
{ "name": "web", "source": { "image": "nginx:alpine" }, "ports": [{ "port": 80 }] }A private image: add the registry credentials. They are stored with the service, used only to pull the image, and never returned by the API.
{
"name": "app",
"source": { "image": "ghcr.io/acme/app:1.4.2", "registryUsername": "acme-bot", "registryPassword": "ghp_xxx" },
"ports": [{ "port": 8080 }]
}Image services skip the build step, so they deploy fastest.
Example
curl -X POST https://api.helipod.io/api/containers/environments/$ENV/services \
-H "Authorization: Bearer hel_your_key" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: create-api-001" \
-d '{
"name": "api",
"source": { "image": "ghcr.io/acme/api:2.0.0" },
"ports": [{ "port": 3000 }],
"variables": { "NODE_ENV": "production", "DATABASE_URL": "${{Postgres.DATABASE_URL}}", "SESSION_SECRET": "${{secret(48)}}" },
"volumes": [{ "mountPath": "/app/uploads", "sizeGb": 5 }],
"cpu": 250,
"ram": 512
}'The response (201) is { "service": { ... }, "deploymentId": "..." }. deploymentId is null when deploy is false. If the service was created but its deploy could not be queued, the response also has deployError; deploy it again with POST /deployments.
Images from Helipod's own registry
Images built by Helipod live in a private registry that only the platform can use. Referencing them as a source is refused; deploy the original repository instead.
Get a service
/containers/services/{serviceId}Update settings
/containers/services/{serviceId}Prop
Type
curl -X PATCH https://api.helipod.io/api/containers/services/$SERVICE \
-H "Authorization: Bearer hel_your_key" -H "Content-Type: application/json" \
-d '{ "healthcheck": { "path": "/health", "timeout": 120 }, "dependsOn": ["5d4c3b2a-1f0e-4d9c-8b7a-6f5e4d3c2b1a"] }'The response is { "service": { ... }, "needsRedeploy": true, "warnings": [] }. needsRedeploy is true when a setting changed; a rename alone does not need a deploy. Send at least one field (400 NOTHING_TO_UPDATE otherwise).
Renaming
Other services find this one by name in references such as ${{api.API_URL}}, so a rename does not update them for you. The response lists every variable that still points at the old name:
curl -X PATCH https://api.helipod.io/api/containers/services/$SERVICE \
-H "Authorization: Bearer hel_your_key" -H "Content-Type: application/json" \
-d '{ "name": "backend" }'{
"success": true,
"data": {
"service": { "id": "9a8b7c6d-5e4f-4a3b-9c2d-1e0f9a8b7c6d", "name": "backend", "...": "..." },
"needsRedeploy": false,
"warnings": [
"Service \"web\" variable API_URL references ${{api.…}}: update it to ${{backend.…}} or its next deploy will fail."
]
}
}Fix each one with PUT /variables, or in the project's shared variables. A name another service in the environment already has answers 409 SERVICE_NAME_TAKEN.
Delete a service
/containers/services/{serviceId}Returns 202 with { "id": "...", "status": "deleting" }. Data on its volumes is deleted and cannot be recovered.