Webhooks
Webhooks push events to your server as they happen, no polling needed.
Create a webhook
Section titled “Create a webhook”curl -X POST https://qck.sh/public-api/v1/webhooks \ -H "X-API-Key: qck_your_api_key_here" \ -H "Content-Type: application/json" \ -d '{ "url": "https://your-server.com/webhook", "events": ["link.created", "link.updated"] }'Requires webhooks:write permission.
Update a webhook
Section titled “Update a webhook”curl -X PATCH https://qck.sh/public-api/v1/webhooks/{id} \ -H "X-API-Key: qck_your_api_key_here" \ -H "Content-Type: application/json" \ -d '{"events": ["link.updated"]}'Delete a webhook
Section titled “Delete a webhook”curl -X DELETE https://qck.sh/public-api/v1/webhooks/{id} \ -H "X-API-Key: qck_your_api_key_here"Test a webhook
Section titled “Test a webhook”Send a test payload to verify your endpoint is receiving events:
curl -X POST https://qck.sh/public-api/v1/webhooks/{id}/test \ -H "X-API-Key: qck_your_api_key_here"Delivery history
Section titled “Delivery history”Check delivery status and debug failed deliveries:
curl https://qck.sh/public-api/v1/webhooks/{id}/deliveries \ -H "X-API-Key: qck_your_api_key_here"Payload format
Section titled “Payload format”{ "event": "link.created", "timestamp": "2026-04-08T12:00:00Z", "data": { ... }}Verifying signatures
Section titled “Verifying signatures”Every delivery includes these headers:
| Header | Description |
|---|---|
X-QCK-Signature | sha256=<hex>: HMAC-SHA256 of the raw request body, keyed with your endpoint secret |
X-QCK-Event | Event type (e.g. link.created) |
X-QCK-Delivery | Unique delivery ID |
Verify the signature before trusting a payload:
import crypto from 'node:crypto';
function verifyWebhook(rawBody, signatureHeader, secret) { const expected = 'sha256=' + crypto.createHmac('sha256', secret).update(rawBody).digest('hex'); return crypto.timingSafeEqual( Buffer.from(signatureHeader), Buffer.from(expected) );}The secret is returned once when you create the endpoint.
Retries
Section titled “Retries”Failed deliveries are retried up to 3 attempts with exponential backoff: 30s, then 120s, then 480s. After 10 consecutive failures, the endpoint is automatically disabled. Re-enable it from the dashboard or via PATCH /webhooks/{id} once your server is healthy.
Limits by tier
Section titled “Limits by tier”| Tier | Webhook Endpoints |
|---|---|
| Free | 1 |
| Basic ($19/mo) | 2 |
| Growth ($49/mo) | 5 |
| Pro ($99/mo) | 10 |
| Business ($249/mo) | 25 |