Webhooks are the production-grade way to know when a post completed or failed — beats polling getStatus every few seconds.
How it works
- You register an HTTPS endpoint with
eventsyou care about - Socifyr POSTs a JSON payload to that endpoint every time a matching event fires
- Your endpoint validates the HMAC signature and reacts
- Socifyr retries failed deliveries 3 times with exponential backoff
Quick setup
typescript
const hook = await socifyr.webhooks.create({
url: 'https://myapp.com/webhooks/socifyr',
events: ['upload.completed', 'upload.failed', 'upload.partial_failure'],
secret: 'whsec_my_signing_secret',
})bash
curl -X POST https://api.socifyr.com/api/webhooks \
-H "Authorization: Bearer sk_..." \
-H "X-Workspace-Id: <workspaceId>" \
-H "Content-Type: application/json" \
-d '{
"url": "https://myapp.com/webhooks/socifyr",
"events": ["upload.completed", "upload.failed"],
"secret": "whsec_..."
}'Receiving an event
Every delivery is a POST with these headers:
http
Content-Type: application/json
X-Socifyr-Event: upload.completed
X-Socifyr-Signature: t=1715731000,v1=<hex_signature>
X-Socifyr-Delivery: <uuid>And a JSON body. See Events for the payload shape per event.
Retries
| Attempt | Delay |
|---|---|
| 1 | Immediate |
| 2 | 30 seconds |
| 3 | 5 minutes |
| 4 | 30 minutes |
After 4 attempts, the delivery is marked failed and you can inspect it via webhooks.deliveries().
A delivery is considered successful if your endpoint returns any 2xx status within 10 seconds. Any other response (including timeouts) triggers a retry.
Best practices
- Respond fast. Return
200immediately and process async — anything over 10s times out. - Verify signatures. Don't trust the body without checking the HMAC; see Signatures.
- Idempotency. The same event can arrive multiple times due to retries — use
X-Socifyr-Deliveryas a dedup key. - One endpoint, many events. Subscribe one webhook to multiple events; switch on
X-Socifyr-Event.
Testing locally
For local development, expose your dev server with a tunnel:
bash
# ngrok
ngrok http 3000
# cloudflared
cloudflared tunnel --url http://localhost:3000Then register the tunneled URL as your webhook endpoint.