Skip to content

Webhooks

Webhooks push events to your HTTPS endpoint so you don’t poll. Manage them via the dashboard or the Webhooks API:

Terminal window
curl -X POST "https://api.scrapersocial.com/v1/webhooks" \
-H "Authorization: Bearer sk_live_..." \
-H "Content-Type: application/json" \
-d '{"url": "https://example.com/hooks/scrapersocial", "events": ["job.completed", "credits.low"]}'

The response includes a signing secret (whsec_...) — shown once, store it safely.

Events

EventFires when
job.completedAn async job succeeds or fails
credits.lowBalance crosses your low-credit threshold
plan.changedSubscription upgraded, downgraded, or canceled

Verify signatures

Every delivery carries x-scrapersocial-signature: t=<unix>,v1=<hex> — an HMAC-SHA256 of "{t}.{raw_body}" with your whsec_ secret:

import crypto from "node:crypto";
export function verify(rawBody, header, secret) {
const { t, v1 } = Object.fromEntries(header.split(",").map((p) => p.split("=")));
if (Math.abs(Date.now() / 1000 - Number(t)) > 300) return false; // 5 min tolerance
const expected = crypto
.createHmac("sha256", secret)
.update(`${t}.${rawBody}`)
.digest("hex");
return crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(v1));
}

Compute the HMAC over the raw request body (before JSON parsing), and reject timestamps older than a few minutes to block replays.

Delivery behavior

Deliveries expect a 2xx within 10 seconds; anything else is retried with exponential backoff for up to 24 hours. Events include an id — treat processing as idempotent.

Next: Verify-webhook recipe · Async jobs