Skip to main content
A webhook endpoint is an HTTPS URL on your server. SocialAPI sends it a signed JSON POST each time an event you subscribed to occurs: a new comment, direct message (DM), mention, or review, a post changing state, or a connected account changing connection state. Webhooks replace polling each platform for new activity. Managing endpoints costs no credits. Each event, its platforms, and its payload are on Webhook events. While your SocialAPI account is past due, SocialAPI delivers no events (see Past-due accounts).

Endpoints

You can also manage endpoints in the dashboard under Webhooks.

Register an endpoint

Subscribe an endpoint to 3 events:
Response (HTTP 201):
The secret is a 64-character string. It is returned once, in this response. GET /v1/webhooks/{id} returns only a hint made of whsec_... and the last 4 characters. To replace a lost secret, register a new endpoint and delete the old one. SocialAPI does not call your URL when you register it, so registration succeeds even when the server is not running. Send a test delivery to check the endpoint. An invalid request returns 400 validation.field_required (no url), 400 validation.field_invalid (url is not an HTTPS URL, events is empty, or an event name is unknown), or 400 validation.body_invalid (the body is not valid JSON). An endpoint receives events for every connected account and brand of your SocialAPI account. There is no filter by account or brand: route each event with the brand_id it carries (see Route events by brand).

What SocialAPI sends

Every delivery is a POST with a JSON body that holds an event name and a data value: an object, except an array on a mention.received event sent when you list mentions (see the event envelope). These headers are on every request:

Verify signatures

Verify X-SocialAPI-Signature-V2 on every request before you act on it. The signature proves the request came from SocialAPI and that nobody changed the body. Follow these rules:
  1. Read the raw request body. Do not parse it and serialize it again, because that changes the bytes.
  2. Use the endpoint secret exactly as returned, as the key. Do not decode it from hex.
  3. Compute the HMAC-SHA256 of the timestamp header value, a literal ., and the raw body. Prefix the hex digest with sha256=.
  4. Compare it with X-SocialAPI-Signature-V2 in constant time.
  5. Reject the request when the timestamp is more than 5 minutes from your clock (see Replay protection).
Use a constant-time comparison (timingSafeEqual, compare_digest, hmac.Equal, hash_equals). A plain string comparison leaks timing information. X-SocialAPI-Signature (v1) is the HMAC-SHA256 of the raw body alone, prefixed with sha256=. It is kept for existing integrations. It proves authenticity but not freshness, so a captured request still verifies later.

Replay protection

X-SocialAPI-Signature-V2 covers the timestamp, so an attacker cannot move a captured request into a later time window by editing the header. Reject any request whose X-SocialAPI-Timestamp is more than 5 minutes from your clock. The timestamp is the time of the attempt, so a retry of an old event carries a new timestamp and passes the check. To process each event once, store the X-SocialAPI-Delivery IDs you handled and skip repeats. A manual retry (POST .../retry) creates a new delivery with a new ID, so also deduplicate on the event’s own identity: data.id for comment and DM events, data.id or each data[].id for mention.received, and data.post_id with the event name for post events.

Respond to a webhook

Your endpoint must return an HTTP 2xx status within 10 seconds. Any other status, a timeout, or a connection error counts as a failed attempt. Return 200 once you have stored the body, and do the real work afterward. SocialAPI delivers each event at least once. The same event can arrive more than once, and events can arrive in a different order than they happened. Make your handler idempotent, and read the current state from the API when order matters. While an endpoint’s is_active is false, SocialAPI sends it nothing. It does not send those events later when you turn the endpoint on again. To recover what you missed, read GET /v1/events (within your plan’s event history) or the inbox and post endpoints.

Retries

A failed attempt is retried until the delivery has used 10 attempts. The wait before each retry grows, so an endpoint that recovers within about 14 hours of the first attempt still receives the event: Each wait varies by up to 10 percent either way. After the tenth failed attempt, about 14 hours after the first, the delivery’s status becomes failed and SocialAPI makes no further attempts. Send a failed delivery again yourself with POST /v1/webhooks/{id}/deliveries/{did}/retry. A retried event can arrive hours after events that happened later. Order events by their own timestamps, not by arrival. When an attempt ends in a connection error, a 429, or a 5xx other than 501, SocialAPI sends the same request one more time within the same attempt. Your endpoint can therefore receive the same delivery twice, seconds apart. Both requests carry the same X-SocialAPI-Delivery.

Manage endpoints

List your endpoints:
Response (HTTP 200):
GET /v1/webhooks/{id} returns the same fields plus secret_hint and delivery counts:
Change an endpoint with PATCH. Send at least 1 of url, events, and is_active. events replaces the whole list. The url and events rules are the same as at registration, and a body with no fields returns 400 validation.body_invalid.
The response (HTTP 200) is the updated endpoint, in the shape of the list items. Delete an endpoint:
Response (HTTP 200):
Deleting stops future deliveries. A delivery already in progress can still reach your URL once. An unknown endpoint ID returns 404 resource.not_found.

Monitor deliveries

SocialAPI records every delivery with its status, the HTTP status of your response, and how long your endpoint took. A delivery’s status is pending (not finished), delivered (your endpoint returned 2xx), or failed (10 attempts used).
Response (HTTP 200):
count is the number of deliveries that match the filters across all pages. next_cursor is absent on the last page. Deliveries are sorted newest first. GET /v1/webhooks/{id}/deliveries/{did} returns the delivery with the exact payload that was sent and every attempt:
Each attempt holds the first 10,240 bytes of your response body. An attempt that ended in a connection error has an error_message in place of a response. The example payload is shortened. The real one is the full body that was sent. POST /v1/webhooks/{id}/deliveries/{did}/retry creates a new delivery with the same event and payload and the description Retry of {did}. It returns the new delivery with status pending. The new delivery gets 10 attempts of its own. The original delivery is unchanged. SocialAPI keeps deliveries for the number of days your plan allows (see History and export allowances).

Test an endpoint

POST /v1/webhooks/{id}/test sends one request to the endpoint and returns the result. You choose the event name and the body:
Response (HTTP 200):
SocialAPI sends payload exactly as you give it, as the request body. It does not wrap it. The request carries the signature headers and X-SocialAPI-Event set to event_type, but no X-SocialAPI-Delivery. status is delivered for a 2xx response and failed otherwise, and response_status_code is 0 when the connection failed. SocialAPI does not retry a failed test. The delivery appears in the delivery list with the description Test delivery. event_type and payload are both required (400 validation.field_required). event_type can be any string, including names that are not subscribable.

Security

  • Verify every signature with X-SocialAPI-Signature-V2 and reject stale timestamps.
  • Keep the secret out of source control. Store it in an environment variable or a secret manager.
  • Use HTTPS only. SocialAPI rejects any other scheme at registration.
  • Return 200 fast and process afterward, to avoid timeouts and duplicate retries.
  • Make handlers idempotent. SocialAPI delivers each event at least once.
  • Rotate by replacement. There is no rotate call: register a new endpoint, switch your handler to its secret, then delete the old endpoint.

Platform support

Which platforms emit each event is listed under the event on Webhook events. Platforms that push nothing to SocialAPI have no comment, DM, mention, or review events: read those with the inbox endpoints.

Limits

Errors and debugging

When an event does not arrive, check in this order:
  1. Endpoint state. GET /v1/webhooks/{id} must show is_active: true and the event name in events. An event is delivered only to endpoints subscribed to it when it occurs.
  2. Past due. While your SocialAPI account is past due, SocialAPI sends no events and records no deliveries. Calls to the API return 402 billing.past_due.
  3. Platform support. Check Emitted for under the event on Webhook events. A platform that does not emit the event never sends it.
  4. Deliveries. GET /v1/webhooks/{id}/deliveries?status=failed lists failures. Read the attempts of one delivery: status_code is your endpoint’s response, and error_message explains a connection error or timeout.
  5. Signature. When your handler returns 401 on every request, check that you hash the raw body, key the HMAC with the secret string as returned, and compare against X-SocialAPI-Signature-V2.
  6. Test. Send POST /v1/webhooks/{id}/test to separate your endpoint’s behavior from SocialAPI’s event delivery.
Other codes on these endpoints: 401 auth.invalid_key and its siblings for a missing or invalid key, 403 auth.insufficient_scope when the key lacks webhooks:manage, and 404 resource.not_found for an unknown endpoint or delivery. Every code is in Errors.

Scopes

A brand-restricted key is refused these endpoints with 403 auth.insufficient_scope, even when it holds webhooks:manage, because endpoints belong to your SocialAPI account and not to one brand. See Scoped API keys.

Use from an AI agent

See MCP tools for the full list.
  • Webhook events: every event, its platforms, and its payload.
  • Track post delivery: the post statuses and target errors that the post.* events report.
  • Scoped API keys: restrict a key to webhooks:manage for a webhook-only integration.
  • Plans and usage: delivery history length, and what happens while an account is past due.
  • Errors: every error code and how to handle it.
  • Automations: answer Instagram and Facebook comments and DMs without running a webhook handler.
Last modified on October 19, 2026