How to set up and verify webhooks
Create an endpoint with POST /api/webhooks, subscribe it to the events you need, and verify the X-Webhook-Signature header on every delivery. Socifyr then calls your URL when a post finishes or a single platform succeeds or fails, so you stop polling.
Webhooks are a Business plan feature. See limits for the endpoint cap. On other plans, creating a webhook returns Webhooks are not available on your current plan. Upgrade to Business to continue.
How do I create a webhook?
The dashboard has no webhook screen. Create and manage webhooks with the
REST API or the TypeScript SDK.The CLI has no webhook commands.const hook = await socifyr.webhooks.create({
url: 'https://myapp.com/webhooks/socifyr',
events: ['upload.completed', 'upload.partial_failure', 'platform.failed'],
description: 'Content pipeline',
})
console.log(hook.id, hook.secret) // the secret is shown once: store it nowNo webhook management in the Python SDK. Create the endpoint with REST or the
TypeScript SDK. Python can verify signatures: see below.curl -X POST https://api.socifyr.com/api/webhooks \
-H "Authorization: Bearer $SOCIFYR_API_KEY" \
-H "X-Workspace-Id: $SOCIFYR_WORKSPACE_ID" \
-H "Content-Type: application/json" \
-d '{
"url": "https://myapp.com/webhooks/socifyr",
"events": ["upload.completed", "upload.partial_failure", "platform.failed"],
"description": "Content pipeline"
}'No webhook tools. The MCP server cannot create or read webhooks, and a key
with guardrails cannot call the webhook routes at all.Response (secret shown once, masked on later reads):
{
"success": true,
"data": {
"id": "6a05300000000000000000cc",
"url": "https://myapp.com/webhooks/socifyr",
"secret": "9f2c...64 hex characters...",
"events": ["upload.completed", "upload.partial_failure", "platform.failed"],
"active": true,
"description": "Content pipeline",
"createdAt": "2026-11-13T09:00:00.000Z",
"updatedAt": "2026-11-13T09:00:00.000Z"
}
}The five events are upload.completed, upload.failed, upload.partial_failure, platform.success and platform.failed. Payloads for each are in webhook payloads.
How do I verify the signature?
Socifyr signs the raw request body with HMAC-SHA256 using your webhook secret and sends X-Webhook-Signature: sha256=<hex>. Compare against the raw bytes, not a re-serialized object.
import express from 'express'
import { verifyWebhookSignature, parseWebhookEvent } from '@socifyr/sdk'
const app = express()
app.post('/webhooks/socifyr', express.raw({ type: 'application/json' }), (req, res) => {
const ok = verifyWebhookSignature(
req.body,
req.headers['x-webhook-signature'] as string,
process.env.SOCIFYR_WEBHOOK_SECRET!,
)
if (!ok) return res.status(401).send('Invalid signature')
const event = parseWebhookEvent(req.body)
if (event.event === 'platform.failed') {
console.warn('Failed on', event.payload)
}
res.sendStatus(200)
})import os
from flask import Flask, request, abort
from socifyr import verify_webhook_signature
app = Flask(__name__)
@app.post("/webhooks/socifyr")
def hook():
ok = verify_webhook_signature(
request.get_data(), # raw bytes
request.headers.get("X-Webhook-Signature", ""),
os.environ["SOCIFYR_WEBHOOK_SECRET"],
)
if not ok:
abort(401)
event = request.get_json()
return "", 200More languages and the manual HMAC code are in Verifying signatures.
How do I check that deliveries are arriving?
curl https://api.socifyr.com/api/webhooks/6a05300000000000000000cc/deliveries \
-H "Authorization: Bearer $SOCIFYR_API_KEY"const deliveries = await socifyr.webhooks.deliveries('6a05300000000000000000cc')You get the last 50 attempts with status, statusCode and attempts. Failed deliveries retry up to 5 times with exponential backoff starting at 10 seconds. Respond with a 2xx quickly and do heavy work after.
How do I pause or delete a webhook?
await socifyr.webhooks.update('6a05300000000000000000cc', { active: false })
await socifyr.webhooks.delete('6a05300000000000000000cc')REST: PATCH /api/webhooks/:id with { "active": false }, and DELETE /api/webhooks/:id.
What errors can I get, and how do I fix them?
| Error | Status | Fix |
|---|---|---|
Webhooks are not available on your current plan. Upgrade to Business to continue. | 403 | Upgrade, or poll status. |
| Maximum of N webhook endpoints allowed on your plan | 400 | Delete an endpoint first. |
Validation error on url | 400 | Use an http or https URL with a top-level domain. |
This API key has guardrails and cannot call this endpoint ... | 403 | Use a session or an unrestricted key. |
| Your handler returns 401 for every delivery | n/a | You verified against a parsed body. Use the raw body and the right secret. |
FAQ
Can I choose the signing secret?
No. The server generates it. To rotate, delete the endpoint and create a new one.
Why does one post send several events?
platform.success and platform.failed fire per account as each finishes. The upload.* events fire once when the whole post ends. Subscribe only to what you handle.