Services
List the services in an environment
curl https://api.koo.io/accounts/:accountId/projects/:projectId/environments/:environmentId/services \ -H "Authorization: Bearer kc_your_api_token"[ { "id": "svc_01example0000000000000000x", "name": "my-app", "type": "web", "cpu": 1, "memory": 1, "exposed": true, "source": { "type": "git", "git": { "provider": "github", "repoUrl": "https://example.com", "branch": "example", "autoDeploy": true }, "image": { "ref": "example" } }, "imagePullCredentialsSet": true, "runtime": { "port": 8080, "protocol": "http", "healthCheckPath": "example", "entrypoint": { "command": "example", "args": [ "example" ] } }, "serverless": { "enabled": true }, "cron": { "enabled": true, "schedule": "example" }, "volume": { "id": "svc_01example0000000000000000x", "mountPath": "example", "sizeGb": 0, "name": "my-app" }, "locations": [ { "name": "my-app", "replicas": 1 } ], "domains": [ { "hostname": "example", "mode": "cname", "status": "pending", "statusReason": "example", "dnsRecords": [ { "type": "TXT", "name": "my-app", "value": "example" } ] } ], "status": { "applied": "pending", "build": "pending", "health": "starting", "errors": [ { "source": "applied", "code": "dns_propagating", "resource": "example", "message": "example", "at": "2026-01-01T00:00:00.000Z" } ], "warnings": [ { "source": "applied", "code": "dns_propagating", "resource": "example", "message": "example", "at": "2026-01-01T00:00:00.000Z" } ], "url": "https://example.com", "lastDeployment": { "id": "svc_01example0000000000000000x", "version": 3 }, "appliedAt": "2026-01-01T00:00:00.000Z", "statusObservedAt": "2026-01-01T00:00:00.000Z" }, "internalHost": "example", "connection": { "key": "example" } }]Create a service in an environment
Creates the service. A deployable web service (git/image source) starts rolling out immediately — create is deploy.
Service name — lowercase letters, digits and dashes (3–16 chars, starts with a letter). The name is the service identity within the environment: renaming creates a new service.
Service kind: `web` runs your own code; `postgres`/`redis` are managed addons. Immutable per name.
CPU limit in millicores (250, 500, or whole-vCPU multiples of 1000).
Memory limit in MiB (256, 512, or whole-GiB multiples of 1024).
Expose the service publicly with its own URL (web services only).
Optional credential overrides for a managed database addon (postgres/redis), applied at create time. Ignored for web services.
Registry credentials for a private image source (requires an image source with a ref). Write-only — a read returns only `imagePullCredentialsSet`.
Variables to apply atomically with the service create (same shape as POST …/variables).
Where the deployable artifact comes from.
Runtime configuration (port, protocol, health check, entrypoint). Variables are managed separately via the /variables endpoints.
Run as a scale-to-zero serverless service (web only; mutually exclusive with cron/volume).
Run as a scheduled cron job (web only; mutually exclusive with serverless/volume).
Attach, create, or detach a persistent volume (web only; mutually exclusive with serverless/cron).
Locations this service runs in, each with its replica count.
The full desired set of custom hostnames routed to this exposed service. Omit to leave unchanged; send `[]` to remove all. Re-read the service to see each hostname’s DNS records + live status.
Unique identifier of the service (read-only).
Service name — lowercase letters, digits and dashes (3–16 chars, starts with a letter). The name is the service identity within the environment: renaming creates a new service.
Service kind: `web` runs your own code; `postgres`/`redis` are managed addons.
CPU limit in millicores (250, 500, or whole-vCPU multiples of 1000).
Memory limit in MiB (256, 512, or whole-GiB multiples of 1024).
Whether the service is publicly reachable with its own URL (web services only).
Where the deployable artifact comes from.
Read-only: true when private-image registry credentials are stored for this service. The credentials themselves are never returned.
Runtime configuration (port, protocol, health check, entrypoint). Variables are managed separately.
Present when the service runs in scale-to-zero serverless mode.
Present when the service runs as a scheduled cron job.
Present when the service has an attached persistent volume.
Locations this service runs in, each with its replica count.
Read-only: the custom domains routing to this service, with DNS records + live status.
Read-only: live status of the service.
Read-only: the internal DNS host other services reach this one at, for service-to-service wiring.
Read-only: non-secret connection details for a managed addon (postgres/redis).
curl https://api.koo.io/accounts/:accountId/projects/:projectId/environments/:environmentId/services \ -X POST \ -H "Authorization: Bearer kc_your_api_token" \ -H "Content-Type: application/json" \ -d '{ "name": "my-app", "type": "web", "cpu": 1, "memory": 1 }'{ "id": "svc_01example0000000000000000x", "name": "my-app", "type": "web", "cpu": 1, "memory": 1, "exposed": true, "source": { "type": "git", "git": { "provider": "github", "repoUrl": "https://example.com", "branch": "example", "autoDeploy": true }, "image": { "ref": "example" } }, "imagePullCredentialsSet": true, "runtime": { "port": 8080, "protocol": "http", "healthCheckPath": "example", "entrypoint": { "command": "example", "args": [ "example" ] } }, "serverless": { "enabled": true }, "cron": { "enabled": true, "schedule": "example" }, "volume": { "id": "svc_01example0000000000000000x", "mountPath": "example", "sizeGb": 0, "name": "my-app" }, "locations": [ { "name": "my-app", "replicas": 1 } ], "domains": [ { "hostname": "example", "mode": "cname", "status": "pending", "statusReason": "example", "dnsRecords": [ { "type": "TXT", "name": "my-app", "value": "example" } ] } ], "status": { "applied": "pending", "build": "pending", "health": "starting", "errors": [ { "source": "applied", "code": "dns_propagating", "resource": "example", "message": "example", "at": "2026-01-01T00:00:00.000Z" } ], "warnings": [ { "source": "applied", "code": "dns_propagating", "resource": "example", "message": "example", "at": "2026-01-01T00:00:00.000Z" } ], "url": "https://example.com", "lastDeployment": { "id": "svc_01example0000000000000000x", "version": 3 }, "appliedAt": "2026-01-01T00:00:00.000Z", "statusObservedAt": "2026-01-01T00:00:00.000Z" }, "internalHost": "example", "connection": { "key": "example" }}Get a service
Service name within the environment.
Unique identifier of the service (read-only).
Service name — lowercase letters, digits and dashes (3–16 chars, starts with a letter). The name is the service identity within the environment: renaming creates a new service.
Service kind: `web` runs your own code; `postgres`/`redis` are managed addons.
CPU limit in millicores (250, 500, or whole-vCPU multiples of 1000).
Memory limit in MiB (256, 512, or whole-GiB multiples of 1024).
Whether the service is publicly reachable with its own URL (web services only).
Where the deployable artifact comes from.
Read-only: true when private-image registry credentials are stored for this service. The credentials themselves are never returned.
Runtime configuration (port, protocol, health check, entrypoint). Variables are managed separately.
Present when the service runs in scale-to-zero serverless mode.
Present when the service runs as a scheduled cron job.
Present when the service has an attached persistent volume.
Locations this service runs in, each with its replica count.
Read-only: the custom domains routing to this service, with DNS records + live status.
Read-only: live status of the service.
Read-only: the internal DNS host other services reach this one at, for service-to-service wiring.
Read-only: non-secret connection details for a managed addon (postgres/redis).
curl https://api.koo.io/accounts/:accountId/projects/:projectId/environments/:environmentId/services/:name \ -H "Authorization: Bearer kc_your_api_token"{ "id": "svc_01example0000000000000000x", "name": "my-app", "type": "web", "cpu": 1, "memory": 1, "exposed": true, "source": { "type": "git", "git": { "provider": "github", "repoUrl": "https://example.com", "branch": "example", "autoDeploy": true }, "image": { "ref": "example" } }, "imagePullCredentialsSet": true, "runtime": { "port": 8080, "protocol": "http", "healthCheckPath": "example", "entrypoint": { "command": "example", "args": [ "example" ] } }, "serverless": { "enabled": true }, "cron": { "enabled": true, "schedule": "example" }, "volume": { "id": "svc_01example0000000000000000x", "mountPath": "example", "sizeGb": 0, "name": "my-app" }, "locations": [ { "name": "my-app", "replicas": 1 } ], "domains": [ { "hostname": "example", "mode": "cname", "status": "pending", "statusReason": "example", "dnsRecords": [ { "type": "TXT", "name": "my-app", "value": "example" } ] } ], "status": { "applied": "pending", "build": "pending", "health": "starting", "errors": [ { "source": "applied", "code": "dns_propagating", "resource": "example", "message": "example", "at": "2026-01-01T00:00:00.000Z" } ], "warnings": [ { "source": "applied", "code": "dns_propagating", "resource": "example", "message": "example", "at": "2026-01-01T00:00:00.000Z" } ], "url": "https://example.com", "lastDeployment": { "id": "svc_01example0000000000000000x", "version": 3 }, "appliedAt": "2026-01-01T00:00:00.000Z", "statusObservedAt": "2026-01-01T00:00:00.000Z" }, "internalHost": "example", "connection": { "key": "example" }}Update a service spec
A deployable source change rolls out automatically.
Service name within the environment.
CPU limit in millicores (250, 500, or whole-vCPU multiples of 1000).
Memory limit in MiB (256, 512, or whole-GiB multiples of 1024).
Expose the service publicly with its own URL (web services only).
Acknowledge a change that loses access to persistent-volume data: moving a volume service to a different location (destroys the disk), or attaching an existing volume to a service running in a different location than the disk (mounts a new, empty disk — the data stays with the disk). Required for those specific changes.
Acknowledge that unexposing this service degrades an active published app that points at it (the listing loses its Visit URL). Required for that specific change.
Credentials for pulling a private container image (write-only).
Where the deployable artifact comes from.
Runtime configuration (port, protocol, health check, entrypoint). Variables are managed separately via the /variables endpoints.
Run as a scale-to-zero serverless service (web only; mutually exclusive with cron/volume).
Run as a scheduled cron job (web only; mutually exclusive with serverless/volume).
Attach, create, or detach a persistent volume (web only; mutually exclusive with serverless/cron).
Locations this service runs in, each with its replica count.
The full desired set of custom hostnames routed to this exposed service. Omit to leave unchanged; send `[]` to remove all. Re-read the service to see each hostname’s DNS records + live status.
Unique identifier of the service (read-only).
Service name — lowercase letters, digits and dashes (3–16 chars, starts with a letter). The name is the service identity within the environment: renaming creates a new service.
Service kind: `web` runs your own code; `postgres`/`redis` are managed addons.
CPU limit in millicores (250, 500, or whole-vCPU multiples of 1000).
Memory limit in MiB (256, 512, or whole-GiB multiples of 1024).
Whether the service is publicly reachable with its own URL (web services only).
Where the deployable artifact comes from.
Read-only: true when private-image registry credentials are stored for this service. The credentials themselves are never returned.
Runtime configuration (port, protocol, health check, entrypoint). Variables are managed separately.
Present when the service runs in scale-to-zero serverless mode.
Present when the service runs as a scheduled cron job.
Present when the service has an attached persistent volume.
Locations this service runs in, each with its replica count.
Read-only: the custom domains routing to this service, with DNS records + live status.
Read-only: live status of the service.
Read-only: the internal DNS host other services reach this one at, for service-to-service wiring.
Read-only: non-secret connection details for a managed addon (postgres/redis).
curl https://api.koo.io/accounts/:accountId/projects/:projectId/environments/:environmentId/services/:name \ -X PATCH \ -H "Authorization: Bearer kc_your_api_token" \ -H "Content-Type: application/json" \ -d '{}'{ "id": "svc_01example0000000000000000x", "name": "my-app", "type": "web", "cpu": 1, "memory": 1, "exposed": true, "source": { "type": "git", "git": { "provider": "github", "repoUrl": "https://example.com", "branch": "example", "autoDeploy": true }, "image": { "ref": "example" } }, "imagePullCredentialsSet": true, "runtime": { "port": 8080, "protocol": "http", "healthCheckPath": "example", "entrypoint": { "command": "example", "args": [ "example" ] } }, "serverless": { "enabled": true }, "cron": { "enabled": true, "schedule": "example" }, "volume": { "id": "svc_01example0000000000000000x", "mountPath": "example", "sizeGb": 0, "name": "my-app" }, "locations": [ { "name": "my-app", "replicas": 1 } ], "domains": [ { "hostname": "example", "mode": "cname", "status": "pending", "statusReason": "example", "dnsRecords": [ { "type": "TXT", "name": "my-app", "value": "example" } ] } ], "status": { "applied": "pending", "build": "pending", "health": "starting", "errors": [ { "source": "applied", "code": "dns_propagating", "resource": "example", "message": "example", "at": "2026-01-01T00:00:00.000Z" } ], "warnings": [ { "source": "applied", "code": "dns_propagating", "resource": "example", "message": "example", "at": "2026-01-01T00:00:00.000Z" } ], "url": "https://example.com", "lastDeployment": { "id": "svc_01example0000000000000000x", "version": 3 }, "appliedAt": "2026-01-01T00:00:00.000Z", "statusObservedAt": "2026-01-01T00:00:00.000Z" }, "internalHost": "example", "connection": { "key": "example" }}Delete a service
Deleting a service that backs an active published app degrades its listing; pass confirmAppImpact to proceed (412 otherwise).
Service name within the environment.
Must be true to proceed when this service backs an active published app: deleting it leaves the listing degraded.
curl https://api.koo.io/accounts/:accountId/projects/:projectId/environments/:environmentId/services/:name \ -X DELETE \ -H "Authorization: Bearer kc_your_api_token" \ -H "Content-Type: application/json" \ -d '{}'Reveal a managed service’s connection details (incl. password)
The host/port/user/db + the connection URL and password for a postgres/redis service. Editor+ and audited; web services have no connection details (422).
Service name within the environment.
curl https://api.koo.io/accounts/:accountId/projects/:projectId/environments/:environmentId/services/:name/connection \ -H "Authorization: Bearer kc_your_api_token"{ "key": "example"}Get the data to open an interactive shell into a running replica
Returns everything the browser needs to open an interactive shell DIRECTLY against the replica’s terminal WebSocket — there is no Koo-side proxy: the per-location endpoint, the opaque connection coordinates the client passes through in the handshake, container choices, and a connect-only per-environment token (minted lazily; rotated on membership changes). List replicas via exec-replicas. Editor+ and audited; not available to OAuth authorizations.
Service name within the environment.
The location whose replicas the shell targets.
Container names in the service (the shell target choices).
The per-location terminal endpoint (https://…) — the browser opens the shell WebSocket at wss://{host}/remote.
Opaque account-level connection coordinate — pass it through verbatim in the terminal handshake.
Opaque environment-level connection coordinate — pass it through verbatim in the terminal handshake.
Opaque service-level connection coordinate — pass it through verbatim in the terminal handshake.
A connect-only credential scoped to this environment — sent inside the binary exec-WebSocket handshake (never in the URL). Minted lazily per environment; revoked and re-minted when a member is removed or downgraded below editor.
curl https://api.koo.io/accounts/:accountId/projects/:projectId/environments/:environmentId/services/:name/exec-connection \ -H "Authorization: Bearer kc_your_api_token"{ "location": "example", "containers": [ "example" ], "remote": "example", "org": "example", "gvc": "example", "workload": "example", "token": "example"}List running replicas for an interactive shell
Lists running replicas, resolved server-side from live hosting state. Editor+.
Service name within the environment.
Running replica (pod) names available to open a shell into.
curl https://api.koo.io/accounts/:accountId/projects/:projectId/environments/:environmentId/services/:name/exec-replicas \ -H "Authorization: Bearer kc_your_api_token"{ "items": [ "example" ]}