Skip to content

Services

View as Markdown

Web services, private services, workers and cron jobs. A service is defined once per project and has an instance in each environment.

Operation Method and path
List services (project-level definitions) GET /v1/projects/{project}/services
Create a service POST /v1/projects/{project}/services
Get a service’s base settings GET /v1/projects/{project}/services/{service}
Update a service’s base settings PATCH /v1/projects/{project}/services/{service}
Delete a service from every environment DELETE /v1/projects/{project}/services/{service}
Services as they run in an environment GET /v1/projects/{project}/environments/{environment}/services
A service in one environment (effective settings, status, URLs) GET /v1/projects/{project}/environments/{environment}/services/{service}
Set this environment’s overrides for a service PATCH /v1/projects/{project}/environments/{environment}/services/{service}
Restart the running deployment POST /v1/projects/{project}/environments/{environment}/services/{service}/restart
GET /v1/projects/{project}/services
  • Operation: listServices
  • 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).

Responses

Status Meaning Body
200 OK A page of Service objects. ServiceList

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/services \
-H "Authorization: Bearer $GUV_TOKEN"

Example response

{
"data": [
{
"id": "svc_01jbx2m9k7q4r8t5v6w3y0z1sv",
"project_id": "prj_01jbx2m9k7q4r8t5v6w3y0z1pr",
"name": "web",
"kind": "web",
"managed_by_manifest": true,
"source": {
"kind": "git",
"repo": "primecarers/platform",
"root": "apps/web",
"watch": [
"apps/web/**",
"packages/ui/**",
"pnpm-lock.yaml"
]
},
"build": {
"builder": "railpack"
},
"start": "pnpm --filter web start",
"pre_deploy": "pnpm --filter db migrate deploy",
"port": 3000,
"healthcheck": {
"type": "http",
"path": "/healthz",
"timeout_seconds": 10
},
"resources": {
"cpu": 2,
"memory_mb": 2048
},
"replicas": {
"min": 2,
"max": 6,
"scale_on": {
"cpu_percent": 70,
"concurrency": 80
}
},
"sleep_when_idle": false,
"private": false,
"cron": null,
"created_at": "2026-10-22T09:30:00Z",
"updated_at": "2026-10-23T10:00:00Z"
}
],
"next_cursor": "string",
"has_more": false
}
POST /v1/projects/{project}/services

Creates the definition and an instance in every environment. Nothing runs until the first deployment.

  • Operation: createService
  • Scopes: projects:write
  • 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).

Request body (application/json, required): ServiceCreate

Field Type Description
name * string
source ServiceSource
build BuildSettings
start string or null Start command. Detected when empty.
pre_deploy string or null Runs once per deployment in a separate VM before traffic moves; failure stops the rollout.
port integer or null
healthcheck Healthcheck or any or null
resources ServiceResources
replicas Replicas
sleep_when_idle boolean Scale to zero after 10 idle minutes; the first request wakes it in 1–3 s.
private boolean No public domain; reachable only on the environment’s private network.
cron CronSettings or any or null
restart_policy object
deploy object
volumes array of VolumeMount

Responses

Status Meaning Body
200 OK Dry run. Nothing was changed; this is what would happen. Plan
201 Created Created. Service

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/services \
-H "Authorization: Bearer $GUV_TOKEN" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{
"name": "string",
"source": {
"kind": "git",
"repo": "string",
"root": "apps/web",
"watch": [
"apps/web/**",
"packages/ui/**",
"pnpm-lock.yaml"
],
"image": "ghcr.io/acme/api:1.4.2",
"registry_credentials_secret": "string"
},
"build": {
"builder": "railpack",
"dockerfile": "services/api/Dockerfile",
"context": "string"
},
"start": "pnpm --filter web start",
"pre_deploy": "pnpm --filter db migrate deploy",
"port": 3000,
"healthcheck": {
"type": "http",
"path": "/healthz",
"port": 1,
"timeout_seconds": 10,
"interval_seconds": 10,
"start_timeout_seconds": 300
},
"resources": {
"cpu": 1,
"memory_mb": 1024
},
"replicas": {
"min": 1,
"max": 1,
"scale_on": {
"cpu_percent": 10,
"memory_percent": 10,
"concurrency": 1
}
},
"sleep_when_idle": false,
"private": false,
"cron": {
"schedule": "0 2 * * *",
"timezone": "Europe/London",
"timeout_seconds": 1,
"concurrency_policy": "forbid"
},
"restart_policy": {
"mode": "on_failure",
"max_retries": 10
},
"deploy": {
"overlap_seconds": 20,
"auto_rollback": false
},
"volumes": [
{
"volume": "string",
"mount_path": "/data"
}
]
}'

Example response

{
"id": "svc_01jbx2m9k7q4r8t5v6w3y0z1sv",
"project_id": "prj_01jbx2m9k7q4r8t5v6w3y0z1pr",
"name": "web",
"kind": "web",
"managed_by_manifest": true,
"source": {
"kind": "git",
"repo": "primecarers/platform",
"root": "apps/web",
"watch": [
"apps/web/**",
"packages/ui/**",
"pnpm-lock.yaml"
]
},
"build": {
"builder": "railpack"
},
"start": "pnpm --filter web start",
"pre_deploy": "pnpm --filter db migrate deploy",
"port": 3000,
"healthcheck": {
"type": "http",
"path": "/healthz",
"timeout_seconds": 10
},
"resources": {
"cpu": 2,
"memory_mb": 2048
},
"replicas": {
"min": 2,
"max": 6,
"scale_on": {
"cpu_percent": 70,
"concurrency": 80
}
},
"sleep_when_idle": false,
"private": false,
"cron": null,
"created_at": "2026-10-22T09:30:00Z",
"updated_at": "2026-10-23T10:00:00Z"
}
GET /v1/projects/{project}/services/{service}
  • Operation: getService
  • Scopes: projects:read

Parameters

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

Responses

Status Meaning Body
200 OK OK. Service

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/services/web \
-H "Authorization: Bearer $GUV_TOKEN"

Example response

{
"id": "svc_01jbx2m9k7q4r8t5v6w3y0z1sv",
"project_id": "prj_01jbx2m9k7q4r8t5v6w3y0z1pr",
"name": "web",
"kind": "web",
"managed_by_manifest": true,
"source": {
"kind": "git",
"repo": "primecarers/platform",
"root": "apps/web",
"watch": [
"apps/web/**",
"packages/ui/**",
"pnpm-lock.yaml"
]
},
"build": {
"builder": "railpack"
},
"start": "pnpm --filter web start",
"pre_deploy": "pnpm --filter db migrate deploy",
"port": 3000,
"healthcheck": {
"type": "http",
"path": "/healthz",
"timeout_seconds": 10
},
"resources": {
"cpu": 2,
"memory_mb": 2048
},
"replicas": {
"min": 2,
"max": 6,
"scale_on": {
"cpu_percent": 70,
"concurrency": 80
}
},
"sleep_when_idle": false,
"private": false,
"cron": null,
"created_at": "2026-10-22T09:30:00Z",
"updated_at": "2026-10-23T10:00:00Z"
}
PATCH /v1/projects/{project}/services/{service}

JSON Merge Patch. Changes apply on the next deployment of each environment. Projects managed by guv.yaml return a manifest_patch fix suggesting a PR instead, unless ?force=true.

  • Operation: updateService
  • Scopes: projects:write
  • CLI: guv services update
  • 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
  • Concurrency: send the ETag you read as If-Match

Parameters

Name In Type Description
project * path string Project id (prj_…) or slug (resolved in the Guv-Workspace workspace, or the caller’s default).
service * path string Service id (svc_…) or name.
force query boolean Edit even though the project is managed by guv.yaml (creates drift).

Request body (application/json, required): ServiceConfig

Field Type Description
source ServiceSource
build BuildSettings
start string or null Start command. Detected when empty.
pre_deploy string or null Runs once per deployment in a separate VM before traffic moves; failure stops the rollout.
port integer or null
healthcheck Healthcheck or any or null
resources ServiceResources
replicas Replicas
sleep_when_idle boolean Scale to zero after 10 idle minutes; the first request wakes it in 1–3 s.
private boolean No public domain; reachable only on the environment’s private network.
cron CronSettings or any or null
restart_policy object
deploy object
volumes array of VolumeMount

Responses

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

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

Example

Terminal window
curl -X PATCH https://api.guv.dev/v1/projects/shopfront/services/web \
-H "Authorization: Bearer $GUV_TOKEN" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{
"source": {
"kind": "git",
"repo": "string",
"root": "apps/web",
"watch": [
"apps/web/**",
"packages/ui/**",
"pnpm-lock.yaml"
],
"image": "ghcr.io/acme/api:1.4.2",
"registry_credentials_secret": "string"
},
"build": {
"builder": "railpack",
"dockerfile": "services/api/Dockerfile",
"context": "string"
},
"start": "pnpm --filter web start",
"pre_deploy": "pnpm --filter db migrate deploy",
"port": 3000,
"healthcheck": {
"type": "http",
"path": "/healthz",
"port": 1,
"timeout_seconds": 10,
"interval_seconds": 10,
"start_timeout_seconds": 300
},
"resources": {
"cpu": 1,
"memory_mb": 1024
},
"replicas": {
"min": 1,
"max": 1,
"scale_on": {
"cpu_percent": 10,
"memory_percent": 10,
"concurrency": 1
}
},
"sleep_when_idle": false,
"private": false,
"cron": {
"schedule": "0 2 * * *",
"timezone": "Europe/London",
"timeout_seconds": 1,
"concurrency_policy": "forbid"
},
"restart_policy": {
"mode": "on_failure",
"max_retries": 10
},
"deploy": {
"overlap_seconds": 20,
"auto_rollback": false
},
"volumes": [
{
"volume": "string",
"mount_path": "/data"
}
]
}'

Example response

{
"id": "svc_01jbx2m9k7q4r8t5v6w3y0z1sv",
"project_id": "prj_01jbx2m9k7q4r8t5v6w3y0z1pr",
"name": "web",
"kind": "web",
"managed_by_manifest": true,
"source": {
"kind": "git",
"repo": "primecarers/platform",
"root": "apps/web",
"watch": [
"apps/web/**",
"packages/ui/**",
"pnpm-lock.yaml"
]
},
"build": {
"builder": "railpack"
},
"start": "pnpm --filter web start",
"pre_deploy": "pnpm --filter db migrate deploy",
"port": 3000,
"healthcheck": {
"type": "http",
"path": "/healthz",
"timeout_seconds": 10
},
"resources": {
"cpu": 2,
"memory_mb": 2048
},
"replicas": {
"min": 2,
"max": 6,
"scale_on": {
"cpu_percent": 70,
"concurrency": 80
}
},
"sleep_when_idle": false,
"private": false,
"cron": null,
"created_at": "2026-10-22T09:30:00Z",
"updated_at": "2026-10-23T10:00:00Z"
}
DELETE /v1/projects/{project}/services/{service}
  • Operation: deleteService
  • Scopes: projects:delete
  • Approval: Always needs a human approval with a passkey, whoever asks, including agents with full scopes.
  • Idempotency-Key: required; supports ?dry_run=true
  • Concurrency: send the ETag you read as If-Match

Parameters

Name In Type Description
project * path string Project id (prj_…) or slug (resolved in the Guv-Workspace workspace, or the caller’s default).
service * path string Service id (svc_…) or name.
confirm query string Typed confirmation for destructive actions. Must equal the resource name (or slug/hostname). Missing or wrong values return confirmation_required.

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, 412, 422, 429, 500, as problem+json with a stable code.

Example

Terminal window
curl -X DELETE https://api.guv.dev/v1/projects/shopfront/services/web \
-H "Authorization: Bearer $GUV_TOKEN" \
-H "Idempotency-Key: $(uuidgen)"

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/projects/{project}/environments/{environment}/services
  • Operation: listServiceInstances
  • 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.

Responses

Status Meaning Body
200 OK A page of ServiceInstance objects. ServiceInstanceList

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 \
-H "Authorization: Bearer $GUV_TOKEN"

Example response

{
"data": [
{
"service_id": "string",
"environment_id": "string",
"name": "string",
"kind": "web",
"status": "no_deployment",
"status_text": "Live. 2 of 2 copies healthy.",
"effective": {
"source": {
"kind": "git",
"repo": "string",
"root": "apps/web",
"watch": [
"apps/web/**",
"packages/ui/**",
"pnpm-lock.yaml"
],
"image": "ghcr.io/acme/api:1.4.2",
"registry_credentials_secret": "string"
},
"build": {
"builder": "railpack",
"dockerfile": "services/api/Dockerfile",
"context": "string"
},
"start": "pnpm --filter web start",
"pre_deploy": "pnpm --filter db migrate deploy",
"port": 3000,
"healthcheck": {
"type": "http",
"path": "/healthz",
"port": 1,
"timeout_seconds": 10,
"interval_seconds": 10,
"start_timeout_seconds": 300
},
"resources": {
"cpu": 1,
"memory_mb": 1024
},
"replicas": {
"min": 1,
"max": 1,
"scale_on": {}
},
"sleep_when_idle": false,
"private": false,
"cron": {
"schedule": "0 2 * * *",
"timezone": "Europe/London",
"timeout_seconds": 1,
"concurrency_policy": "forbid"
},
"restart_policy": {
"mode": "on_failure",
"max_retries": 10
},
"deploy": {
"overlap_seconds": 20,
"auto_rollback": false
},
"volumes": [
{}
]
},
"overrides": {
"source": {
"kind": "git",
"repo": "string",
"root": "apps/web",
"watch": [
"apps/web/**",
"packages/ui/**",
"pnpm-lock.yaml"
],
"image": "ghcr.io/acme/api:1.4.2",
"registry_credentials_secret": "string"
},
"build": {
"builder": "railpack",
"dockerfile": "services/api/Dockerfile",
"context": "string"
},
"start": "pnpm --filter web start",
"pre_deploy": "pnpm --filter db migrate deploy",
"port": 3000,
"healthcheck": {
"type": "http",
"path": "/healthz",
"port": 1,
"timeout_seconds": 10,
"interval_seconds": 10,
"start_timeout_seconds": 300
},
"resources": {
"cpu": 1,
"memory_mb": 1024
},
"replicas": {
"min": 1,
"max": 1,
"scale_on": {}
},
"sleep_when_idle": false,
"private": false,
"cron": {
"schedule": "0 2 * * *",
"timezone": "Europe/London",
"timeout_seconds": 1,
"concurrency_policy": "forbid"
},
"restart_policy": {
"mode": "on_failure",
"max_retries": 10
},
"deploy": {
"overlap_seconds": 20,
"auto_rollback": false
},
"volumes": [
{}
]
},
"current_deployment": {
"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
},
"urls": {
"public": [
"https://web-primecarers-k7q4.guv.run",
"https://www.primecarers.co.uk"
],
"internal_host": "web.guv.internal"
},
"replicas": {
"desired": 1,
"running": 1
},
"last_error": {
"message": "string",
"explanation_url": "string"
},
"cost_today": {
"amount": "7.42",
"currency": "GBP",
"display": "£7.42"
},
"updated_at": "2026-10-22T13:05:00Z"
}
],
"next_cursor": "string",
"has_more": false
}

A service in one environment (effective settings, status, URLs)

Section titled “A service in one environment (effective settings, status, URLs)”
GET /v1/projects/{project}/environments/{environment}/services/{service}
  • Operation: getServiceInstance
  • Scopes: projects:read

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.

Responses

Status Meaning Body
200 OK OK. ServiceInstance

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 \
-H "Authorization: Bearer $GUV_TOKEN"

Example response

{
"service_id": "string",
"environment_id": "string",
"name": "string",
"kind": "web",
"status": "no_deployment",
"status_text": "Live. 2 of 2 copies healthy.",
"effective": {
"source": {
"kind": "git",
"repo": "string",
"root": "apps/web",
"watch": [
"apps/web/**",
"packages/ui/**",
"pnpm-lock.yaml"
],
"image": "ghcr.io/acme/api:1.4.2",
"registry_credentials_secret": "string"
},
"build": {
"builder": "railpack",
"dockerfile": "services/api/Dockerfile",
"context": "string"
},
"start": "pnpm --filter web start",
"pre_deploy": "pnpm --filter db migrate deploy",
"port": 3000,
"healthcheck": {
"type": "http",
"path": "/healthz",
"port": 1,
"timeout_seconds": 10,
"interval_seconds": 10,
"start_timeout_seconds": 300
},
"resources": {
"cpu": 1,
"memory_mb": 1024
},
"replicas": {
"min": 1,
"max": 1,
"scale_on": {
"cpu_percent": 10,
"memory_percent": 10,
"concurrency": 1
}
},
"sleep_when_idle": false,
"private": false,
"cron": {
"schedule": "0 2 * * *",
"timezone": "Europe/London",
"timeout_seconds": 1,
"concurrency_policy": "forbid"
},
"restart_policy": {
"mode": "on_failure",
"max_retries": 10
},
"deploy": {
"overlap_seconds": 20,
"auto_rollback": false
},
"volumes": [
{
"volume": "string",
"mount_path": "/data"
}
]
},
"overrides": {
"source": {
"kind": "git",
"repo": "string",
"root": "apps/web",
"watch": [
"apps/web/**",
"packages/ui/**",
"pnpm-lock.yaml"
],
"image": "ghcr.io/acme/api:1.4.2",
"registry_credentials_secret": "string"
},
"build": {
"builder": "railpack",
"dockerfile": "services/api/Dockerfile",
"context": "string"
},
"start": "pnpm --filter web start",
"pre_deploy": "pnpm --filter db migrate deploy",
"port": 3000,
"healthcheck": {
"type": "http",
"path": "/healthz",
"port": 1,
"timeout_seconds": 10,
"interval_seconds": 10,
"start_timeout_seconds": 300
},
"resources": {
"cpu": 1,
"memory_mb": 1024
},
"replicas": {
"min": 1,
"max": 1,
"scale_on": {
"cpu_percent": 10,
"memory_percent": 10,
"concurrency": 1
}
},
"sleep_when_idle": false,
"private": false,
"cron": {
"schedule": "0 2 * * *",
"timezone": "Europe/London",
"timeout_seconds": 1,
"concurrency_policy": "forbid"
},
"restart_policy": {
"mode": "on_failure",
"max_retries": 10
},
"deploy": {
"overlap_seconds": 20,
"auto_rollback": false
},
"volumes": [
{
"volume": "string",
"mount_path": "/data"
}
]
},
"current_deployment": {
"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
},
"urls": {
"public": [
"https://web-primecarers-k7q4.guv.run",
"https://www.primecarers.co.uk"
],
"internal_host": "web.guv.internal"
},
"replicas": {
"desired": 1,
"running": 1
},
"last_error": {
"message": "string",
"explanation_url": "string"
},
"cost_today": {
"amount": "7.42",
"currency": "GBP",
"display": "£7.42"
},
"updated_at": "2026-10-22T13:05:00Z"
}

Set this environment’s overrides for a service

Section titled “Set this environment’s overrides for a service”
PATCH /v1/projects/{project}/environments/{environment}/services/{service}
  • Operation: updateServiceInstance
  • Scopes: projects:write
  • 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
  • Concurrency: send the ETag you read as If-Match

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, required): ServiceInstanceUpdate

Field Type Description
overrides ServiceConfig

Responses

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

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

Example

Terminal window
curl -X PATCH https://api.guv.dev/v1/projects/shopfront/environments/production/services/web \
-H "Authorization: Bearer $GUV_TOKEN" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{
"overrides": {
"source": {
"kind": "git",
"repo": "string",
"root": "apps/web",
"watch": [
"apps/web/**",
"packages/ui/**",
"pnpm-lock.yaml"
],
"image": "ghcr.io/acme/api:1.4.2",
"registry_credentials_secret": "string"
},
"build": {
"builder": "railpack",
"dockerfile": "services/api/Dockerfile",
"context": "string"
},
"start": "pnpm --filter web start",
"pre_deploy": "pnpm --filter db migrate deploy",
"port": 3000,
"healthcheck": {
"type": "http",
"path": "/healthz",
"port": 1,
"timeout_seconds": 10,
"interval_seconds": 10,
"start_timeout_seconds": 300
},
"resources": {
"cpu": 1,
"memory_mb": 1024
},
"replicas": {
"min": 1,
"max": 1,
"scale_on": {
"cpu_percent": 10,
"memory_percent": 10,
"concurrency": 1
}
},
"sleep_when_idle": false,
"private": false,
"cron": {
"schedule": "0 2 * * *",
"timezone": "Europe/London",
"timeout_seconds": 1,
"concurrency_policy": "forbid"
},
"restart_policy": {
"mode": "on_failure",
"max_retries": 10
},
"deploy": {
"overlap_seconds": 20,
"auto_rollback": false
},
"volumes": [
{
"volume": "string",
"mount_path": "/data"
}
]
}
}'

Example response

{
"service_id": "string",
"environment_id": "string",
"name": "string",
"kind": "web",
"status": "no_deployment",
"status_text": "Live. 2 of 2 copies healthy.",
"effective": {
"source": {
"kind": "git",
"repo": "string",
"root": "apps/web",
"watch": [
"apps/web/**",
"packages/ui/**",
"pnpm-lock.yaml"
],
"image": "ghcr.io/acme/api:1.4.2",
"registry_credentials_secret": "string"
},
"build": {
"builder": "railpack",
"dockerfile": "services/api/Dockerfile",
"context": "string"
},
"start": "pnpm --filter web start",
"pre_deploy": "pnpm --filter db migrate deploy",
"port": 3000,
"healthcheck": {
"type": "http",
"path": "/healthz",
"port": 1,
"timeout_seconds": 10,
"interval_seconds": 10,
"start_timeout_seconds": 300
},
"resources": {
"cpu": 1,
"memory_mb": 1024
},
"replicas": {
"min": 1,
"max": 1,
"scale_on": {
"cpu_percent": 10,
"memory_percent": 10,
"concurrency": 1
}
},
"sleep_when_idle": false,
"private": false,
"cron": {
"schedule": "0 2 * * *",
"timezone": "Europe/London",
"timeout_seconds": 1,
"concurrency_policy": "forbid"
},
"restart_policy": {
"mode": "on_failure",
"max_retries": 10
},
"deploy": {
"overlap_seconds": 20,
"auto_rollback": false
},
"volumes": [
{
"volume": "string",
"mount_path": "/data"
}
]
},
"overrides": {
"source": {
"kind": "git",
"repo": "string",
"root": "apps/web",
"watch": [
"apps/web/**",
"packages/ui/**",
"pnpm-lock.yaml"
],
"image": "ghcr.io/acme/api:1.4.2",
"registry_credentials_secret": "string"
},
"build": {
"builder": "railpack",
"dockerfile": "services/api/Dockerfile",
"context": "string"
},
"start": "pnpm --filter web start",
"pre_deploy": "pnpm --filter db migrate deploy",
"port": 3000,
"healthcheck": {
"type": "http",
"path": "/healthz",
"port": 1,
"timeout_seconds": 10,
"interval_seconds": 10,
"start_timeout_seconds": 300
},
"resources": {
"cpu": 1,
"memory_mb": 1024
},
"replicas": {
"min": 1,
"max": 1,
"scale_on": {
"cpu_percent": 10,
"memory_percent": 10,
"concurrency": 1
}
},
"sleep_when_idle": false,
"private": false,
"cron": {
"schedule": "0 2 * * *",
"timezone": "Europe/London",
"timeout_seconds": 1,
"concurrency_policy": "forbid"
},
"restart_policy": {
"mode": "on_failure",
"max_retries": 10
},
"deploy": {
"overlap_seconds": 20,
"auto_rollback": false
},
"volumes": [
{
"volume": "string",
"mount_path": "/data"
}
]
},
"current_deployment": {
"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
},
"urls": {
"public": [
"https://web-primecarers-k7q4.guv.run",
"https://www.primecarers.co.uk"
],
"internal_host": "web.guv.internal"
},
"replicas": {
"desired": 1,
"running": 1
},
"last_error": {
"message": "string",
"explanation_url": "string"
},
"cost_today": {
"amount": "7.42",
"currency": "GBP",
"display": "£7.42"
},
"updated_at": "2026-10-22T13:05:00Z"
}
POST /v1/projects/{project}/environments/{environment}/services/{service}/restart
  • Operation: restartService
  • Scopes: deploy:{environment}
  • CLI: guv restart
  • 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, required): ServiceRestart

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/projects/shopfront/environments/production/services/web/restart \
-H "Authorization: Bearer $GUV_TOKEN" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{
"reason": "string"
}'

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"
}
}