Services API
Create, configure, build, deploy, roll back and inspect container services over the API.
Services are the containers you run. Everything the dashboard's service pages do is available here: create a service, push a new image, deploy it, watch the rollout, and roll back if it goes wrong.
All paths below are relative to:
https://api.smll.io/api/v1/workspaces/{workspaceID}/vpcs/{vpcID}/servicesEndpoints
| Method | Path | Role | Purpose |
|---|---|---|---|
GET | / | Member | List services in the VPC |
POST | / | Admin | Create a service |
GET | /{serviceID} | Member | Service detail, with live status |
PATCH | /{serviceID} | Admin | Update configuration |
DELETE | /{serviceID} | Admin | Delete the service |
POST | /{serviceID}/deploy | Admin | Deploy an image |
POST | /{serviceID}/restart | Admin | Restart without changing the image |
POST | /{serviceID}/rollback | Admin | Roll back to an earlier deployment |
GET | /{serviceID}/deployments | Member | Deployment history |
GET | /{serviceID}/logs | Member | Recent logs |
GET | /{serviceID}/logs/history | Member | Historical logs |
GET | /{serviceID}/env | Member | List environment variables |
PUT | /{serviceID}/env | Admin | Set environment variables |
DELETE | /{serviceID}/env/{envVarID} | Admin | Remove one variable |
GET | /{serviceID}/domains | Member | List custom domains |
POST | /{serviceID}/domains | Admin | Attach a custom domain |
POST | /{serviceID}/domains/{domainID}/verify | Admin | Re-check DNS and issue TLS |
DELETE | /{serviceID}/domains/{domainID} | Admin | Detach a domain |
GET | /{serviceID}/uptime | Member | Uptime monitor status |
POST | /{serviceID}/uptime | Admin | Enable uptime monitoring |
DELETE | /{serviceID}/uptime | Admin | Disable uptime monitoring |
Build and disk-backup endpoints are listed under Builds and Disk backups.
Create a service
curl -s -X POST -H "$AUTH" -H "Content-Type: application/json" \
-d '{
"name": "api",
"service_type": "web",
"instance_type": "smll.small",
"image": "registry.smll.io/vpc-4f2c413b/api:v1",
"port": 8080,
"health_check_path": "/healthz",
"min_replicas": 1,
"max_replicas": 3
}' \
"$BASE/workspaces/$WORKSPACE_ID/vpcs/$VPC_ID/services"| Field | Type | Default | Notes |
|---|---|---|---|
name | string | required | Unique in the VPC |
service_type | string | web | web, worker or cron |
instance_type | string | smll.nano | smll.nano through smll.xlarge |
deployment_mode | string | always_on | always_on, or on_demand to scale to zero |
image | string | Image reference to run | |
port | integer | 8080 for web | Port your process listens on |
health_check_path | string | HTTP path probed for readiness | |
min_replicas | integer | 1 | Lower bound, 0 with on_demand |
max_replicas | integer | Upper bound for autoscaling | |
cron_schedule | string | Required when service_type is cron | |
disk_size_gb | integer | Attach a persistent volume | |
disk_mount_path | string | Where to mount it | |
command | string[] | Override the image entrypoint | |
args | string[] | Override the image arguments | |
run_as_user | integer | 1000 | Container UID |
A cron service without cron_schedule is rejected with 400. A web service with no port defaults to 8080, which will fail its health check if your process listens elsewhere.
Creation fails with 503 if the platform cannot reach Kubernetes, and no record is written. There is no half-created service to clean up.
Deploy
Deploying means pointing the service at an image and rolling the pods:
curl -s -X POST -H "$AUTH" -H "Content-Type: application/json" \
-d '{"image_tag":"v1.4.2"}' \
"$BASE/workspaces/$WORKSPACE_ID/vpcs/$VPC_ID/services/$SERVICE_ID/deploy"image_tag takes either form:
- A bare tag (
v1.4.2), appended to the service's configured base image. - A full reference (
registry.smll.io/vpc-4f2c413b/api:v1.4.2), used as-is.
Use the full reference when the image lives somewhere other than the service's usual repository.
The call returns once the rollout has been requested, not once it is healthy. Poll the service detail endpoint and watch status to know when it has landed.
Roll back
Every deploy is recorded. List them, then roll back to one:
curl -s -H "$AUTH" \
"$BASE/workspaces/$WORKSPACE_ID/vpcs/$VPC_ID/services/$SERVICE_ID/deployments"
curl -s -X POST -H "$AUTH" -H "Content-Type: application/json" \
-d '{"deployment_id":"7c4a..."}' \
"$BASE/workspaces/$WORKSPACE_ID/vpcs/$VPC_ID/services/$SERVICE_ID/rollback"A rollback is itself a deployment, so it appears in the history too.
Environment variables
PUT /env sets variables in one call. It takes the full list you want applied:
curl -s -X PUT -H "$AUTH" -H "Content-Type: application/json" \
-d '{
"variables": [
{"key": "LOG_LEVEL", "value": "info"},
{"key": "DATABASE_URL", "secret_id": "9f21...", "secret_key": "url"}
]
}' \
"$BASE/workspaces/$WORKSPACE_ID/vpcs/$VPC_ID/services/$SERVICE_ID/env"Each entry is either a literal or a reference to a shared secret:
| Field | Purpose |
|---|---|
key | The variable name in the container |
value | A literal value |
secret_id | The secret to read from, instead of value |
secret_key | Which key inside that secret |
A secret reference means the value is never stored on the service, and updating the secret updates every service that links to it. Changing environment variables triggers a rollout so the new values take effect.
Builds
You can have SMLL build the image rather than pushing one yourself.
| Method | Path | Role | Purpose |
|---|---|---|---|
GET | /{serviceID}/builds | Member | List builds (accepts limit) |
POST | /{serviceID}/builds/git | Admin | Build from a public git repository |
POST | /{serviceID}/builds/source-upload | Admin | Build from an uploaded archive |
GET | /{serviceID}/builds/{buildID} | Member | Build status |
GET | /{serviceID}/builds/{buildID}/logs | Member | Build logs |
POST | /{serviceID}/builds/{buildID}/cancel | Admin | Cancel a running build |
Git builds clone without credentials, so they only work with public repositories. For private source, upload an archive with builds/source-upload (which is what smll deploy does), or build in your own CI and push the image to the VPC registry.
Disk backups
For services with a persistent volume:
| Method | Path | Role | Purpose |
|---|---|---|---|
GET | /{serviceID}/backups | Member | List disk backups |
POST | /{serviceID}/backups | Admin | Take a backup now |
POST | /{serviceID}/backups/restore | Admin | Restore a backup |
PUT | /{serviceID}/backups/schedule | Admin | Set a backup schedule |
DELETE | /{serviceID}/backups/schedule | Admin | Remove the schedule |
Restoring scales the service down, replaces the volume contents, and scales it back up. Expect downtime for the length of the restore.
Shell access
GET /{serviceID}/exec upgrades to a WebSocket and attaches a shell to a running pod. It authenticates by query parameter, not the Authorization header, because browsers cannot set headers on a WebSocket handshake.
In practice, use the CLI:
smll services exec my-app
# or
smll shell my-appStatus values
status on a service reflects reality in the cluster, resynced on each read:
| Status | Meaning |
|---|---|
creating | Being provisioned |
running | Healthy and serving |
deploying | A rollout is in progress |
restarting | Restarting on the same image |
scaled | Scaled to zero, either on-demand or by billing enforcement |
crashed | The container is failing or restart-looping |
deleting | Teardown in progress |
deleted | Soft-deleted, excluded from lists |
Because status is resynced against Kubernetes on every read, a service that died outside the platform still shows as crashed on the next GET.