Skip to content

Manifest

View as Markdown

Validate, plan, apply and export guv.yaml.

Operation Method and path
Export live state as guv.yaml (pull / eject) GET /v1/projects/{project}/manifest
Manifest management and drift status GET /v1/projects/{project}/manifest/status
Validate guv.yaml (schema, references, policy) POST /v1/projects/{project}/manifest/validate
Plan guv.yaml against live state POST /v1/projects/{project}/manifest/plan
Apply a plan POST /v1/projects/{project}/manifest/apply

Export live state as guv.yaml (pull / eject)

Section titled “Export live state as guv.yaml (pull / eject)”
GET /v1/projects/{project}/manifest

Accept: application/yaml returns the file itself.

  • Operation: exportManifest
  • Scopes: projects:read
  • CLI: guv pull

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

Responses

Status Meaning Body
200 OK OK. ManifestExport

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

Example response

{
"manifest": "string",
"generated_at": "2026-10-22T13:05:00Z"
}
GET /v1/projects/{project}/manifest/status
  • Operation: getManifestStatus
  • 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).

Responses

Status Meaning Body
200 OK OK. ManifestStatus

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

Example response

{
"managed_by_manifest": false,
"source": {
"repo": "string",
"path": "string",
"commit": "string"
},
"last_applied": {
"plan_hash": "string",
"at": "2026-10-22T13:05:00Z",
"by": {
"type": "agent",
"id": "tok_01jbx2m9k7q4r8t5v6w3y0z1tk",
"display": "Stewart Webb via agent claude-code-on-stewart-laptop",
"via_agent": {
"id": "tok_01jbx2m9k7q4r8t5v6w3y0z1tk",
"name": "claude-code-on-stewart-laptop"
},
"on_behalf_of": {
"id": "usr_01jbx2m9k7q4r8t5v6w3y0z1us",
"display": "Stewart Webb"
}
},
"operation_id": "string"
},
"drift": {
"detected": false,
"checked_at": "2026-10-22T13:05:00Z",
"changes": [
{
"action": "create",
"resource": {
"type": "service",
"id": "svc_01jbx2m9k7q4r8t5v6w3y0z1sv",
"name": "web",
"url": "/v1/projects/primecarers/services/web"
},
"environment": "production",
"summary": "Create Postgres 18 database main (HA, 50 GB, 30 days point-in-time recovery)",
"diff": [
{}
],
"destructive": false,
"requires_approval": false,
"reason": "string"
}
]
}
}

Validate guv.yaml (schema, references, policy)

Section titled “Validate guv.yaml (schema, references, policy)”
POST /v1/projects/{project}/manifest/validate
  • Operation: validateManifest
  • Scopes: projects:read
  • CLI: guv validate
  • Idempotency-Key: optional

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): ManifestInput

Field Type Description
manifest * string The guv.yaml text (YAML or JSON).
files map of string to string Extra files referenced by include (path to content).
environment string Limit the plan to one environment.

Responses

Status Meaning Body
200 OK OK. ManifestValidation

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/manifest/validate \
-H "Authorization: Bearer $GUV_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"manifest": "string",
"files": {
"key": "string"
},
"environment": "string"
}'

Example response

{
"valid": false,
"errors": [
{
"path": "/services/web/port",
"line": 1,
"column": 1,
"code": "secret_missing",
"message": "string",
"fix": "string",
"severity": "error"
}
],
"warnings": [
{
"path": "/services/web/port",
"line": 1,
"column": 1,
"code": "secret_missing",
"message": "string",
"fix": "string",
"severity": "error"
}
],
"schema_version": "1"
}
POST /v1/projects/{project}/manifest/plan

Never changes anything. Returns the diff, cost delta, policy decision and the plan_hash to apply.

  • Operation: planManifest
  • Scopes: projects:read
  • CLI: guv plan
  • Idempotency-Key: optional

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): ManifestInput

Field Type Description
manifest * string The guv.yaml text (YAML or JSON).
files map of string to string Extra files referenced by include (path to content).
environment string Limit the plan to one environment.

Responses

Status Meaning Body
200 OK OK. Plan

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/manifest/plan \
-H "Authorization: Bearer $GUV_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"manifest": "string",
"files": {
"key": "string"
},
"environment": "string"
}'

Example response

{
"plan_hash": "sha256:9f2c1e0b7a4d3c2b1a09f8e7d6c5b4a39281706f5e4d3c2b1a0f9e8d7c6b5a49",
"dry_run": true,
"summary": "1 to update. +£5.00/month at current usage.",
"changes": [
{
"action": "update",
"resource": {
"type": "service",
"id": "svc_01jbx2m9k7q4r8t5v6w3y0z1sv",
"name": "web"
},
"environment": "production",
"summary": "Raise web memory limit from 1 GB to 2 GB",
"diff": [
{
"path": "/resources/memory_mb",
"before": 1024,
"after": 2048
}
],
"destructive": false,
"requires_approval": true,
"reason": "production requires approval for changes made by agents"
}
],
"cost": {
"current_monthly": {
"amount": "18.20",
"currency": "GBP",
"display": "£18.20"
},
"projected_monthly": {
"amount": "23.20",
"currency": "GBP",
"display": "£23.20"
},
"delta_monthly": {
"amount": "5.00",
"currency": "GBP",
"display": "£5.00"
},
"confidence": "medium"
},
"policy": {
"decision": "approval_required",
"reasons": [
{
"code": "environment_protected",
"message": "production requires approval for changes made by agents",
"policy": "guv.environment.protection"
}
],
"approver_roles": [
"owner",
"admin"
]
},
"requires_approval": true,
"expires_at": "2026-10-23T15:00:00Z"
}
POST /v1/projects/{project}/manifest/apply

The plan_hash must match a fresh plan of the same manifest; otherwise 409 plan_hash_mismatch. The plan hash doubles as the idempotency key of the apply operation.

  • Operation: applyManifest
  • Scopes: manifest:apply
  • CLI: guv apply
  • 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).

Request body (application/json, required): ManifestApplyRequest

Field Type Description
manifest * string The guv.yaml text (YAML or JSON).
files map of string to string Extra files referenced by include (path to content).
environment string Limit the plan to one environment.
plan_hash * string Must match a plan made from the same manifest and the current live state, or the call fails with plan_hash_mismatch.

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/manifest/apply \
-H "Authorization: Bearer $GUV_TOKEN" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{
"manifest": "string",
"files": {
"key": "string"
},
"environment": "string",
"plan_hash": "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"
}
}