Guide d’intégration des webhooks Screenshot API
Points de terminaison HTTPS, charge utile JSON signée, exemple Express et stratégie d’idempotence face aux relivraisons.
Pourquoi un webhook ?
Le polling depuis le navigateur ou un service court-circuité gaspille des requêtes. Avec un webhook, ScreenshotCenter appelle votre URL HTTPS lorsque le traitement est terminé — idéal pour déclencher des workflows internes, notifier la supervision ou enchaîner sur Zapier/Make après une étape intermédiaire.
Présentation produit : Webhooks. Procédure détaillée : article d’aide.
Configuration
- Tableau de bord → Apps → Connecter une nouvelle app → Webhook.
- Renseignez une URL HTTPS publique qui répond en
2xxrapidement. - Optionnel : secret de signature ; l’en-tête
X-Signaturecontient alorssha256=<HMAC>calculé sur le corps brut (voir l’aide pour le nom exact selon votre espace).
Déclencher les envois
Ajoutez l’app_id du webhook au paramètre apps sur /screenshot/create (répétable). Les lots déclenchent la même chaîne pour chaque ligne réussie.
Exemple de charge utile
{
"event": "screenshot.completed",
"screenshot_id": "abc123",
"url": "https://example.com",
"status": "done",
"image_url": "https://cdn.screenshotcenter.com/abc123.png",
"created_at": "2026-03-24T12:00:00Z"
}
Récepteur Express (Node.js, ESM)
import express from 'express';
import crypto from 'crypto';
const app = express();
const secret = process.env.WEBHOOK_SECRET ?? '';
app.post(
'/webhooks/screenshotcenter',
express.json({
verify: (req, _res, buf) => {
req.rawBody = buf;
},
}),
(req, res) => {
const sig = req.headers['x-signature'];
if (secret && typeof sig === 'string' && req.rawBody) {
const attendu =
'sha256=' +
crypto.createHmac('sha256', secret).update(req.rawBody).digest('hex');
const a = Buffer.from(attendu);
const b = Buffer.from(sig);
if (a.length !== b.length || !crypto.timingSafeEqual(a, b)) {
return res.status(401).send('signature invalide');
}
}
const { event, screenshot_id, image_url } = req.body;
console.log('webhook', event, screenshot_id, image_url);
res.sendStatus(200);
},
);
app.listen(Number(process.env.PORT) || 3000, () => {
console.log('écoute');
});
Relances et idempotence
Les échecs (timeout ou statut non 2xx) entraînent des relivraisons avec backoff. Stockez chaque screenshot_id traité avant de répondre 200 afin d’éviter les doublons.
Cas d’usage
- Traitement asynchrone des PDF longs sans bloquer votre API publique.
- Alertes opérationnelles sur les lignes en erreur d’un lot de captures.
- Pont vers Zapier ou Make via une petite couche de routage.