> This page is for Plattform, version V4 Experimental.
> For other versions, use one of these documentation indexes:
> - V4 (default): https://next.developer.frame.io/platform/v4/llms.txt
> - V4 Experimental: https://next.developer.frame.io/platform/v4-experimental/llms.txt
> - Vorgängerversion: https://next.developer.frame.io/platform/v2/llms.txt

> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://next.developer.frame.io/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://next.developer.frame.io/_mcp/server.

# V4 Webhooks

## Was ist ein Webhook?

Ein **Webhook** ist ein im Push-Prinzip funktionierender HTTP-Rückruf, der von Frame.io ausgelöst wird, sobald in Ihrem Konto **etwas Interessantes geschieht**, etwa wenn die Transkodierung einer neuen Datei abgeschlossen, ein Kommentar hinzugefügt oder ein Projekt erstellt wird.

Anstatt die API abzufragen, stellen Sie eine öffentliche HTTPS-URL bereit; von Frame.io wird in Echtzeit eine JSON-Payload an diese URL gesendet, damit Sie Folgendes durchführen können:

#### Metadaten mit einem externen DAM/MAM synchronisieren

#### Slack-Kanäle oder Ticketsysteme befüllen

Weitere Informationen darüber, was ein Webhook ist und was damit gemacht wird, finden Sie unter [https://docs.webhook.site/](https://docs.webhook.site/) (in englischer Sprache).

## Endpunkt-Übersicht

| **Vorgang**                                           | **Endpunkt**                                                          | **Details**                                               |
| ----------------------------------------------------- | --------------------------------------------------------------------- | --------------------------------------------------------- |
| **Erstellen** eines Webhooks                          | POST /v4/accounts/\{account\_id}/workspaces/\{workspace\_id}/webhooks | Hauptteil mit `name`, `url`, `events[]`                   |
| **Auflisten** aller Webhooks für einen Arbeitsbereich | GET /v4/accounts/\{account\_id}/workspaces/\{workspace\_id}/webhooks  | Unterstützt Paginierung                                   |
| **Anzeigen** eines Webhooks                           | GET /v4/Webhooks/\{webhook\_id}                                       | Gibt Signiergeheimnis nur zum Erstellungszeitpunkt zurück |
| **Aktualisieren** eines Webhooks                      | PATCH /v4/Webhooks/\{webhook\_id}                                     | Ändert `url`, `events` oder `is_active`                   |
| **Löschen** eines Webhooks                            | DELETE /v4/Webhooks/\{webhook\_id}                                    | Stoppt Bereitstellungen sofort                            |

> **Warning**
>
> **Authentifizierung**: Für alle V4-Endpunkte ist ein OAuth-2.0-Zugriffstoken erforderlich, der über die Adobe Developer Console bezogen wurde.Ältere Entwicklungstoken und JWTs werden **nicht** akzeptiert.

## Änderungen und Aktualisierungen in Frame V4

> **Info**
>
> In der Vorgängerversion erstellte Webhooks werden mit folgenden Änderungen in V4 übertragen:
>
> 1. **Payload-Struktur**: Konto-ID zur Payload hinzugefügt
> 2. **Endpunkt-Änderungen**: Die `team_id` wird nicht mehr in der JSON-Payload bereitgestellt, sondern stattdessen im Pfadparameter der URL: `https://api.frame.io/v4/accounts/:account_id/workspaces/:workspace_id/webhooks`.
> 3. **API-Integration**: Aufgrund von Änderungen in der API-Struktur, den Endpunkten und den Authentifizierungsmethoden müssen alle vorhandenen Codes für eingehende Webhooks aktualisiert werden, mit denen nachfolgende Aufrufe an die Frame.io-API durchgeführt werden, um nach Ressourcen zu suchen und diese anzureichern.
> 4. **Ereignistypen**: Asset-Webhooks wurden in separate Datei- und Ordner-Ereignisse aufgeteilt. Alle Webhooks aus der Vorgängerversion mit Asset-Ereignissen müssen aktualisiert werden, damit sie die entsprechenden Datei- und Ordner-Ereignisse enthalten.

> **Warning**
>
> **Webhook-Status nach Migration**: Wenn Ihr Konto nach Frame.io V4 migriert wird, werden vorhandene Webhooks aus vorherigen Versionen automatisch deaktiviert.Dadurch wird gewährleistet, dass Sie Ihre Webhook-Endpunkte und Integrationslogik ändern können, damit diese mit den Aktualisierungen in V4 funktionieren, bevor Sie sie wieder aktivieren.Webhooks, die nicht für die Kompatibilität mit V4 aktualisiert wurden, werden auf Fehler stoßen, wenn sie ohne ordnungsgemäße Änderungen aktiviert werden.Sie können überprüfen, welche Webhooks inaktiv sind, indem Sie das Feld `is_active` über die API untersuchen oder Ihre [Webhook-Einstellungen](https://next.frame.io/settings/webhooks) überprüfen, bevor Sie sie wieder einschalten.

## Abonnements für Webhook-Ereignisse

Identifizieren Sie beim Erstellen und Aktualisieren von Webhooks, an welchen Ereignissen Sie interessiert sind.Wählen Sie so wenige oder so viele aus, wie Sie möchten. Beachten Sie, dass das Erlebnis besser ist, wenn Sie weniger Ereignisse abonnieren und Ihre Webhooks mit verschiedenen Benennungseinstellungen logisch auf verschiedene Endpunkte aufteilen. Dadurch können Sie Ihre Geschäftslogik auf der empfangenden Seite modellieren, sodass in gemeinsam genutzten Funktionen weniger gefiltert und weitergeleitet wird.

> **Note**
>
> Gültigkeitsbereich des Ereignisses: Alle Ereignisse sind auf den Arbeitsbereich beschränkt, der während der Erstellung des Webhooks bereitgestellt wurde.Das bedeutet, Ereignisse werden für Aktionen gesendet, die in allen Projekten in diesem Arbeitsbereich durchgeführt werden.

### Projekte

| Ereignis          | Beschreibung                                              |
| ----------------- | --------------------------------------------------------- |
| `project.created` | Ein neues Projekt wurde **erstellt**.                     |
| `project.updated` | Die Einstellungen eines Projekts wurden **aktualisiert**. |
| `project.deleted` | Ein Projekt wurde **gelöscht**.                           |

### Dateien

| Ereignis                | Beschreibung                                                                                                                                                                                                                                    |
| ----------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `file.created`          | In Frame.io wurde eine Datei **erstellt**.*Hinweis:* Dies wird ausgelöst, bevor das Hochladen der Datei beendet ist.Wenn Ihr Handler die vollständige Datei benötigt, empfehlen wir, stattdessen auf das Ereignis `upload.completed` zu warten. |
| `file.ready`            | Alle Transkodierungen wurden **abgeschlossen**, nachdem eine Datei hochgeladen und verarbeitet wurde.                                                                                                                                           |
| `file.updated`          | Der Name einer Datei oder andere Informationen wurden geändert.                                                                                                                                                                                 |
| `file.deleted`          | Eine Datei wurde **gelöscht** (manuell oder anderweitig).                                                                                                                                                                                       |
| `file.upload.completed` | Eine Datei wurde **hochgeladen**.                                                                                                                                                                                                               |
| `file.versioned`        | Eine Dateiversion wurde **erstellt**.                                                                                                                                                                                                           |

### Ordner

| Ereignis         | Beschreibung                                             |
| ---------------- | -------------------------------------------------------- |
| `folder.created` | Ein neuer Ordner wurde **erstellt**.                     |
| `folder.updated` | Die Einstellungen eines Ordners wurden **aktualisiert**. |
| `folder.deleted` | Ein Ordner wurde **gelöscht**.                           |

### Kommentare

| Ereignis              | Beschreibung                                                   |
| --------------------- | -------------------------------------------------------------- |
| `comment.created`     | Ein neuer Kommentar oder eine neue Antwort wurde **erstellt**. |
| `comment.updated`     | Ein Kommentar wurde aktualisiert.                              |
| `comment.deleted`     | Ein Kommentar wurde **gelöscht**.                              |
| `comment.completed`   | Ein Kommentar wurde als **abgeschlossen** markiert.            |
| `comment.uncompleted` | Ein Kommentar wurde als **nicht abgeschlossen** markiert.      |

### Metadaten

| Ereignis                 | Beschreibung                                |
| ------------------------ | ------------------------------------------- |
| `metadata.value.updated` | Metadaten-Felder für ein Asset aktualisiert |

### Sammlungen

| Ereignis             | Beschreibung                           |
| -------------------- | -------------------------------------- |
| `collection.created` | Eine neue Sammlung wurde **erstellt**. |
| `collection.updated` | Eine Sammlung wurde **aktualisiert**.  |
| `collection.deleted` | Eine Sammlung wurde **gelöscht**.      |

### Selbstdefinierte Felder

| Ereignis              | Beschreibung                                         |
| --------------------- | ---------------------------------------------------- |
| `customfield.created` | Ein neues selbstdefiniertes Feld wurde **erstellt**. |
| `customfield.updated` | Ein selbstdefiniertes Feld wurde **aktualisiert**.   |
| `customfield.deleted` | Ein selbstdefiniertes Feld wurde **gelöscht**.       |

### Freigaben

| Ereignis        | Beschreibung                           |
| --------------- | -------------------------------------- |
| `share.created` | Eine neue Freigabe wurde **erstellt**. |
| `share.updated` | Eine Freigabe wurde **aktualisiert**.  |
| `share.deleted` | Eine Freigabe wurde **gelöscht**.      |
| `share.viewed`  | Eine Freigabe wurde **angezeigt**.     |

## Payload von Webhook-Nachrichten

Alle Webhook-Payloads enthalten das Feld `type`, in dem das aufgetretene Ereignis angegeben wird, und das Objekt `resource`.Das Objekt `resource` enthält den `type` und die `ID` der Frame.io-Ressource, die mit dem Ereignis verknüpft ist.

### Beispiel-Payload

```json
{
  "account": {
    "id": "6f70f1bd-7e89-4a7e-b4d3-7e576585a181"
  },
  "project": {
    "id": "7e46e495-4444-4555-8649-bee4d391a997"
  },
  "resource": {
    "id": "d3075547-4e64-45f0-ad12-d075660eddd2",
    "type": "file"
  },
  "type": "file.ready",
  "user": {
    "id": "56556a3f-859f-4b38-b6c6-e8625b5da8a5"
  },
  "workspace": {
    "id": "378fcbf7-6f88-4224-8139-6a743ed940b2"
  }
}
```

Im obigen Beispiel eines `file.created`-Ereignisses wird von der `resource.id` die `ID` der neu erstellten Datei angegeben.Zusätzlich sind die Objekte `workspace`, `project` und `user` enthalten, die die zugehörige `workspace.id`, `project.id` und `user.id` enthalten.Mit diesen Werten können API-Aufrufe reduziert werden, indem eingehende Ereignisse gefiltert oder lokal zwischengespeicherte Daten abgerufen werden.

> **Warning**
>
> **Wir fügen der abonnierten Ressource keine zusätzlichen Informationen hinzu, die über die Ressourcen-ID hinausgehen.**
>
> Falls Sie für Ihre Anwendung zusätzliche Informationen oder Kontext benötigen, empfehlen wir einen API-Aufruf, um weitere Informationen über die referenzierten Ressourcen abzurufen.

## Sicherheit

Standardmäßig haben alle Webhooks einen Signaturschlüssel.Mit diesem nicht konfigurierbaren Signiergeheimnis kann verifiziert werden, dass die Anfrage von Frame.io stammt.

Die Antwort-Payload für den konfigurierten Webhook enthält das Signiergeheimnis, das für diesen Webhook spezifisch ist.Dieses Geheimnis wird **nur in dieser ersten Erstellungsantwort des Webhooks bereitgestellt**. Speichern Sie es daher sicher in Ihrem Geheimnisspeicher oder in Umgebungsvariablen.Damit können Sie später verifizieren, dass der Webhook direkt von unseren Servern stammt und nicht abgefangen oder manipuliert wurde.

### Verifizieren von Webhook-Signaturen

Zum Schutz einer Integration vor Man-in-the-Middle- und Replay-Angriffen ist es wichtig, die Signatur der Webhook-Payload zu verifizieren.Durch die Verifizierung wird gewährleistet, dass Webhook-Payloads tatsächlich von Frame.io gesendet wurden und der Inhalt der Payload nicht während des Transports verändert wurde.

In der `POST`-Anfrage sind die folgenden HTTP-Header enthalten:

| Name des Headers                              | Beschreibung                                              | Beispiel                                                              |
| --------------------------------------------- | --------------------------------------------------------- | --------------------------------------------------------------------- |
| `X-Frameio-Request-Timestamp`                 | Zeitstempel, der anzeigt, wann die Anfrage gesendet wurde | `1604004499`                                                          |
| `X-Frameio-Signature`                         | Die berechnete Webhook-Signatur                           | `v0=a77ce6856e609c884575c2fd211d07a9ad1c3f72e19c06ff710e8f086ffca883` |
| `user-agent: &quot;Frame.io V4 API&quot;`     | User Agent im Header für v4                               |                                                                       |
| `user-agent: &quot;Frame.io Legacy API&quot;` | User Agent im Header für Vorgängerversion                 |                                                                       |

**`Python`**

```python title="Python"
import hmac
import hashlib

def verify_signature(curr_time, req_time, signature, body, secret):
    """
    Verify Webhook signature
    :Args:
        curr_time (float): Current epoch time
        req_time (float): Request epoch time
        signature (str): Signature provided by the Frame.io API for the given request
        body (str): Webhook body from the received POST
        secret (str): The secret for this Webhook that you saved when you first created it
    """
    if int(curr_time) - int(req_time) < 500:
        message = 'v0:{}:{}'.format(req_time, body)
        calculated_signature = 'v0={}'.format(hmac.new(
            bytes(secret, 'latin-1'),
            msg=bytes(message, 'latin-1'),
            digestmod=hashlib.sha256).hexdigest())
        if calculated_signature == signature:
            return True
    return False
```

Mit **dem Zeitstempel** wird die Systemzeit von Frame.io-Systemen wiedergegeben und angezeigt, wann der ausgehende Webhook gesendet wurde.Damit können [Replay](https://en.wikipedia.org/wiki/Replay_attack)-Angriffe verhindert werden.Wir empfehlen, zu verifizieren, dass diese Zeit innerhalb von 5 Minuten der lokalen Zeit liegt.**Die Signatur** ist ein HMAC-SHA-256-Hash, in dem der Signaturschlüssel verwendet wird, der bei der Ersterstellung des Webhooks bereitgestellt wird.**Führen Sie diese Schritten aus, um die Signatur zu verifizieren:**

#### Signatur extrahieren

Extrahieren Sie die Signatur aus den HTTP-Headern.

#### Nachricht zum Signieren erstellen

Erstellen Sie eine Nachricht zum Signieren, indem Sie Version, Bereitstellungszeit und Text der Anfrage kombinieren: `v0:timestamp:body.`

#### HMAC SHA256 berechnen

Berechnen Sie mit Ihrem Signiergeheimnis die HMAC-SHA256-Signatur.

#### Signaturen vergleichen

Vergleichen Sie die berechnete Signatur mit der bereitgestellten.

> **Note**
>
> Der bereitgestellten Signatur ist das Präfix `v0=` vorangestellt.Derzeit gibt es in Frame.io nur diese eine Version für das Signieren von Anfragen.Achten Sie darauf, dass dieses Präfix der berechneten Signatur vorangestellt ist.

## Wiederholungen und Protokollierung

#### Wiederholungsrichtlinie

* Fünf Versuche insgesamt (erster plus 4 Wiederholungen)

* Exponentieller Rückzug beginnt bei 15 Sek. (plus Jitter)

* Bei einem Nicht-`2xx`-Status oder einer Zeitüberschreitung von mehr als 5 Sekunden wird die Wiederholung ausgelöst.

#### Fehlerprotokollierung

In Frame.io wird ein **Fehlerprotokoll** mit folgenden Parametern geführt: `webhook_id`, `account_id`, `event_type`, `resource_id`, `user_id`.

## Webhook-Tutorial

### Schritt 1: Empfangsende einrichten (zuerst durchführen, damit Sie wissen, wie Ihre URL lauten wird)

Hier verwenden wir [webhook.site](http://webhook.site/), mit dem Sie einfach einmalige Webhook-Empfangende erstellen können, die ohne jegliche Geschäftslogik zum Inspizieren von Payloads und zum Senden grundlegender Antworten verwendet werden können.Wenn Sie zum ersten Mal zu [https://webhook.site](https://webhook.site/) navigieren, wird ein eindeutiger Webhook-Endpunkt für Sie erstellt, den Sie sofort kopieren und verwenden können.

Diese URL ist für Ihre Sitzung eindeutig.

![Beispiel zu Schritt 1](/_fern-files/frame-io.docs.buildwithfern.com/09ca9e64de4cd7b5b0982e6c2ae5f0978320cd11272b448b7f9f8c2aff1239ab/docs/pages/v4/guides/webhook_site_example.gif)

### Schritt 2: Ereignisse wählen, die Sie abonnieren möchten

In dieser Anleitung halten wir es einfach und richten diesen Webhook so ein, dass nur `file.created`-Ereignisse abonniert werden.Die JSON-Payload, die wir für die Webhook-Erstellung verwenden, lautet wie folgt.

```json
{
    "data": {
        "name": "asset.created sample webhook",
        "events": ["file.created"],
        "url": "https://webhook.site/c05f2216-9558-4816-bc09-f77ee7b9de40"
    }
}
```

### Schritt 3: Webhook-Ressource mit Postman erstellen

Führen Sie mit Postman einen API-Aufruf durch und erstellen Sie die Webhook-Ressource. Geben Sie dabei in der Payload den Endpunkt [webhook.site](http://webhook.site/) an.

### Schritt 4: Testen

Jetzt, da Sie das Webhook-Abonnement erstellt und einen Endpunkt eingerichtet haben, um Webhooks zu empfangen, sollten Sie all dies testen. Lösen Sie den ersten Webhook aus, indem Sie die entsprechende Aktion durchführen, durch die er ausgelöst würde.

Da unser Beispiel so eingerichtet ist, dass es bei `file.created` ausgelöst wird, werden wir ein neues Asset in ein beliebiges Projekt innerhalb desjenigen Kontos und Arbeitsbereichs hochladen, in dem der Webhook eingerichtet wurde.

![Beispiel zu Schritt 4](/_fern-files/frame-io.docs.buildwithfern.com/7503b906ce873425c6477487378fe9c513d5cbddc524754f0e1fe8ba10de5c16/docs/pages/v4/guides/trigger_asset_created_webhook.gif)

## Zusätzliche Ressourcen

#### [Ngrok](https://ngrok.com/)

**Ngrok** ist ein fantastisches Tool für Entwickelnde, die mit Webhooks arbeiten und diese über eine öffentlich zugängliche URL freilegen müssen.Damit werden sichere Tunnel von Ihrer lokalen Umgebung ins Internet erstellt. Außerdem wird Ihnen ermöglicht, Ihren lokalen Server freizulegen, um Webhook-Payloads in Echtzeit zu empfangen.

#### [Hookdeck](https://hookdeck.com/)

**Hookdeck** ist eine Plattform, die Teams anhand eines robusten Ereignis-Gateways dabei hilft, Webhooks zuverlässig zu verwalten.Die Verarbeitung von Webhooks wird zentralisiert. Es wird darauf geachtet, dass keine Ereignisse verpasst werden, und es gibt Funktionen wie Filterung, Warteschlangen und Wiederholung fehlgeschlagener Webhooks.

#### [Webhook.site](https://webhook.site)

**Webhook.site** ist ein herausragendes Tool für das Prototyping und Testen von Webhooks. Es bietet eine einfache, aber mächtige Plattform, um HTTP-Anfragen zu erfassen und zu untersuchen, die an eindeutige, automatisch generierte URLs gesendet werden.

#### [Val.town](https://www.val.town/)

**Val.town** ist ein exzellentes Tool für das schnelle Prototyping von Webhook-Handlern, da der Prozess des Schreibens, Testens und Bereitstellens kleiner JavaScript- und Python-Funktionen direkt über den Browser vereinfacht wird.