Skip to content

REST API Reference

The Zerokie CLI is a thin wrapper around the REST API. You can call the API directly for automation, CI/CD integration, or building custom tooling.

https://api.platform-dev.zerokie.com

All requests require an Authorization header with your API key:

Authorization: Bearer YOUR_API_KEY
POST /v1/apps

Request body (container app):

{
"name": "my-app",
"type": "container",
"image": "nginx:alpine",
"port": 80,
"env": {
"NODE_ENV": "production"
},
"cpu": 256,
"memory": 512,
"registry_auth": {
"username": "deploy-token",
"password": "glpat-xxxx",
"server_address": "registry.gitlab.com"
}
}

Request body (static app):

{
"name": "my-site",
"type": "static"
}

The type field is optional and defaults to "container". When type is "static", the image, port, cpu, memory, and registry_auth fields are ignored. The registry_auth object is only needed for private registries. The app type is immutable after creation.

Response (201 Created):

{
"name": "my-app",
"image": "nginx:alpine",
"port": 80,
"status": "deploying",
"url": "https://my-app.platform-dev.zerokie.com"
}
GET /v1/apps

Response (200 OK):

[
{
"name": "my-app",
"image": "nginx:alpine",
"port": 80,
"status": "running",
"url": "https://my-app.platform-dev.zerokie.com"
}
]
GET /v1/apps/:name

Response (200 OK):

{
"name": "my-app",
"image": "nginx:alpine",
"port": 80,
"status": "running",
"url": "https://my-app.platform-dev.zerokie.com",
"instances": 1,
"cpu": 256,
"memory": 512,
"created_at": "2026-01-15T10:30:00Z",
"updated_at": "2026-01-15T10:30:00Z"
}
DELETE /v1/apps/:name

Response (204 No Content)

POST /v1/apps/:name/deploy

Request body (optional):

{
"image": "my-registry.com/my-app:v2",
"registry_auth": {
"username": "deploy-token",
"password": "glpat-xxxx",
"server_address": "registry.gitlab.com"
}
}
FieldTypeRequiredDescription
imagestringNoNew Docker image to deploy. If omitted, the app re-pulls and restarts with the current image tag.
registry_authobjectNoCredentials for pulling from a private registry.
registry_auth.usernamestringNoRegistry username or deploy token name.
registry_auth.passwordstringNoRegistry password or deploy token.
registry_auth.server_addressstringNoRegistry server address (e.g. registry.gitlab.com).

Response (200 OK):

{
"name": "my-app",
"image": "my-registry.com/my-app:v2",
"status": "deploying"
}

The following endpoints are specific to static apps.

GET /v1/apps/:name/files

Returns a flat JSON array of all files in the app’s storage zone.

Response (200 OK):

[
{"path": "index.html", "length": 1024, "lastModified": "2026-03-07T17:00:00Z"},
{"path": "assets/style.css", "length": 2048, "lastModified": "2026-03-07T17:00:00Z"}
]
PUT /v1/apps/:name/files/{path}

Upload a single file to the app’s storage zone. The request body is the raw file content. Set Content-Type based on the file extension.

Response (200 OK)

DELETE /v1/apps/:name/files/{path}

Delete a file from the app’s storage zone.

Response (204 No Content)

POST /v1/apps/:name/deploy/lock

Acquire a deploy lock to prevent concurrent deploys.

Request body:

{
"deploy_session_id": "550e8400-e29b-41d4-a716-446655440000"
}

Response (200 OK):

{
"locked": true,
"deploy_session_id": "550e8400-e29b-41d4-a716-446655440000"
}

Returns 409 Conflict if another deploy is already in progress.

PUT /v1/apps/:name/deploy/lock

Keep the deploy lock alive during long-running deploys. Send the current deploy_session_id in the request body. The CLI sends this every 3 minutes. Locks expire after 30 minutes without a heartbeat.

POST /v1/apps/:name/deploy/finalize

Finalize a deployment: purge the CDN cache, release the deploy lock, and record the deployment.

Request body:

{
"deploy_session_id": "550e8400-e29b-41d4-a716-446655440000",
"files_uploaded": 42,
"files_deleted": 3,
"total_bytes": 1048576
}

Response (200 OK):

{
"deploy_id": "d-20260307-170000",
"timestamp": "2026-03-07T17:00:00Z",
"cache_purged": true,
"summary": {
"files_uploaded": 42,
"files_deleted": 3,
"total_bytes": 1048576
}
}
POST /v1/apps/:name/domains

Add a custom domain to a static app. Apex domains are not supported.

Request body:

{
"domain": "www.example.com"
}

Response (201 Created):

{
"domain": "www.example.com",
"cname_target": "my-site.platform-dev.zerokie.com",
"tls_status": "pending"
}
DELETE /v1/apps/:name/domains/:domain

Remove a custom domain from a static app.

Response (204 No Content)

All errors follow a consistent format:

{
"error": "app not found"
}
Status CodeMeaning
400Invalid request (missing required fields, invalid values)
401Missing or invalid API key
404App not found
409App name already exists / deploy lock conflict
500Internal server error
502Upstream service error (e.g. CDN failure)

The API currently does not enforce rate limits. This may change in the future.