Webhooks: gebeurtenissen, payloads en handtekeningen

Met webhooks kunnen je eigen systemen reageren zodra Inwista klaar is met het werk: wanneer een transcriptie is afgerond of een video-export is gerenderd, POST Inwista een ondertekende JSON-gebeurtenis naar een HTTPS-endpoint dat jij beheert. Gebruik het voor publicatiepipelines, archiefsystemen, projecttools — alles wat automatisch moet gebeuren nadat Inwista klaar is.

Instellen en het ondertekeningsgeheim

Koppel onder My workspaceIntegrations de Webhooks-kaart en voer je endpoint-URL in (HTTPS vereist). Inwista genereert een ondertekeningsgeheim met het voorvoegsel whsec_ en toont het precies één keer — sla het meteen op in je secret manager. Je kunt het geheim op elk moment roteren vanuit de integratie-instellingen; het oude werkt onmiddellijk niet meer.

Gebruik Send test event in de instellingen om een ondertekende webhook.test-gebeurtenis naar je endpoint te sturen en de koppeling te bevestigen vóór echt verkeer. Verander je de endpoint-URL later, dan blijft hetzelfde geheim behouden.

Gebeurtenissen

  • transcript.completed Wordt één keer per project verstuurd, wanneer de eerste transcriptie klaar is. Bevat downloadlinks voor de transcriptiebestanden in de formaten die op de integratie zijn geconfigureerd.
  • export.completed Wordt verstuurd telkens wanneer een video-export klaar is met renderen. Bevat de gerenderde video plus verse transcriptiebestanden die eventuele ondertitelbewerkingen van na de transcriptie weerspiegelen.
  • webhook.test Wordt handmatig verstuurd vanuit de integratie-instellingen, om je ontvanger te verifiëren.

Beide gebeurtenistypen zijn onafhankelijk van elkaar aan en uit te zetten in de integratie-instellingen. Gebeurtenissen worden bij elke geabonneerde gelegenheid verstuurd, ongeacht opslagkeuzes per export — webhooks zijn meldingen, geen leveringsbestemmingen.

Payload

Elke gebeurtenis deelt dezelfde envelop: een event-type, een uniek id voor deduplicatie, een Unix-timestamp, het workspaceId en een project-blok. Bestandsdragende gebeurtenissen voegen een files-array toe; export.completed bevat ook een video-object.

{
  "event": "export.completed",
  "id": "evt_9c1b7e2a4f0d4b6e8a12",
  "timestamp": 1784034017,
  "workspaceId": "UK6naH1L1sMtzTVcVZih",
  "project": {
    "id": "abc123def456",
    "name": "Interview — Aflevering 12",
    "language": "nl",
    "durationSeconds": 1834
  },
  "files": [
    {
      "format": "srt",
      "name": "Interview — Aflevering 12.srt",
      "mimeType": "application/x-subrip",
      "url": "https://storage.googleapis.com/...signed...",
      "expiresAt": 1784120417
    }
  ],
  "video": {
    "name": "Interview — Aflevering 12.mp4",
    "mimeType": "video/mp4",
    "sizeBytes": 812340221,
    "url": "https://storage.googleapis.com/...signed...",
    "expiresAt": 1784120417
  }
}

De url-waarden zijn ondertekende downloadlinks die 24 uur geldig zijn (het Unix-tijdstempel expiresAt zegt precies wanneer) — haal meteen op wat je nodig hebt in plaats van de links te bewaren. transcript.completed heeft dezelfde vorm, alleen zonder het video-object.

Handtekeningen verifiëren

Elk verzoek draagt drie headers: X-Inwista-Event (het gebeurtenistype), X-Inwista-Delivery (het gebeurtenis-ID) en X-Inwista-Signature — een HMAC-SHA256 van de rauwe request-body, berekend met jouw ondertekeningsgeheim. Bereken hem opnieuw en vergelijk voordat je de payload vertrouwt; zonder deze controle kan iedereen die je endpoint-URL ontdekt je valse gebeurtenissen voeren.

const crypto = require("crypto");

function verifyInwistaSignature(rawBody, signatureHeader, secret) {
  const expected =
    "sha256=" +
    crypto.createHmac("sha256", secret).update(rawBody).digest("hex");
  return (
    signatureHeader.length === expected.length &&
    crypto.timingSafeEqual(
      Buffer.from(signatureHeader),
      Buffer.from(expected),
    )
  );
}

// Express example — capture the raw body for verification:
// app.post("/inwista-hook", express.raw({ type: "application/json" }), (req, res) => {
//   if (!verifyInwistaSignature(req.body, req.get("X-Inwista-Signature"), process.env.INWISTA_WEBHOOK_SECRET)) {
//     return res.status(401).end();
//   }
//   const event = JSON.parse(req.body);
//   res.status(200).end(); // acknowledge fast, process async
// });

Belangrijk: bereken de HMAC over de rauwe request-body, niet over een opnieuw geserialiseerde versie van de geparseerde JSON — verschillen in sleutelvolgorde en witruimte breken de vergelijking.

Levering, herpogingen en deduplicatie

  • Bevestig met 2xx Antwoord binnen 10 seconden. Doe zware verwerking asynchroon na de bevestiging — een traag antwoord telt als een mislukking.
  • Herpogingen Mislukte leveringen worden tot twee keer opnieuw geprobeerd (ongeveer 10 en 30 seconden later). Antwoorden in het 4xx-bereik worden als permanent behandeld en niet opnieuw geprobeerd, met uitzondering van 408 en 429.
  • Dedupliceer op id Als je server een verzoek accepteert maar het antwoord verloren gaat, kan een herpoging dezelfde gebeurtenis twee keer afleveren. Het id-veld blijft stabiel over herpogingen — gebruik het om duplicaten te negeren.
  • Automatische pauze Na 10 opeenvolgende mislukte leveringen pauzeert Inwista het endpoint en toont waarom in de integratie-instellingen, waar je kunt hervatten zodra je ontvanger is gerepareerd. De status en HTTP-code van de laatste levering zijn daar altijd zichtbaar.