Deployments
Create, update, promote, cancel, and stream logs for deployments.
A deployment is one version of an app running on the platform. It holds a spec (replicas, resources, image or artifact, env vars) and a status.
Status lifecycle: pending → running → succeeded | failed | cancelled
POST /api/v1/apps//deployments — Create
Creates a new deployment for the app. If artifact_id or a Docker image is provided, the scheduler is notified immediately. Without either, the deployment waits for a build to complete.
Body
- environment (string):
"development"(default) or"production"or any custom slug - process_type (string):
"tish"(native binary) or"docker". Default"tish" - artifact_id (UUID, optional): Required for
tishapps — reference to a compiled binary in the registry - image (string, optional): Required for
dockerapps — e.g."nginx:latest" - replicas (number): Default
1 - resources (object):
{ "cpu": "100m", "memory": "128Mi" }— defaults shown - networking (object):
- port (number, optional): Leave
nullto have the platform assign a port - protocol (string):
"http"(default) - health_path (string): e.g.
"/health"
- port (number, optional): Leave
- env (object): Additional env vars merged on top of app-level vars
- cold_start_enabled (boolean): Enable scale-to-zero. Default
true - idle_timeout_secs (number): Seconds before an idle task is stopped. Default
300 - max_runtime_secs (number, optional): Kill task after this many seconds
- volumes (array):
[{ "host_path": "/data", "container_path": "/app/data" }]
Deploy a Docker container
curl -X POST http://localhost:47080/api/v1/apps/$APP_ID/deployments \
-H 'Content-Type: application/json' \
-d '{
"process_type": "docker",
"image": "ghcr.io/myorg/my-api:latest",
"replicas": 2,
"environment": "production",
"resources": {"cpu":"250m","memory":"256Mi"},
"networking": {"port":8080,"health_path":"/health"},
"env": {"LOG_LEVEL":"info"}
}'Deploy a tish binary
curl -X POST http://localhost:47080/api/v1/apps/$APP_ID/deployments \
-H 'Content-Type: application/json' \
-d "{
\"artifact_id\": \"$ARTIFACT_ID\",
\"process_type\": \"tish\",
\"replicas\": 1,
\"environment\": \"development\",
\"networking\": {\"port\": 8080}
}"Response 201 Created
{
"id": "uuid",
"sha": "a1b2c3d4",
"app_id": "uuid",
"version": 3,
"status": "pending",
"spec": { ... },
"tasks_ready": 0,
"tasks_total": 2,
"progress": 0,
"environment_slug": "production",
"preview_url": "https://my-api-a1b2c3d4-production.example.com",
"created_at": "...",
"updated_at": "..."
}GET /api/v1/deployments/ — Status
Includes live tasks_ready, tasks_total, and progress (0–100).
# Poll until running
while true; do
D=$(curl -sf http://localhost:47080/api/v1/deployments/$DEPLOY_ID)
echo "$(echo $D | jq -r .status) — $(echo $D | jq -r .tasks_ready)/$(echo $D | jq -r .tasks_total) ready"
[ "$(echo $D | jq -r .status)" != "pending" ] && break
sleep 3
doneGET /api/v1/apps//deployments — List for app
Cursor-based pagination. Pass page_token (a version number) for subsequent pages.
Query params — page_size (default 20, max 100), page_token
{ "deployments": [ { ...deployment } ], "next_page_token": "42" }GET /api/v1/deployments — List all
Supports app_id, page, page_size, sort_by, sort_order query params.
curl "http://localhost:47080/api/v1/deployments?app_id=$APP_ID&sort_order=desc"PATCH /api/v1/deployments/ — Scale / update spec
Updates the spec in place and tells the scheduler to reconcile. No new deployment object is created.
Body — spec with any of: replicas, resources, image, process_type, volumes
# Scale to 3
curl -X PATCH http://localhost:47080/api/v1/deployments/$DEPLOY_ID \
-H 'Content-Type: application/json' \
-d '{"spec":{"replicas":3}}'
# Scale to zero (traffic wakes it via cold start)
curl -X PATCH http://localhost:47080/api/v1/deployments/$DEPLOY_ID \
-H 'Content-Type: application/json' \
-d '{"spec":{"replicas":0}}'POST /api/v1/apps//deploy/trigger 🔒
Trigger a build-and-deploy from the app's configured Git source. Requires source config to be set. Polls the build service internally (up to 5 minutes) and creates the deployment when the build succeeds.
Body
- branch (string, optional): Override the configured branch
- ref (string, optional): Deploy a specific commit SHA
- skip_build (boolean): Default
false - environment (string): Default
"development"
curl -X POST http://localhost:47080/api/v1/apps/$APP_ID/deploy/trigger \
-H "Authorization: Bearer $TOKEN" \
-H 'Content-Type: application/json' \
-d '{"branch":"main","environment":"development"}'// 201 Created
{ "deployment_id": "uuid", "status": "pending", "message": "Deployment created and scheduler notified" }Only
"github"source type is supported today. GitLab returns501.
POST /api/v1/deployments//promote — Promote
Creates a new deployment in the target environment using the same artifact or image. The source deployment is not modified. Target environment's env vars are applied to the new deployment.
Body
- strategy (string):
"instant"(reuse artifact/image) or"rebuild"(new build from same source) - environment (string): Default
"production"
# Get the latest development deployment
DEV_ID=$(curl -sf "http://localhost:47080/api/v1/apps/$APP_ID/deployments?page_size=1" \
| jq -r '.deployments[0].id')
curl -X POST http://localhost:47080/api/v1/deployments/$DEV_ID/promote \
-H 'Content-Type: application/json' \
-d '{"strategy":"instant","environment":"production"}'// 201 Created
{ "deployment_id": "uuid", "message": "Deployment created and scheduler notified" }Poll the returned deployment_id to track the new deployment's status.
POST /api/v1/deployments//cancel
Cancels a pending or running deployment. Returns the updated deployment object.
Logs
GET /api/v1/deployments//logs
Fetch stored log entries for all tasks in the deployment.
curl http://localhost:47080/api/v1/deployments/$DEPLOY_ID/logs | jq '.[] | .message'GET /api/v1/deployments//logs/stream
Live log stream as Server-Sent Events. Connect with Accept: text/event-stream.
curl -N -H 'Accept: text/event-stream' \
http://localhost:47080/api/v1/deployments/$DEPLOY_ID/logs/streamIn JavaScript:
const evtSource = new EventSource(
`http://localhost:47080/api/v1/deployments/${deploymentId}/logs/stream`
);
evtSource.onmessage = (e) => {
const entry = JSON.parse(e.data);
console.log(`[${entry.timestamp}] ${entry.message}`);
};GET /api/v1/deployments//tasks
List the task instances (replicas) for this deployment. See Tasks.
Webhooks
POST /api/v1/webhooks/github
GitHub sends push and pull-request events here. The platform verifies X-Hub-Signature-256 against the webhook secret in source config, then triggers a deploy on matching push events.
See also
- Builds & artifacts — build from source or upload binaries manually
- Tasks — inspect and stop individual running replicas
- Applications — source config, env vars, custom domains