Admin API

Manage your fleet programmatically.

Everything you can do per app in the panel also works as a REST call: create app IDs with enrollment codes, list your fleet, deactivate or delete apps. Built for scripts and AI agents — one static API key, plain JSON, no SDK required.

Authentication

Create an API key in the panel under Settings → API keys. The key (pz_live_…) is shown once — store it safely. Send it as a Bearer token with every request:

curl https://poisonzero.com/api/v1/apps \
  -H "Authorization: Bearer pz_live_..."

Endpoints

POST /v1/apps

Creates an app and an enrollment code in one call. Optional body: {"name": "…"} (max. 100 characters). Returns 201 with appId, enrollCode, and enrollCodeExpiresAt — everything a machine needs to enroll.

curl -X POST https://poisonzero.com/api/v1/apps \
  -H "Authorization: Bearer $PZ_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"name": "build-server-07"}'

GET /v1/apps

Lists your fleet: appId, name, status (pending / active / revoked), platform, agentVersion, lastSeenAt, createdAt.

curl https://poisonzero.com/api/v1/apps -H "Authorization: Bearer $PZ_API_KEY"

GET /v1/apps/{appId}

Returns a single app. Unknown IDs — including apps that belong to someone else — answer 404.

curl https://poisonzero.com/api/v1/apps/k7x2m9q4w1bz8r3tj6vn -H "Authorization: Bearer $PZ_API_KEY"

POST /v1/apps/{appId}/enroll-code

Creates a fresh enrollment code for an existing app, e.g. to re-provision a machine. Codes are single-use and valid for 30 days.

curl -X POST https://poisonzero.com/api/v1/apps/k7x2m9q4w1bz8r3tj6vn/enroll-code -H "Authorization: Bearer $PZ_API_KEY"

POST /v1/apps/{appId}/revoke

Deactivates an app: status becomes revoked and the daemon's credentials stop working immediately. Same effect as “Revoke” in the panel.

curl -X POST https://poisonzero.com/api/v1/apps/k7x2m9q4w1bz8r3tj6vn/revoke -H "Authorization: Bearer $PZ_API_KEY"

DELETE /v1/apps/{appId}

Deletes an app permanently: app, configuration, daemon identity, open enrollment codes, and its review-queue entries. Audit logs are retained. Returns 204.

curl -X DELETE https://poisonzero.com/api/v1/apps/k7x2m9q4w1bz8r3tj6vn -H "Authorization: Bearer $PZ_API_KEY"

Provision 50 daemons in one loop

Each call returns an app ID plus enrollment code — feed them straight into your fleet automation (Ansible, SSH loop, MDM). The daemons enroll themselves on first start:

for i in $(seq -w 1 50); do
  curl -s -X POST https://poisonzero.com/api/v1/apps \
    -H "Authorization: Bearer $PZ_API_KEY" \
    -H "Content-Type: application/json" \
    -d "{\"name\": \"daemon-$i\"}"
done

Errors

All errors share one shape: {"error": {"code": "…", "message": "…"}}. 401 — missing/invalid/revoked key or disabled account. 404 — unknown endpoint or unknown/foreign app ID. 400 — validation (e.g. invalid_name, limit_reached).

Machine-readable: Markdown version · OpenAPI 3 spec. Billing is unchanged: active daemons are metered nightly, no matter how they were created.