Webhooks
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
- An event occurs in Scompler (for example, an app is uninstalled).
- Scompler sends an HTTP POST request to your configured webhook URL.
- App backend validates the webhook request.
- 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:
- Navigate to Settings > Developers > Apps.
- Open your app configuration.
- 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
| Field | Type | Description |
|---|---|---|
id | string (UUID) | Unique identifier of the webhook event. Can be used for idempotency and duplicate detection. |
event | string | Name of the event that triggered the webhook (e.g., app.uninstalled, posting.sent_to_publish). |
account_id | integer | Identifier of the account associated with the event. Use this to locate installation records and access tokens. |
data | object | Event-specific payload. The structure depends on the event type. |
occurred_at | string (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
- Read the raw request body (exact payload).
- Retrieve the
X-Signatureheader value. - Compute the expected HMAC using your app secret.
- Compare the computed value with the received signature.
- Reject the request if they do not match.
If validation fails, respond with:
401 Unauthorized
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 OKonly 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
| Field | Type | Description |
|---|---|---|
delete_related_data | boolean | Indicates whether your app backend should delete all related data for this account. |
installation_id | string (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
| Field | Type | Description |
|---|---|---|
posting_id | integer | The unique identifier of the posting that has been sent to publish. |
service_id | integer | The identifier of the service responsible for the posting. |