Skip to content

Deployments

View as Markdown

Immutable deployments of a service into an environment. Rollback re-promotes an earlier image as a new deployment.

Operation Method and path
Upload a source tarball (guv up) POST /v1/projects/{project}/uploads
Deployment timeline for a project GET /v1/projects/{project}/deployments
List deployments of a service in an environment GET /v1/projects/{project}/environments/{environment}/services/{service}/deployments
Deploy POST /v1/projects/{project}/environments/{environment}/services/{service}/deployments
Get a deployment GET /v1/deployments/{deployment_id}
Roll back to this deployment POST /v1/deployments/{deployment_id}/rollback
Cancel a deployment that has not gone live POST /v1/deployments/{deployment_id}/cancel
Build and deploy logs of a deployment GET /v1/deployments/{deployment_id}/logs
Why a deployment failed and how to fix it GET /v1/deployments/{deployment_id}/explanation
POST /v1/projects/{project}/uploads

Body is a gzip-compressed tar of the working directory (max 500 MB, .gitignore respected by the CLI). Use the returned id as source.upload_id when creating a deployment.

  • Operation: uploadSource
  • Scopes: projects:write
  • Idempotency-Key: required

Parameters

Name In Type Description
project * path string Project id (prj_…) or slug (resolved in the Guv-Workspace workspace, or the caller’s default).

Request body (application/gzip, required): string

Responses

Status Meaning Body
201 Created Created. SourceUpload

Errors: 400, 401, 403, 404, 409, 413, 422, 429, 500, as problem+json with a stable code.

Example

Terminal window
curl -X POST https://api.guv.dev/v1/projects/shopfront/uploads \
-H "Authorization: Bearer $GUV_TOKEN" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '"string"'

Example response

{
"id": "upl_01jbx2m9k7q4r8t5v6w3y0z1pr",
"size_bytes": 1,
"sha256": "string",
"expires_at": "2026-10-22T13:05:00Z"
}
GET /v1/projects/{project}/deployments
  • Operation: listProjectDeployments
  • Scopes: projects:read
  • Paginated: ?limit= and ?cursor=

Parameters

Name In Type Description
project * path string Project id (prj_…) or slug (resolved in the Guv-Workspace workspace, or the caller’s default).
environment query string
service query string
status query DeploymentStatus
actor_type query user, agent, system, ai_ops, github

Responses

Status Meaning Body
200 OK A page of Deployment objects. DeploymentList

Errors: 400, 401, 403, 404, 429, 500, as problem+json with a stable code.

Example

Terminal window
curl https://api.guv.dev/v1/projects/shopfront/deployments \
-H "Authorization: Bearer $GUV_TOKEN"

Example response

{
"data": [
{
"id": "dep_01jbx2m9k7q4r8t5v6w3y0z1dp",
"project_id": "prj_01jbx2m9k7q4r8t5v6w3y0z1pr",
"environment_id": "env_01jbx2m9k7q4r8t5v6w3y0z1en",
"service_id": "svc_01jbx2m9k7q4r8t5v6w3y0z1sv",
"service_name": "web",
"environment_name": "production",
"status": "active",
"status_text": "Live since 14:05",
"trigger": {
"kind": "git_push",
"actor": {
"type": "github",
"id": "stewartwebb",
"display": "stewartwebb pushed to main"
}
},
"source": {
"kind": "git",
"commit": {
"sha": "a1b2c3d4e5f60718293a4b5c6d7e8f9012345678",
"branch": "main",
"message": "Fix rota export",
"author": "Stewart Webb"
}
},
"build_id": "bld_01jbx2m9k7q4r8t5v6w3y0z1bd",
"image": {
"digest": "sha256:4b1f0e9d8c7b6a5948372615f4e3d2c1b0a9f8e7d6c5b4a3928170f6e5d4c3b2",
"signed": true
},
"rollback_of": null,
"operation_id": "op_01jbx2m9k7q4r8t5v6w3y0z1op",
"url": "https://www.primecarers.co.uk",
"failure": null,
"created_at": "2026-10-23T14:02:00Z",
"started_at": "2026-10-23T14:02:01Z",
"active_at": "2026-10-23T14:05:12Z",
"finished_at": "2026-10-23T14:05:12Z",
"duration_ms": 191000
}
],
"next_cursor": "string",
"has_more": false
}

List deployments of a service in an environment

Section titled “List deployments of a service in an environment”
GET /v1/projects/{project}/environments/{environment}/services/{service}/deployments
  • Operation: listDeployments
  • Scopes: projects:read
  • Paginated: ?limit= and ?cursor=

Parameters

Name In Type Description
project * path string Project id (prj_…) or slug (resolved in the Guv-Workspace workspace, or the caller’s default).
environment * path string Environment id (env_…) or name.
service * path string Service id (svc_…) or name.
status query DeploymentStatus

Responses

Status Meaning Body
200 OK A page of Deployment objects. DeploymentList

Errors: 400, 401, 403, 404, 429, 500, as problem+json with a stable code.

Example

Terminal window
curl https://api.guv.dev/v1/projects/shopfront/environments/production/services/web/deployments \
-H "Authorization: Bearer $GUV_TOKEN"

Example response

{
"data": [
{
"id": "dep_01jbx2m9k7q4r8t5v6w3y0z1dp",
"project_id": "prj_01jbx2m9k7q4r8t5v6w3y0z1pr",
"environment_id": "env_01jbx2m9k7q4r8t5v6w3y0z1en",
"service_id": "svc_01jbx2m9k7q4r8t5v6w3y0z1sv",
"service_name": "web",
"environment_name": "production",
"status": "active",
"status_text": "Live since 14:05",
"trigger": {
"kind": "git_push",
"actor": {
"type": "github",
"id": "stewartwebb",
"display": "stewartwebb pushed to main"
}
},
"source": {
"kind": "git",
"commit": {
"sha": "a1b2c3d4e5f60718293a4b5c6d7e8f9012345678",
"branch": "main",
"message": "Fix rota export",
"author": "Stewart Webb"
}
},
"build_id": "bld_01jbx2m9k7q4r8t5v6w3y0z1bd",
"image": {
"digest": "sha256:4b1f0e9d8c7b6a5948372615f4e3d2c1b0a9f8e7d6c5b4a3928170f6e5d4c3b2",
"signed": true
},
"rollback_of": null,
"operation_id": "op_01jbx2m9k7q4r8t5v6w3y0z1op",
"url": "https://www.primecarers.co.uk",
"failure": null,
"created_at": "2026-10-23T14:02:00Z",
"started_at": "2026-10-23T14:02:01Z",
"active_at": "2026-10-23T14:05:12Z",
"finished_at": "2026-10-23T14:05:12Z",
"duration_ms": 191000
}
],
"next_cursor": "string",
"has_more": false
}
POST /v1/projects/{project}/environments/{environment}/services/{service}/deployments

Builds (unless deploying an image or redeploying) and rolls out a new immutable deployment. Returns an operation whose resource is the new deployment. Fails early with secret_missing if a referenced secret is not set.

  • Operation: createDeployment
  • Scopes: deploy:{environment}
  • CLI: guv deploy
  • Approval: In environments with protection turned on (usually production), changes by agents and by roles outside approver_roles return approval_required.
  • Idempotency-Key: required; supports ?dry_run=true

Parameters

Name In Type Description
project * path string Project id (prj_…) or slug (resolved in the Guv-Workspace workspace, or the caller’s default).
environment * path string Environment id (env_…) or name.
service * path string Service id (svc_…) or name.

Request body (application/json): DeploymentCreate

Field Type Description
source object
redeploy_of string Rebuild-free redeploy of an existing deployment’s image with current settings and secrets.
message string
clear_build_cache boolean Default false.

Responses

Status Meaning Body
200 OK Dry run. Nothing was changed; this is what would happen. Plan
202 Accepted Accepted. The work continues in the background; follow the operation. Operation

Errors: 400, 401, 402, 403, 404, 409, 422, 429, 500, as problem+json with a stable code.

Example

Terminal window
curl -X POST https://api.guv.dev/v1/projects/shopfront/environments/production/services/web/deployments \
-H "Authorization: Bearer $GUV_TOKEN" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{
"source": {
"kind": "git",
"ref": "main",
"image": "string",
"upload_id": "string"
},
"redeploy_of": "string",
"message": "string",
"clear_build_cache": false
}'

Example response

{
"id": "op_01jbx2m9k7q4r8t5v6w3y0z1op",
"kind": "deployment.create",
"status": "running",
"summary": "Deploying web to production",
"workspace_id": "ws_01jbx2m9k7q4r8t5v6w3y0z1ws",
"project_id": "prj_01jbx2m9k7q4r8t5v6w3y0z1pr",
"environment_id": "env_01jbx2m9k7q4r8t5v6w3y0z1en",
"resource": {
"type": "deployment",
"id": "dep_01jbx2m9k7q4r8t5v6w3y0z1dp",
"url": "/v1/deployments/dep_01jbx2m9k7q4r8t5v6w3y0z1dp"
},
"progress": {
"current_step": "build",
"completed_steps": 1,
"total_steps": 6,
"percent": 20
},
"steps": [
{
"name": "resolve",
"title": "Reading your settings",
"status": "succeeded",
"attempt": 1,
"started_at": "2026-10-23T14:02:00Z",
"finished_at": "2026-10-23T14:02:01Z"
},
{
"name": "build",
"title": "Building your app",
"status": "running",
"attempt": 1,
"started_at": "2026-10-23T14:02:01Z",
"finished_at": null
}
],
"created_by": {
"type": "user",
"id": "usr_01jbx2m9k7q4r8t5v6w3y0z1us",
"display": "Stewart Webb"
},
"created_at": "2026-10-23T14:02:00Z",
"links": {
"self": "/v1/operations/op_01jbx2m9k7q4r8t5v6w3y0z1op",
"events": "/v1/operations/op_01jbx2m9k7q4r8t5v6w3y0z1op/events",
"resource": "/v1/deployments/dep_01jbx2m9k7q4r8t5v6w3y0z1dp"
}
}
GET /v1/deployments/{deployment_id}
  • Operation: getDeployment
  • Scopes: projects:read

Parameters

Name In Type Description
deployment_id * path string

Responses

Status Meaning Body
200 OK OK. Deployment

Errors: 400, 401, 403, 404, 429, 500, as problem+json with a stable code.

Example

Terminal window
curl https://api.guv.dev/v1/deployments/dep_01jbx2m9k7q4r8t5v6w3y0z1pr \
-H "Authorization: Bearer $GUV_TOKEN"

Example response

{
"id": "dep_01jbx2m9k7q4r8t5v6w3y0z1dp",
"project_id": "prj_01jbx2m9k7q4r8t5v6w3y0z1pr",
"environment_id": "env_01jbx2m9k7q4r8t5v6w3y0z1en",
"service_id": "svc_01jbx2m9k7q4r8t5v6w3y0z1sv",
"service_name": "web",
"environment_name": "production",
"status": "active",
"status_text": "Live since 14:05",
"trigger": {
"kind": "git_push",
"actor": {
"type": "github",
"id": "stewartwebb",
"display": "stewartwebb pushed to main"
}
},
"source": {
"kind": "git",
"commit": {
"sha": "a1b2c3d4e5f60718293a4b5c6d7e8f9012345678",
"branch": "main",
"message": "Fix rota export",
"author": "Stewart Webb"
}
},
"build_id": "bld_01jbx2m9k7q4r8t5v6w3y0z1bd",
"image": {
"digest": "sha256:4b1f0e9d8c7b6a5948372615f4e3d2c1b0a9f8e7d6c5b4a3928170f6e5d4c3b2",
"signed": true
},
"rollback_of": null,
"operation_id": "op_01jbx2m9k7q4r8t5v6w3y0z1op",
"url": "https://www.primecarers.co.uk",
"failure": null,
"created_at": "2026-10-23T14:02:00Z",
"started_at": "2026-10-23T14:02:01Z",
"active_at": "2026-10-23T14:05:12Z",
"finished_at": "2026-10-23T14:05:12Z",
"duration_ms": 191000
}
POST /v1/deployments/{deployment_id}/rollback

Creates a new deployment that re-promotes this deployment’s image and settings snapshot (with current secret values). Fails with deployment_not_rollbackable if the image has passed retention.

  • Operation: rollbackDeployment
  • Scopes: deploy:{environment}
  • CLI: guv rollback
  • Approval: In environments with protection turned on (usually production), changes by agents and by roles outside approver_roles return approval_required.
  • Idempotency-Key: required; supports ?dry_run=true

Parameters

Name In Type Description
deployment_id * path string

Request body (application/json): DeploymentRollback

Field Type Description
reason string

Responses

Status Meaning Body
200 OK Dry run. Nothing was changed; this is what would happen. Plan
202 Accepted Accepted. The work continues in the background; follow the operation. Operation

Errors: 400, 401, 403, 404, 409, 422, 429, 500, as problem+json with a stable code.

Example

Terminal window
curl -X POST https://api.guv.dev/v1/deployments/dep_01jbx2m9k7q4r8t5v6w3y0z1pr/rollback \
-H "Authorization: Bearer $GUV_TOKEN" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{
"reason": "Checkout is failing after the last deploy"
}'

Example response

{
"id": "op_01jbx2m9k7q4r8t5v6w3y0z1op",
"kind": "deployment.create",
"status": "running",
"summary": "Deploying web to production",
"workspace_id": "ws_01jbx2m9k7q4r8t5v6w3y0z1ws",
"project_id": "prj_01jbx2m9k7q4r8t5v6w3y0z1pr",
"environment_id": "env_01jbx2m9k7q4r8t5v6w3y0z1en",
"resource": {
"type": "deployment",
"id": "dep_01jbx2m9k7q4r8t5v6w3y0z1dp",
"url": "/v1/deployments/dep_01jbx2m9k7q4r8t5v6w3y0z1dp"
},
"progress": {
"current_step": "build",
"completed_steps": 1,
"total_steps": 6,
"percent": 20
},
"steps": [
{
"name": "resolve",
"title": "Reading your settings",
"status": "succeeded",
"attempt": 1,
"started_at": "2026-10-23T14:02:00Z",
"finished_at": "2026-10-23T14:02:01Z"
},
{
"name": "build",
"title": "Building your app",
"status": "running",
"attempt": 1,
"started_at": "2026-10-23T14:02:01Z",
"finished_at": null
}
],
"created_by": {
"type": "user",
"id": "usr_01jbx2m9k7q4r8t5v6w3y0z1us",
"display": "Stewart Webb"
},
"created_at": "2026-10-23T14:02:00Z",
"links": {
"self": "/v1/operations/op_01jbx2m9k7q4r8t5v6w3y0z1op",
"events": "/v1/operations/op_01jbx2m9k7q4r8t5v6w3y0z1op/events",
"resource": "/v1/deployments/dep_01jbx2m9k7q4r8t5v6w3y0z1dp"
}
}

Cancel a deployment that has not gone live

Section titled “Cancel a deployment that has not gone live”
POST /v1/deployments/{deployment_id}/cancel
  • Operation: cancelDeployment
  • Scopes: deploy:{environment}
  • Idempotency-Key: required; supports ?dry_run=true

Parameters

Name In Type Description
deployment_id * path string

Responses

Status Meaning Body
200 OK OK. With dry_run=true: a Plan (application/vnd.guv.plan+json) and nothing changes. Deployment

Errors: 400, 401, 403, 404, 409, 422, 429, 500, as problem+json with a stable code.

Example

Terminal window
curl -X POST https://api.guv.dev/v1/deployments/dep_01jbx2m9k7q4r8t5v6w3y0z1pr/cancel \
-H "Authorization: Bearer $GUV_TOKEN" \
-H "Idempotency-Key: $(uuidgen)"

Example response

{
"id": "dep_01jbx2m9k7q4r8t5v6w3y0z1dp",
"project_id": "prj_01jbx2m9k7q4r8t5v6w3y0z1pr",
"environment_id": "env_01jbx2m9k7q4r8t5v6w3y0z1en",
"service_id": "svc_01jbx2m9k7q4r8t5v6w3y0z1sv",
"service_name": "web",
"environment_name": "production",
"status": "active",
"status_text": "Live since 14:05",
"trigger": {
"kind": "git_push",
"actor": {
"type": "github",
"id": "stewartwebb",
"display": "stewartwebb pushed to main"
}
},
"source": {
"kind": "git",
"commit": {
"sha": "a1b2c3d4e5f60718293a4b5c6d7e8f9012345678",
"branch": "main",
"message": "Fix rota export",
"author": "Stewart Webb"
}
},
"build_id": "bld_01jbx2m9k7q4r8t5v6w3y0z1bd",
"image": {
"digest": "sha256:4b1f0e9d8c7b6a5948372615f4e3d2c1b0a9f8e7d6c5b4a3928170f6e5d4c3b2",
"signed": true
},
"rollback_of": null,
"operation_id": "op_01jbx2m9k7q4r8t5v6w3y0z1op",
"url": "https://www.primecarers.co.uk",
"failure": null,
"created_at": "2026-10-23T14:02:00Z",
"started_at": "2026-10-23T14:02:01Z",
"active_at": "2026-10-23T14:05:12Z",
"finished_at": "2026-10-23T14:05:12Z",
"duration_ms": 191000
}
GET /v1/deployments/{deployment_id}/logs

JSON page by default. With Accept: text/event-stream (or ?follow=true) streams log events until the deployment settles.

  • Operation: getDeploymentLogs
  • Scopes: logs:read

Parameters

Name In Type Description
deployment_id * path string
source query build, deploy, runtime
follow query boolean

Responses

Status Meaning Body
200 OK OK. LogQueryResult

Errors: 400, 401, 403, 404, 429, 500, as problem+json with a stable code.

Example

Terminal window
curl https://api.guv.dev/v1/deployments/dep_01jbx2m9k7q4r8t5v6w3y0z1pr/logs \
-H "Authorization: Bearer $GUV_TOKEN"

Example response

{
"lines": [
{
"id": "lg_9f8e7d6c5b",
"timestamp": "2026-10-23T14:04:02.123Z",
"source": "runtime",
"level": "error",
"message": "TypeError: Cannot read properties of undefined (reading 'id')",
"service": {
"id": "svc_01jbx2m9k7q4r8t5v6w3y0z1sv",
"name": "web"
},
"environment": "production",
"deployment_id": "dep_01jbx2m9k7q4r8t5v6w3y0z1dp",
"replica": "web-1",
"http": null,
"attributes": {},
"redacted": false
}
],
"next_cursor": "string",
"has_more": false,
"query": "string",
"dropped_lines": 1
}
GET /v1/deployments/{deployment_id}/explanation
  • Operation: getDeploymentExplanation
  • Scopes: projects:read
  • CLI: guv doctor

Parameters

Name In Type Description
deployment_id * path string

Responses

Status Meaning Body
200 OK OK. DeployExplanation

Errors: 400, 401, 403, 404, 429, 500, as problem+json with a stable code.

Example

Terminal window
curl https://api.guv.dev/v1/deployments/dep_01jbx2m9k7q4r8t5v6w3y0z1pr/explanation \
-H "Authorization: Bearer $GUV_TOKEN"

Example response

{
"deployment_id": "dep_01jbx2m9k7q4r8t5v6w3y0z1dp",
"status": "available",
"category": "port_mismatch",
"cause": "Your app listens on port 8080 but we expected 3000.",
"fix": {
"summary": "Set port: 8080 on the web service.",
"actions": [
{
"kind": "one_click",
"label": "Set port to 8080",
"command": "guv services update web --port 8080",
"api": {
"method": "PATCH",
"path": "/v1/projects/primecarers/services/web",
"body": {
"port": 8080
}
}
},
{
"kind": "open_pr",
"label": "Ask AI to fix (opens a PR)"
}
]
},
"evidence": [
{
"source": "runtime_log",
"timestamp": "2026-10-23T14:04:02Z",
"text": "Server listening on http://0.0.0.0:8080"
}
],
"confidence": "high",
"generated_by": "rules",
"ai_generated": false
}