Skip to content

Stack API

All stack API endpoints require:

  • Accept: application/vnd.pulumi+8 header
  • Authorization: token <api-token> header

The {org} parameter in the URL determines which organization is being accessed. The OrgAuth middleware checks that the authenticated user has the required role in that organization.

POST /api/stacks/{org}/{project}

Creates a new stack. Auto-creates the organization and project if they don’t exist (via INSERT ON CONFLICT DO NOTHING).

Required role: member

Request body:

{
"stackName": "dev"
}

Response (200):

{
"id": "org/project/dev",
"orgName": "org",
"projectName": "project",
"stackName": "dev",
"tags": {},
"version": 0
}

Errors:

  • 409 Conflict — stack already exists
HEAD /api/stacks/{org}/{project}

Returns 200 if the project exists, 404 otherwise. Used by the CLI to check if a project namespace is available.

Required role: viewer

GET /api/stacks/{org}/{project}/{stack}

Returns stack metadata.

Required role: viewer

Response (200):

{
"orgName": "org",
"projectName": "project",
"stackName": "dev",
"tags": {"pulumi:project": "my-project"},
"version": 5,
"activeUpdate": ""
}
DELETE /api/stacks/{org}/{project}/{stack}

Deletes a stack and all associated data (updates, events, checkpoints) via cascade.

Required role: admin

Errors:

  • 404 Not Found — stack doesn’t exist
  • 409 Conflict — stack has an active update in progress
GET /api/user/stacks

Returns all stacks the authenticated user has access to, filtered by their organization memberships.

Required role: viewer (per org)

Response (200):

{
"stacks": [
{
"orgName": "dev-org",
"projectName": "my-project",
"stackName": "dev",
"tags": {},
"version": 3,
"activeUpdate": "",
"lastUpdate": {
"kind": "update",
"status": "succeeded",
"startTime": 1709827200
}
}
]
}
POST /api/stacks/{org}/{project}/{stack}/rename

Renames a stack within the same organization. Creates the target project if it doesn’t exist.

Required role: member

Request body:

{
"newName": "org/new-project/staging"
}

Response (204): No content

Errors:

  • 400 Bad Request — invalid fully qualified name
  • 404 Not Found — source stack doesn’t exist
  • 409 Conflict — target stack name already exists

The rename operation runs in a transaction and also creates a rename update record for history tracking.

PATCH /api/stacks/{org}/{project}/{stack}/tags

Adds or removes tags on a stack. Tags are key-value pairs stored as JSONB.

Required role: member

Request body:

{
"tags": {
"pulumi:project": "my-project",
"environment": "staging",
"team": "platform"
}
}

Response (204): No content

All requests must include:

Accept: application/vnd.pulumi+8
Authorization: token <api-token>
Content-Type: application/json (for POST/PATCH)

The PulumiAccept middleware rejects requests to /api/ routes that don’t include the correct Accept header, returning 415 Unsupported Media Type.