hostess API Sign in

REST API

JSON over HTTPS. Base URL https://hostess2.lab.stratus5.net. Every route under /v1 needs a bearer token. Mutations return an operation id you poll for progress.

Authentication

Send the token in an Authorization: Bearer header. The configured HOSTESS_API_KEY is the bootstrap key. Per-consumer keys are minted with hostess apikey mint <name> and revoked independently. Only the SHA-256 of each key is stored, and the raw value is shown once at mint. A missing or unknown token gets 401.

Authorization: Bearer hk_live_...

Providers

GET
/v1/providers

Native driver names plus the generic tofu driver.

Connections

A connection binds a driver to a sealed credential. Secrets are write-only and never returned.

GET
/v1/connections

List connections. Filter with ?driver=hcloud.

POST
/v1/connections

Create a connection. The secret is sealed server-side.

DELETE
/v1/connections/{id}

Delete a connection.

GET
/v1/connections/{id}/regions

Catalog regions. tofu connections return [] (free-text region).

GET
/v1/connections/{id}/sizes

Catalog sizes. Narrow with ?region=.

GET
/v1/connections/{id}/images

Catalog images.

Request
POST /v1/connections
{
  "name": "hetzner-prod",
  "driver": "hcloud",
  "secret": "",
  "meta": {}
}
201 Created
{ "id": "..." }

Nodes

POST
/v1/nodes

Provision a node. name and connectionId required. Returns 202.

GET
/v1/nodes

List nodes.

GET
/v1/nodes/{id}

Get one node.

POST
/v1/nodes/{id}/start

Power on. Native drivers only.

POST
/v1/nodes/{id}/stop

Power off.

POST
/v1/nodes/{id}/restart

Reboot.

POST
/v1/nodes/{id}/run

Run ansible scripts on a node. Body takes scriptIds and optional extraVars.

DELETE
/v1/nodes/{id}

Destroy the node. Returns an operation id.

Request
POST /v1/nodes
{
  "name": "web-1",
  "connectionId": "",
  "region": "nbg1",
  "size": "cx22",
  "image": "ubuntu-24.04",
  "tags": ["edge"]
}
202 Accepted
{
  "nodeId": "...",
  "operationId": "..."
}

Operations

Every mutation enqueues an operation. Each carries ordered steps with streamed output.

GET
/v1/operations

List recent operations. Cap with ?limit=.

GET
/v1/operations/{id}

Get one operation with its steps.

200 OK
{
  "id": "...",
  "type": "create_node",
  "status": "running",
  "attempts": 1,
  "steps": [
    { "seq": 0, "name": "build-provider", "status": "succeeded" },
    { "seq": 1, "name": "ensure-ssh-key", "status": "succeeded" },
    { "seq": 2, "name": "create-vm",      "status": "running", "output": "..." }
  ]
}

Ansible scripts

GET
/v1/ansible/scripts

List playbooks (metadata, no content).

POST
/v1/ansible/scripts

Create a playbook. name and content required.

GET
/v1/ansible/scripts/{id}

Get one playbook including its content.

PUT
/v1/ansible/scripts/{id}

Update content and variables. Bumps version, keeps history.

DELETE
/v1/ansible/scripts/{id}

Delete a playbook. System playbooks are protected.