Aller au contenu
API Delivery
Avant de compter sur une fonctionnalité, consultez l'état des capacités.

Référence

Webhooks

Les notifications signées qu'Atlas envoie à votre site web lorsque du contenu est publié, pour rafraîchir exactement les pages concernées.

Cette page a été traduite de l'anglais. En cas de divergence, la version anglaise fait foi. Lire en anglais

Créez des webhooks dans Studio sous Integrations → Webhooks. Chacun possède une URL HTTPS, les événements qu’il reçoit et un secret de signature commençant par whsec_, affiché une seule fois.

Atlas ne livre qu’à des adresses HTTPS publiques. Les adresses de réseau privé sont refusées ; le HTTP simple n’est autorisé que vers localhost pendant le développement.

POST https://your-site.example/api/atlas/webhook
Content-Type: application/json
X-Atlas-Event: content.page.published
X-Atlas-Delivery: <unique delivery id>
X-Atlas-Signature: t=1761210000,v1=5f2b…
app/api/atlas/webhook/route.ts
import { createHmac, timingSafeEqual } from 'node:crypto';
import { revalidatePath, revalidateTag } from 'next/cache';
const seen = new Set<string>(); // use a shared store (Redis, KV) when you run several instances
export async function POST(request: Request) {
const body = await request.text(); // the raw body, before any JSON parsing
const header = request.headers.get('x-atlas-signature') ?? '';
const parts = Object.fromEntries(header.split(',').map((part) => part.split('=', 2)));
const timestamp = Number(parts.t);
if (!timestamp || Math.abs(Date.now() / 1000 - timestamp) > 300)
return new Response(null, { status: 400 });
const expected = createHmac('sha256', process.env.ATLAS_WEBHOOK_SECRET!)
.update(`${timestamp}.${body}`)
.digest();
const given = Buffer.from(String(parts.v1 ?? ''), 'hex');
if (given.length !== expected.length || !timingSafeEqual(given, expected)) {
return new Response(null, { status: 401 });
}
const delivery = request.headers.get('x-atlas-delivery') ?? '';
if (seen.has(delivery)) return new Response(null, { status: 200 }); // already handled
seen.add(delivery);
const payload = JSON.parse(body); // e.g. { pageId, route, revision } for content.page.published
if (typeof payload.route === 'string') revalidatePath(payload.route);
else revalidateTag('atlas'); // entries, globals, translations: refresh everything tagged 'atlas'
return new Response(null, { status: 200 });
}

Les vérifications, dans l’ordre :

  1. Utilisez le corps brut de la requête.
  2. Rejetez les horodatages vieux de plus de 5 minutes.
  3. Calculez HMAC-SHA256("<t>.<raw body>") avec votre secret de signature et comparez en temps constant.
  4. Ignorez les identifiants X-Atlas-Delivery répétés.

Journalisez le type d’événement et l’identifiant de livraison, jamais le corps ni le secret.

Le corps de la requête est la charge utile de l’événement. Pour content.page.published, il s’agit de { "pageId", "route", "revision" }. Le type d’événement se trouve dans l’en-tête X-Atlas-Event.

Les webhooks sont configurés une seule fois, dans Development, et reçoivent aussi les événements du site web live. Chaque charge utile contient environment : "development" ou "production", ce qui permet de les distinguer.

Événement Quand
content.page.published Une page est publiée ou restaurée par un retour arrière
content.page.unpublished Une page est retirée du site web
content.page.route.changed Une page change d’adresse (une redirection est ajoutée)
content.entry.published Une entrée de collection est publiée
content.entry.unpublished Une entrée de collection est retirée du site web
content.global.published L’en-tête, le pied de page ou un autre élément global est publié
content.translation.published Une traduction est publiée
contract.activated Un nouveau contrat de site est activé
seo.redirects.changed Les redirections changent
media.asset.uploaded Un fichier média est téléversé
form.published Un formulaire est publié
form.submission.accepted Un envoi de formulaire est accepté
lead.created Un nouveau lead arrive (identifiants uniquement, aucune donnée personnelle)
lead.merged Un lead est fusionné dans un autre (identifiants uniquement)
bot.published Un chatbot est publié

Atlas attend votre réponse jusqu’à 10 secondes et ne suit pas les redirections. Utilisez l’historique de livraison de Studio pour inspecter les charges utiles et les échecs.