Webhooks: händelser, payloads och signaturer

Med webhooks kan dina egna system reagera i samma stund som Inwista är klar med jobbet: när en transkribering slutförs eller en videoexport är renderad POSTar Inwista en signerad JSON-händelse till en HTTPS-endpoint du kontrollerar. Använd det för publiceringspipelines, arkivsystem, projektverktyg — allt som ska ske automatiskt efter att Inwista är klar.

Konfiguration och signeringshemligheten

Under My workspaceIntegrations, koppla Webhooks-kortet och ange din endpoint-URL (HTTPS krävs). Inwista genererar en signeringshemlighet med prefixet whsec_ och visar den exakt en gång — spara den i din hemlighetshantering direkt. Du kan rotera hemligheten när som helst från integrationsinställningarna; den gamla slutar fungera omedelbart.

Använd Send test event i inställningarna för att skicka en signerad webhook.test-händelse till din endpoint och bekräfta kopplingen innan riktig trafik. Byter du endpoint-URL senare behålls samma hemlighet.

Händelser

  • transcript.completed Skickas en gång per projekt, när den första transkriberingen är klar. Innehåller nedladdningslänkar för transkriberingsfilerna i formaten som konfigurerats på integrationen.
  • export.completed Skickas varje gång en videoexport renderats klart. Innehåller den renderade videon plus färska transkriberingsfiler som speglar eventuella undertextredigeringar gjorda efter transkriberingen.
  • webhook.test Skickas manuellt från integrationsinställningarna, för att verifiera din mottagare.

Båda händelsetyperna kan slås av och på oberoende av varandra i integrationsinställningarna. Händelser skickas vid varje prenumererad förekomst, oavsett lagringsval per export — webhooks är aviseringar, inte leveransdestinationer.

Payload

Alla händelser delar samma kuvert: en event-typ, ett unikt id för deduplicering, en Unix-timestamp, workspaceId och ett project-block. Filbärande händelser har dessutom en files-array; export.completed inkluderar också ett video-objekt.

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

url-värdena är signerade nedladdningslänkar giltiga i 24 timmar (Unix-tidsstämpeln expiresAt säger exakt när) — hämta det du behöver direkt i stället för att spara länkarna. transcript.completed har samma form, bara utan video-objektet.

Verifiera signaturer

Varje anrop har tre headers: X-Inwista-Event (händelsetypen), X-Inwista-Delivery (händelse-ID:t) och X-Inwista-Signature — en HMAC-SHA256 av den råa anropskroppen, beräknad med din signeringshemlighet. Räkna om den och jämför innan du litar på innehållet; utan denna kontroll kan vem som helst som upptäcker din endpoint-URL mata dig med falska händelser.

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
// });

Viktigt: beräkna HMAC:en över den råa anropskroppen, inte en omserialiserad version av den parsade JSON:en — skillnader i nyckelordning och mellanslag bryter jämförelsen.

Leverans, omförsök och deduplicering

  • Kvittera med 2xx Svara inom 10 sekunder. Gör tung bearbetning asynkront efter kvittensen — ett långsamt svar räknas som ett misslyckande.
  • Omförsök Misslyckade leveranser försöks om upp till två gånger till (ungefär 10 och 30 sekunder senare). Svar i 4xx-området behandlas som permanenta och försöks inte om, med undantag för 408 och 429.
  • Deduplicera på id Om din server tar emot ett anrop men svaret går förlorat kan ett omförsök leverera samma händelse två gånger. id-fältet är stabilt över omförsök — använd det för att ignorera dubbletter.
  • Automatisk paus Efter 10 misslyckade leveranser i rad pausar Inwista endpointen och visar varför i integrationsinställningarna, där du kan återuppta när din mottagare är lagad. Senaste leveransens status och HTTP-kod syns alltid där.