Core Concepts
Understanding the Puchify object model, resource lifecycle, and API design.
Resources
Everything in Puchify is a resource. Servers, databases, Kubernetes clusters, load balancers — all resources follow the same lifecycle and share a consistent API.
Resource lifecycle
Created ──► Creating ──► Running ──► Stopped ──► Destroyed
\ /
└──► Failed ◄┘States are lowercase identifiers returned by the API:
- creating — provisioning in progress
- running (or healthy / available) — resource is operational
- stopped — resource exists but is powered off
- deleted — soft-deleted, still visible in history
- destroyed — resource is gone, provider resources released
- failed — provisioning error
CRUD + Actions
Every resource supports the standard CRUD operations plus resource-specific actions:
| Operation | Method | Example |
|---|---|---|
| List | GET /api/v1/{resource} | GET /api/v1/servers |
| Create | POST /api/v1/{resource} | POST /api/v1/servers |
| Get | GET /api/v1/{resource}/{id} | GET /api/v1/servers/svr_123 |
| Update | PATCH /api/v1/{resource}/{id} | PATCH /api/v1/servers/svr_123 |
| Delete | DELETE /api/v1/{resource}/{id} | DELETE /api/v1/servers/svr_123 |
| Action | POST /api/v1/{resource}/{id}/{action} | POST /api/v1/servers/svr_123/restart |
Response envelope
Every API response follows a consistent format:
{
"data": { ... },
"meta": {
"persistence": "synced",
"provider": "connected",
"next_cursor": null
}
}- data — the resource or resource list
- meta.persistence —
synced(DB confirmed),stale(cache),unavailable - meta.provider —
connected,degraded, orunavailable(cloud provider status) - meta.next_cursor — for paginated list responses
Error responses:
{
"error": {
"code": "server_not_found",
"message": "Server svr_abc123 not found"
},
"meta": {
"persistence": "synced",
"provider": "connected"
}
}Pagination
List endpoints use cursor-based pagination:
// GET /api/v1/servers?limit=10
{
"data": [ ... ],
"meta": {
"next_cursor": "cursor_abc123",
// ...
}
}
// GET /api/v1/servers?cursor=cursor_abc123&limit=10
{
"data": [ ... ],
"meta": {
"next_cursor": null // last page
}
}Authentication
Two authentication methods:
API keys (recommended for programmatic access):
Authorization: Bearer pk_xxxxCreate and manage API keys in Settings → API Keys. Keys are bcrypt-hashed at rest; only the prefix and the full key (shown once at creation) can access the API.
Session cookies — used automatically by the web app via WorkOS AuthKit.
Rate limiting
API keys are rate-limited to 1000 requests per minute. Rate limit headers are included in every response:
X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 987
X-RateLimit-Reset: 1680000000Exceeding the limit returns 429 Too Many Requests.
Event-driven architecture
Resource state changes emit events. These events power:
- Webhooks — outbound HTTP POST to your endpoints
- Audit log — searchable event history
- Agent — the AI agent reacts to events
Events are fire-and-forget with best-effort delivery. Webhooks include HMAC-SHA256 signatures for verification.