Facultatif. À chaque validation, retouche, remise en ligne ou retrait d'un article, takotak fait un POST JSON sur l'adresse réglée dans l'espace client (Réglages des articles › Publication), sans suivre de redirection, et attend la réponse 20 secondes.
Le message dit seulement quel article a changé. Lisez-le ensuite par l'API, toujours dans son dernier état : une notification en retard ou dans le désordre ne vous fait jamais publier une version périmée.
La notification
{
"id": "6f1c2c0e-8f3a-4c1d-9b7e-2a5d9c4e1f00",
"event": "article.published",
"version": "2026-09-19",
"sentAt": "2026-09-22T07:12:41.000Z",
"site": "mon-site.fr",
"attempt": 1,
"article": {
"id": "17704761-f25c-40a0-a8d3-02d4e5808a8a",
"slug": "osteopathe-reprise-sport-vienne",
"title": "Ostéopathe reprise sport Vienne : prévenir les blessures",
"updatedAt": "2026-09-15T09:02:11.410Z",
"url": "https://app.takotak.ai/api/v1/articles/17704761-f25c-40a0-a8d3-02d4e5808a8a",
"replaces": null
}
}
| Événement | Ce qu'il veut dire |
|---|---|
article.published |
Un article est en ligne : validé, remis en ligne ou retouché. Même article.id à chaque fois : mettez à jour au lieu de créer. Avec article.replaces.url, c'est la mise à jour d'une page déjà en ligne : remplacez le contenu de la page qui porte ce slug, retrouvée par ce slug et jamais par l'id (une page remise à jour une seconde fois arrive sous un autre id) (voir Mise à jour d'un article déjà en ligne). |
article.removed |
L'article est retiré ; article.url est absent. Dépubliez-le, ne l'effacez pas : un article retiré peut revenir par un nouvel article.published. Un article supprimé, ou réécrit avant une nouvelle validation, arrive par le même événement. |
article.test |
Envoyé depuis les réglages. Son article.url mène à un article témoin, lisible par l'API avec votre clé : de quoi vérifier tout le branchement. Traitez-le comme un brouillon. |
Les en-têtes
| En-tête | Contenu |
|---|---|
Content-Type |
application/json |
User-Agent |
takotak-webhook/2 |
X-Takotak-Event |
article.published, article.removed ou article.test |
X-Takotak-Delivery |
Identifiant unique de cet envoi, le même que id dans le corps. |
X-Takotak-Signature |
t=<secondes Unix>,v1=<HMAC-SHA256 en hexadécimal> |
La réponse attendue
Un statut 2xx accepte l'envoi. Facultatif : un corps JSON { "url": "https://www.mon-site.fr/blog/…" } avec l'adresse publique de l'article, affichée dans l'espace client.
Tout autre statut, ou l'absence de réponse, est journalisé et retenté automatiquement après 1 min, 5 min, 30 min, 2 h puis 6 h. L'espace client permet aussi de prévenir à nouveau d'un clic.
Vérifier la signature
HMAC-SHA256, avec la clé de signature, de la chaîne t + "." + corps brut, où t est l'horodatage de l'en-tête et le corps la requête telle que reçue, avant tout décodage JSON. Refusez tout envoi dont la signature ne correspond pas ou dont l'horodatage a plus de cinq minutes.
Un build hook ne vérifie rien : il relance seulement le build, qui lit l'API avec sa clé.
Node.js
import { createHmac, timingSafeEqual } from "node:crypto";
// rawBody : le corps de la requête tel quel (chaîne), avant tout parsing JSON.
export function verify(rawBody, signatureHeader, secret) {
const parts = Object.fromEntries(signatureHeader.split(",").map((p) => p.split("=")));
const t = Number(parts.t);
if (!t || Math.abs(Date.now() / 1000 - t) > 300) return false; // plus de 5 minutes : rejouée ?
const expected = createHmac("sha256", secret).update(`${t}.${rawBody}`).digest("hex");
return expected.length === parts.v1?.length && timingSafeEqual(Buffer.from(expected), Buffer.from(parts.v1));
}
PHP
<?php
// $raw : file_get_contents('php://input'), avant json_decode.
function takotak_verify(string $raw, string $header, string $secret): bool {
$parts = [];
foreach (explode(',', $header) as $kv) { [$k, $v] = explode('=', $kv, 2) + [1 => '']; $parts[$k] = $v; }
$t = (int) ($parts['t'] ?? 0);
if (!$t || abs(time() - $t) > 300) return false;
$expected = hash_hmac('sha256', $t . '.' . $raw, $secret);
return hash_equals($expected, $parts['v1'] ?? '');
}
Pour la suite, voir les exemples complets : Next.js, build statique et WordPress.