Skip to main content

Webhooks

info

Webhooks allow Scompler to notify your app backend about platform events. These events are delivered as HTTP POST requests to your configured webhook URL.

Webhooks are used when your app needs to:

  • React automatically to Scompler events – e.g., app uninstalled, posting sent to publish.
  • Keep your data in sync in real time – avoiding manual polling of the API.

How it works

  1. An event occurs in Scompler (for example, an app is uninstalled).
  2. Scompler sends an HTTP POST request to your configured webhook URL.
  3. App backend validates the webhook request.
  4. App backend processes the event.

Webhooks are delivered server-to-server and must be handled by your backend.

Configuration

To receive webhooks, follow these steps:

  1. Navigate to Settings > Developers > Apps.
  2. Open your app configuration.
  3. Set the webhook URL.

The webhook URL must:

  • Be publicly accessible.
  • Use HTTPS.
  • Accept POST requests.

Webhook payload

Webhooks are sent as JSON payloads in the request body.

{
"id": "b7f9c2d4-1c4f-4a6e-9c9b-8e2d8a6e5f21",
"event": "app.uninstalled",
"account_id": "12345",
"data": {},
"occurred_at": "2026-02-17T10:00:00Z"
}

Field reference

FieldTypeDescription
idstring (UUID)Unique identifier of the webhook event. Can be used for idempotency and duplicate detection.
eventstringName of the event that triggered the webhook (e.g., app.uninstalled, posting.sent_to_publish).
account_idintegerIdentifier of the account associated with the event. Use this to locate installation records and access tokens.
dataobjectEvent-specific payload. The structure depends on the event type.
occurred_atstring (ISO 8601)Timestamp (UTC) indicating when the event occurred in Scompler.

Security

Each webhook request includes a signature in the X-Signature header.

The signature is an HMAC-SHA256 digest of the raw request payload using the app secret as the key.

OpenSSL::HMAC.hexdigest('SHA256', app_secret, payload)

How to process webhook requests

  1. Read the raw request body (exact payload).
  2. Retrieve the X-Signature header value.
  3. Compute the expected HMAC using your app secret.
  4. Compare the computed value with the received signature.
  5. Reject the request if they do not match.

If validation fails, respond with:

401 Unauthorized
warning

Never process webhook payloads before validating the signature.

Example: Signature validation

This example demonstrates signature validation in Node.js. The same logic should be implemented in your app backend language.

import crypto from 'crypto'

function verifyWebhook(rawBody, receivedSignature, appSecret) {
const expectedSignature = crypto.createHmac('sha256', appSecret).update(rawBody).digest('hex')
return crypto.timingSafeEqual(
Buffer.from(expectedSignature, 'hex'),
Buffer.from(receivedSignature, 'hex'),
)
}

Best practices

  • Always validate webhook signatures.
  • Respond quickly (avoid long-running processing in the request thread).
  • Log webhook deliveries for debugging.
  • Implement idempotency to safely handle duplicate deliveries.
  • Return 200 OK only after successful processing.

Available webhooks

app.uninstalled

This webhook is triggered when a user uninstalls your app from their account. It allows your backend to clean up resources and stop any ongoing processes related to that installation.

{
"id": "b7f9c2d4-1c4f-4a6e-9c9b-8e2d8a6e5f21",
"event": "app.uninstalled",
"account_id": "12345",
"data": {
"delete_related_data": true,
"installation_id": "3f29b6e2-8c4a-4d5f-9b12-7a1d2f3e4b5c"
},
"occurred_at": "2026-02-17T10:00:00Z"
}

Field: data

FieldTypeDescription
delete_related_databooleanIndicates whether your app backend should delete all related data for this account.
installation_idstring (UUID)Identifier of the specific installation being uninstalled.

posting.sent_to_publish

This webhook is triggered when a posting is successfully sent to be published. This event helps you track when an article is moved to the publishing stage.

{
"id": "b7f9c2d4-1c4f-4a6e-9c9b-8e2d8a6e5f21",
"event": "posting.sent_to_publish",
"account_id": "12345",
"data": {
"posting_id": 12345,
"service_id": 12345
},
"occurred_at": "2026-02-17T10:00:00Z"
}

Field: data

FieldTypeDescription
posting_idintegerThe unique identifier of the posting that has been sent to publish.
service_idintegerThe identifier of the service responsible for the posting.