Webhooks
PrintStudio both sends webhooks (outbound to your systems) and receives them (inbound from Stripe and OpenClaw).
Outbound Webhooks
Section titled “Outbound Webhooks”Register an endpoint to receive events when orders and jobs change state.
Register an Endpoint
Section titled “Register an Endpoint”curl -X POST http://localhost:8787/api/webhooks/endpoints \ -H "Content-Type: application/json" \ -H "X-API-Key: your-api-key" \ -d '{ "url": "https://your-system.example.com/hooks/printstudio", "events": ["order.created", "order.shipped", "job.failed"], "secret": "your-signing-secret" }'Available Events
Section titled “Available Events”| Event | Description |
|---|---|
order.created | New order placed |
order.paid | Payment confirmed |
order.printing | Production started |
order.ready | All jobs complete |
order.shipped | Tracking assigned |
order.cancelled | Order cancelled |
job.failed | Job failed (includes error) |
job.completed | Individual job completed |
inventory.low | Material below reorder point |
printer.offline | Printer stopped responding |
Payload Format
Section titled “Payload Format”All outbound webhooks share a common envelope:
{ "id": "evt-uuid", "event": "order.shipped", "timestamp": "2024-01-15T14:30:00Z", "data": { "orderId": "ord-abc123", "trackingNumber": "1Z999AA10123456784", "carrier": "UPS", "estimatedDelivery": "2024-01-17" }}Verifying Signatures
Section titled “Verifying Signatures”Each delivery includes an X-PrintStudio-Signature header — an HMAC-SHA256 of the raw request body signed with your endpoint’s secret:
import { createHmac } from "crypto";
function verifySignature(body: string, signature: string, secret: string): boolean { const expected = createHmac("sha256", secret) .update(body) .digest("hex"); return `sha256=${expected}` === signature;}Retry Policy
Section titled “Retry Policy”Failed deliveries (non-2xx response or timeout) are retried with exponential backoff: 1 min, 5 min, 25 min, 2 h, 10 h. After 5 failures the endpoint is automatically disabled and the operator is notified.
Inbound Webhooks
Section titled “Inbound Webhooks”Stripe
Section titled “Stripe”Stripe payment events are received at POST /webhooks/stripe. The endpoint validates the Stripe signature using STRIPE_WEBHOOK_SECRET.
Handled events:
| Stripe event | Action |
|---|---|
checkout.session.completed | Mark order as paid, create jobs |
payment_intent.payment_failed | Mark order payment failed |
charge.refunded | Mark order refunded |
Use the Stripe CLI for local testing:
stripe listen --forward-to localhost:8787/webhooks/stripeOpenClaw
Section titled “OpenClaw”OpenClaw agent events are received at POST /webhooks/openclaw. This handles inbound commands from the AI skills (e.g., an operator asking the bot to pause a print):
{ "skill": "pause-print", "params": { "jobId": "job-uuid" }, "userId": "whatsapp:+15551234567"}