Docs/Webhooks

Webhooks

Lors de l'utilisation de delivery_mode: webhook, Apertur envoie les images par POST à votre point de terminaison dès qu'elles sont traitées.

En-têtes de requête

En-têteDescription
X-Aptr-SignatureSignature HMAC-SHA256 du corps de la requête
X-Aptr-Session-IdL'identifiant de la session d'envoi
X-Aptr-Image-IndexIndex basé sur 0 de cette image dans la session
X-Aptr-Image-IdIdentifiant unique de l'image
Content-TypeDépend du format : multipart/form-data, application/json ou application/octet-stream

Formats de webhook

multipart(par défaut)

L'image est envoyée sous forme de POST multipart/form-data. Le nom du champ de fichier est image. Les tags de la session sont inclus comme champs de formulaire additionnels.

Content-Type: multipart/form-data; boundary=----AptrBoundary

------AptrBoundary
Content-Disposition: form-data; name="image"; filename="photo.jpg"
Content-Type: image/jpeg

<binary image data>
------AptrBoundary
Content-Disposition: form-data; name="user_id"

usr_abc123
------AptrBoundary--

json_base64

L'image est encodée en base64 et incluse dans un corps JSON avec les métadonnées et les tags.

{
  "session_id": "sess_01HX...",
  "image_id": "img_01HX...",
  "image_index": 0,
  "mime_type": "image/jpeg",
  "filename": "photo.jpg",
  "size_bytes": 245000,
  "data": "base64-encoded-image-data...",
  "tags": {
    "user_id": "usr_abc123"
  }
}

binary

Les octets bruts de l'image sont envoyés comme corps de la requête avec Content-Type: application/octet-stream. Les métadonnées ne sont disponibles que dans les en-têtes.

Vérification de la signature HMAC

Chaque requête de webhook inclut un en-tête X-Aptr-Signature. La valeur est sha256=&lt;hex-digest&gt; calculée sur le corps brut de la requête à l'aide du secret webhook de votre projet.

Trouvez votre secret webhook dans Tableau de bord → Projet → Paramètres.

const crypto = require("crypto");

function verifySignature(body, signatureHeader, secret) {
  const expected = "sha256=" +
    crypto.createHmac("sha256", secret).update(body).digest("hex");
  return crypto.timingSafeEqual(
    Buffer.from(expected, "utf8"),
    Buffer.from(signatureHeader, "utf8")
  );
}

// Express.js example
app.post("/webhook", express.raw({ type: "*/*" }), (req, res) => {
  const sig = req.headers["x-aptr-signature"];
  if (!verifySignature(req.body, sig, process.env.APTR_WEBHOOK_SECRET)) {
    return res.status(401).send("Invalid signature");
  }
  // Process image...
  res.status(200).end();
});

Note de sécurité

Lisez toujours le corps brut de la requête avant de le parser. Parser d'abord (par exemple, avec un middleware JSON) peut altérer les octets du corps et faire échouer la vérification de la signature.

Politique de nouvelles tentatives

Une livraison de webhook est considérée comme échouée si votre serveur retourne un code de statut non-2xx ou ne répond pas dans les 30 secondes. Les livraisons échouées sont retentées avec un délai exponentiel :

TentativeDélai après la précédente
1re nouvelle tentative30 secondes
2e nouvelle tentative5 minutes
3e nouvelle tentative30 minutes
4e nouvelle tentative2 heures
5e nouvelle tentative6 heures

Des tentatives supplémentaires continuent jusqu'à l'épuisement du nombre maximal de jours de nouvelles tentatives de votre plan. Lorsque toutes les tentatives échouent, vous recevez un courriel de notification d'échec.