Integrating Webhooks
Integrating Webhooks
Adapto CMS webhooks send a signed HTTP POST to a URL you control whenever triggered from the backoffice. Use them to notify external systems — revalidation endpoints, Slack bots, build triggers, data pipelines — on demand.
Configuration
In the backoffice, go to Developer Tools → Webhooks and create a new webhook with:
- Label — an internal name for identifying the webhook
- URL — the HTTPS endpoint that will receive the POST
A signing secret is generated automatically on creation. It is shown once — copy and store it securely. The backoffice displays only a truncated version thereafter, with a copy button for the full value.
Delivery
Every delivery is an HTTP POST with Content-Type: application/json and the following body:
{
"event_type": "manual",
"tenant_id": "your-project-uuid",
"timestamp": "2024-01-15T12:00:00",
"data": {
"environment": "production",
"triggered_by": "deployment-script"
}
} data contains the key-value pairs entered in the trigger dialog.
Signature verification
Each delivery includes an adapto-signature header containing an HMAC-SHA256 signature of the raw request body, formatted as sha256={hex_digest}. Verify it on your receiving server before processing the payload:
import crypto from 'crypto';
function verifyAdaptoSignature(
rawBody: string,
secret: string,
signatureHeader: string,
): boolean {
const expected = 'sha256=' + crypto
.createHmac('sha256', secret)
.update(rawBody)
.digest('hex');
return crypto.timingSafeEqual(
Buffer.from(signatureHeader),
Buffer.from(expected),
);
}
// Express example
app.post('/webhook', express.raw({ type: 'application/json' }), (req, res) => {
const signature = req.headers['adapto-signature'] as string;
if (!verifyAdaptoSignature(req.body.toString(), process.env.WEBHOOK_SECRET!, signature)) {
return res.status(401).send('Invalid signature');
}
const payload = JSON.parse(req.body.toString());
// handle payload.data ...
res.sendStatus(200);
}); Use express.raw() (or your framework's equivalent) to access the raw bytes before any JSON parsing — the HMAC is computed over the exact bytes sent, so parsing and re-serializing first will produce a different digest.
Triggering
From the webhook list, use the Trigger button to fire a delivery immediately. The trigger dialog accepts an optional payload of typed key-value pairs (string, number, or boolean) that populate the data field in the request body.