@puchify/sdk
v0.0.4
Published
TypeScript SDK for the [Puchify](https://puchify.com) cloud platform. Manage servers, Kubernetes, GPU instances, storage, networking, observability, and more — with full type safety, pagination, retry logic, and webhook verification.
Readme
@puchify/sdk
TypeScript SDK for the Puchify cloud platform. Manage servers, Kubernetes, GPU instances, storage, networking, observability, and more — with full type safety, pagination, retry logic, and webhook verification.
npm install @puchify/sdkQuick start
import { Puchify } from "@puchify/sdk"
const puchify = new Puchify({ apiKey: "pk_..." })
// List servers
const { data: servers } = await puchify.servers.list()
for (const server of servers) {
console.log(server.name, server.status, server.ipv4)
}
// Create a server
const { data: newServer } = await puchify.servers.create({
name: "web-01",
plan: "c3-small",
region: "ams1",
})
// Wait for it to be running
const ready = await puchify.servers.waitFor(newServer.id, "running")
console.log(`Server ${ready.name} is ready at ${ready.ipv4}`)Resources
Every resource follows the same pattern:
puchify.<resource>.list(query?)
puchify.<resource>.get(id)
puchify.<resource>.create(params)
puchify.<resource>.update(id, params)
puchify.<resource>.delete(id)| Resource | Accessor | Actions |
|----------|----------|---------|
| Servers | puchify.servers | list, get, create, update, delete, restart, waitFor, listAll |
| GPU Servers | puchify.gpuServers | list, get, create, update, delete, restart, waitFor |
| Data | puchify.data | list, get, create, update, delete |
| Kubernetes | puchify.kubernetes | list, get, create, update, delete |
| Jobs | puchify.jobs | list, get, create, delete |
| Object Storage | puchify.objectStorage | list, get, create, delete |
| File Storage | puchify.fileStorage | list, get, create, delete |
| Load Balancers | puchify.loadBalancers | list, get, create, update, delete |
| VPN Gateways | puchify.vpnGateways | list, get, create, update, delete |
| NAT Gateways | puchify.natGateways | list, get, create, update, delete |
| Domains | puchify.domains | list, get, create, update, delete |
| Backups | puchify.backups | list, get, create |
| Logs | puchify.logs | list |
| Usage | puchify.usage | list |
| Observability | puchify.observability | list metrics, alerts, incidents |
| Settings | puchify.settings | get teams, get/update profile |
| Terminal | puchify.terminal | list, create |
| Agent | puchify.agent | list threads, get thread, create thread, send message |
| Webhooks | puchify.webhooks | list, get, create, update, delete |
| API Keys | puchify.apiKeys | list, create, revoke |
| Apple Silicon | puchify.appleSilicon | list, get, create, update, delete |
| Elastic Metal | puchify.elasticMetal | list, get, create, update, delete |
| Block Storage | puchify.blockStorage | list, get, create, update, delete |
| Public Gateways | puchify.publicGateways | list, get, create, update, delete |
| VPC | puchify.vpc | list, get, create, update, delete |
| Edge Services | puchify.edgeServices | list, get, create, update, delete |
| Container Registry | puchify.containerRegistry | list, get, create, update, delete |
| Support Cases | puchify.support | list, get, create, update, delete |
Pagination
Two patterns for iterating over paginated lists:
Async generator
for await (const server of puchify.servers.listAll({ status: "running" })) {
console.log(server.name)
}Manual pagination
import { paginate, collectAll } from "@puchify/sdk"
// Stream one at a time
const gen = paginate<Server>((cursor) =>
puchify.servers.list({ cursor, limit: 100 }),
)
// Collect into array
const all = await collectAll((cursor) =>
puchify.servers.list({ cursor, limit: 100 }),
)Polling & waiting
Block until a resource reaches a desired state:
const server = await puchify.servers.waitFor(
"svr_abc123",
"running",
{ timeout: 120_000, pollInterval: 3_000 },
)Throws if the resource enters a terminal error state or the timeout elapses.
Retry
Wrap any call with exponential backoff for transient failures:
import { withRetry } from "@puchify/sdk"
const result = await withRetry(
() => puchify.servers.get("svr_abc123"),
{ maxAttempts: 5, baseDelay: 500 },
)Retries on HTTP 429 and 5xx errors only.
Error handling
Every error is an instance of PuchifyError with code and status properties:
import { NotFoundError, RateLimitError, AuthError, ValidationError } from "@puchify/sdk"
try {
await puchify.servers.get("nonexistent")
} catch (err) {
if (err instanceof NotFoundError) {
console.log("Server not found:", err.message)
}
if (err instanceof RateLimitError) {
console.log("Rate limited, status:", err.status)
}
// err.code -> "not_found"
// err.status -> 404
}| Error | HTTP Status | Code |
|-------|-------------|------|
| PuchifyError | — | api_error |
| AuthError | 401 | auth_error |
| NotFoundError | 404 | not_found |
| ValidationError | 400 | validation_error |
| RateLimitError | 429 | rate_limited |
Webhooks
Verify incoming webhook payloads with constant-time comparison:
import { verifyWebhookSignature } from "@puchify/sdk"
function handleWebhook(req: Request) {
const raw = await req.text()
const signature = req.headers.get("puchify-signature") ?? ""
const valid = verifyWebhookSignature(raw, signature, process.env.WEBHOOK_SECRET!)
if (!valid) throw new Error("Invalid signature")
const payload = JSON.parse(raw)
console.log(`Webhook ${payload.type} received`)
}Configuration
const puchify = new Puchify({
apiKey: "pk_...",
baseUrl: "https://api.puchify.com", // default, override for custom domains
})