Skip to content

Webhooks are the production-grade way to know when a post completed or failed — beats polling getStatus every few seconds.

How it works

  1. You register an HTTPS endpoint with events you care about
  2. Socifyr POSTs a JSON payload to that endpoint every time a matching event fires
  3. Your endpoint validates the HMAC signature and reacts
  4. 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

AttemptDelay
1Immediate
230 seconds
35 minutes
430 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 200 immediately 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-Delivery as 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:3000

Then register the tunneled URL as your webhook endpoint.