Zum Inhalt springen

Fileverity-API-Dokumentation

Webhooks

Empfangen Sie die Ereignisse analysis.completed, analysis.failed und balance.low. Signaturprüfung nach Standard Webhooks in JavaScript und Python, Wiederholungen, automatisches Deaktivieren und das Testereignis.

Als Markdown ansehenAktualisiert am 2026-11-04

Webhooks senden eine HTTPS-Anfrage an Ihren Server, sobald etwas passiert, sodass Sie nicht abfragen müssen. Sie folgen der Spezifikation Standard Webhooks.

Fügen Sie Endpunkte in der Konsole unter Webhooks hinzu. Wählen Sie die URL und die Ereignisse, die an sie gesendet werden. Das Signing-Secret, das mit whsec_ beginnt, wird beim Erstellen des Endpunkts einmalig angezeigt. Die Ereignisse eines Endpunkts können Sie jederzeit ändern, ohne sein Secret zu ändern.

Um ein verlorenes oder bekannt gewordenes Secret zu ersetzen, wählen Sie beim Endpunkt Secret erneuern. Das neue Secret wird einmalig angezeigt, und das alte funktioniert sofort nicht mehr. Aktualisieren Sie deshalb umgehend Ihre Signaturprüfung.

  • Die URL muss HTTPS am Standardport 443 verwenden und auf eine öffentliche Adresse zeigen. URLs mit Zugangsdaten oder einem anderen Port werden abgelehnt.
  • Ein Workspace kann bis zu 10 Endpunkte haben.
  • Testschlüssel senden nie Ereignisse.

Ereignisse

EreignisGesendet, wenn
analysis.completedEine Bild- oder Dokumentanalyse war erfolgreich.
analysis.failedEine Analyse ist fehlgeschlagen oder wurde abgebrochen. Sie wurde nicht berechnet. Eine abgebrochene Analyse hat status: canceled und error: canceled.
balance.lowDas Guthaben ist unter die Warnschwelle gefallen, die Sie in der Konsole festgelegt haben.

Die unterstützten Ereignistypen sind analysis.completed, analysis.failed, balance.low.

Nutzdaten

Jedes Ereignis hat denselben Aufbau: id, object (immer event), type, created (Unix-Zeitstempel) und data. Die id wird auch im Header webhook-id gesendet.

analysis.completed und analysis.failed

data ist dasselbe Analyseobjekt, das GET /analyses/{id} zurückgibt, mit denselben Feldnamen und Typen, nur dass result immer null ist: Rufen Sie das Ergebnis über diesen Endpunkt ab. status ist succeeded, failed oder canceled, und error ist ein Objekt mit code und message oder null. Zeitstempel sind in Unix-Sekunden angegeben.

{  "id": "evt_Lm8sK3tR6yZ2cXaQ9vB4nP1w",  "object": "event",  "type": "analysis.completed",  "created": 1793700131,  "data": {    "id": "an_8Hk2pQ4vN9sL1xR7cW3mY6zB",    "object": "analysis",    "created": 1793700120,    "model": "fvimg-2-2026-10-30",    "livemode": true,    "status": "succeeded",    "file": {      "name": "claim-photo.jpg",      "bytes": 2481920,      "format": "jpeg"    },    "report_id": "FV-7K2M-9QXD-4T8R",    "report_url": "https://fileverity.com/verify/FV-7K2M-9QXD-4T8R",    "summary": {      "level": "L2",      "assessment": "authentic_untouched",      "action": "accept",      "ai": "very_low",      "edit": "none"    },    "result": null,    "error": null,    "progress": null,    "usage": {      "amount": 199,      "currency": "usd",      "funding": "balance"    },    "metadata": {      "order_id": "A-10492"    },    "completed_at": 1793700131,    "expires_at": 1794304931  }}
{  "id": "evt_Zc4vB7nP1sK8tL3wR6yQm2Xa",  "object": "event",  "type": "analysis.failed",  "created": 1793700131,  "data": {    "id": "an_8Hk2pQ4vN9sL1xR7cW3mY6zB",    "object": "analysis",    "created": 1793700120,    "model": "fvimg-2-2026-10-30",    "livemode": true,    "status": "failed",    "file": {      "name": "claim-photo.jpg",      "bytes": 2481920,      "format": "jpeg"    },    "report_id": null,    "report_url": null,    "summary": null,    "result": null,    "error": {      "code": "analysis_failed",      "message": "The analysis could not be completed. You were not charged; retry it, and contact support with the request ID if it fails again."    },    "progress": null,    "usage": {      "amount": 0,      "currency": "usd",      "funding": null    },    "metadata": null,    "completed_at": 1793700135,    "expires_at": null  }}

balance.low

balance und threshold sind in US-Cent angegeben.

{  "id": "evt_Lm8sK3tR6yZ2cXaQ9vB4nP1w",  "object": "event",  "type": "balance.low",  "created": 1793700500,  "data": {    "balance": 640,    "threshold": 1000  }}

Signatur prüfen

Jede Anfrage enthält drei Header, wie die Spezifikation Standard Webhooks sie definiert:

HeaderWert
webhook-idDie Ereignis-ID. Bei Wiederholungen bleibt sie gleich; nutzen Sie sie, um Duplikate zu ignorieren.
webhook-timestampUnix-Zeit in Sekunden dieses Zustellversuchs. Sie ändert sich bei jeder Wiederholung.
webhook-signaturev1, gefolgt von einem Base64-kodierten HMAC-SHA256. Ein Header kann mehrere durch Leerzeichen getrennte Signaturen enthalten.

So prüfen Sie eine Anfrage:

  1. Lesen Sie den Anfragetext unverändert als Text, noch bevor Sie ihn als JSON parsen.
  2. Bilden Sie den signierten Inhalt: webhook-id, einen Punkt, webhook-timestamp, einen Punkt und den unveränderten Anfragetext.
  3. Nehmen Sie Ihr Signing-Secret, entfernen Sie das Präfix whsec_ und dekodieren Sie den Rest aus Base64. Das ist der HMAC-Schlüssel.
  4. Berechnen Sie den HMAC-SHA256 des signierten Inhalts und kodieren Sie ihn in Base64.
  5. Vergleichen Sie ihn in konstanter Zeit mit jeder v1-Signatur im Header.
  6. Lehnen Sie Zeitstempel ab, die mehr als fünf Minuten von Ihrer Systemzeit abweichen.
import { createHmac, timingSafeEqual } from "node:crypto"; export function verify(secret, headers, body) {  const id = headers["webhook-id"];  const timestamp = headers["webhook-timestamp"];  const signatures = headers["webhook-signature"];  if (!id || !timestamp || !signatures) throw new Error("Missing webhook headers");  if (Math.abs(Date.now() / 1000 - Number(timestamp)) > 300) throw new Error("Timestamp outside tolerance");  const key = Buffer.from(secret.replace(/^whsec_/, ""), "base64");  const expected = createHmac("sha256", key).update(id + "." + timestamp + "." + body).digest();  const valid = signatures.split(" ").some((entry) => {    const [version, value] = entry.split(",");    const given = Buffer.from(value ?? "", "base64");    return version === "v1" && given.length === expected.length && timingSafeEqual(given, expected);  });  if (!valid) throw new Error("Invalid signature");  return JSON.parse(body);} app.post("/webhooks/fileverity", express.raw({ type: "application/json" }), (req, res) => {  try {    const event = verify(process.env.FILEVERITY_WEBHOOK_SECRET, req.headers, req.body.toString("utf8"));    handle(event);    res.sendStatus(200);  } catch {    res.sendStatus(400);  }});

Prüfen Sie gegen genau die Bytes, die gesendet wurden. Wenn Sie das JSON parsen und erneut serialisieren, ändern sich diese Bytes, und die Signatur stimmt nicht mehr.

Zustellung und Wiederholungen

  • Antworten Sie innerhalb von 10 Sekunden mit einem beliebigen 2xx-Status. Weiterleitungen werden nicht verfolgt und zählen als Fehler.
  • Jede andere Antwort, auch ein Timeout oder ein Verbindungsfehler, löst eine Wiederholung mit wachsenden Abständen aus: 5, 10, 20, 40, 80, 160, 320 und 640 Minuten, danach alle 12 Stunden. Die Wiederholungen enden 3 Tage nach dem Ereignis. Sie laufen nach einem Zeitplan, daher kann eine Wiederholung später als ihr Abstand erfolgen, aber nie früher.
  • Die Zustellung erfolgt mindestens einmal, und die Reihenfolge ist nicht garantiert. Nutzen Sie webhook-id, um Duplikate zu ignorieren, und rufen Sie die Analyse ab, wenn Sie den aktuellen Stand benötigen.
  • Die Konsole listet die letzten 50 Zustellungen mit Status und Fehlern auf, bewahrt sie 30 Tage lang auf und lässt Sie einzelne erneut senden. Wenn Sie eine Zustellung öffnen, sehen Sie ihre Nutzdaten, ihre Antwortzeit und die ersten 2 KB der Antwort Ihres Endpunkts. Geben Sie in dieser Antwort daher keine Secrets oder personenbezogenen Daten zurück. Beim erneuten Senden bleibt die ursprüngliche Ereignis-ID erhalten.
  • Anfragen enthalten den User-Agent Fileverity-Webhooks/1.0.

Automatisches Deaktivieren

Ein Endpunkt, bei dem die Zustellung 3 Tage lang durchgehend fehlschlägt, wird deaktiviert. Er erhält dann keine neuen Ereignisse, und seine nicht zugestellten Ereignisse werden als fehlgeschlagen markiert. Eine erfolgreiche Zustellung vor Ablauf dieser Frist setzt den Fehlerstatus zurück. Inhaber und Admins des Workspace werden per E-Mail informiert, wenn ein Endpunkt deaktiviert wird. Aktivieren Sie den Endpunkt nach der Behebung des Fehlers in der Konsole wieder.

Das Testereignis

Wählen Sie in der Konsole bei einem Endpunkt Test senden, um sofort ein Beispielereignis zuzustellen. Es ist ein signiertes Ereignis analysis.completed mit data.test auf true und ohne Bericht, damit Sie Ihre URL und Ihren Signaturcode prüfen können, bevor echte Ereignisse eintreffen.

{  "id": "evt_Qm4vB7nP1sK8tL3wR6yZ2cXa",  "object": "event",  "type": "analysis.completed",  "created": 1793700500,  "data": {    "id": "an_Pw3mY6zB8Hk2pQ4vN9sL1xR7",    "object": "analysis",    "created": 1793700120,    "model": "fvimg-2-2026-10-30",    "livemode": true,    "status": "succeeded",    "file": {      "name": "claim-photo.jpg",      "bytes": 2481920,      "format": "jpeg"    },    "report_id": null,    "report_url": null,    "summary": null,    "result": null,    "error": null,    "progress": null,    "usage": {      "amount": 199,      "currency": "usd",      "funding": "balance"    },    "metadata": {      "order_id": "A-10492"    },    "completed_at": 1793700131,    "expires_at": 1794304931,    "test": true  }}

Siehe auch: Analysen, Idempotenz und Fehler.