> This page is for Plataforma, 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
> - Herdado: 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.

# Webhooks V4

## O que é um webhook?

Um **webhook** é um callback HTTP do tipo push que o Frame.io dispara **assim que algo interessante** acontece na sua conta (por exemplo, quando um novo arquivo termina a transcodificação, um comentário é adicionado ou um projeto é criado).

Em vez de consultar a API repetidamente, você fornece uma URL HTTPS pública; o Frame.io envia uma carga JSON para essa URL em tempo real para que você possa:

#### Sincronizar metadados com um DAM/MAM externo

#### Preencher canais do Slack ou sistemas de tickets

Para saber mais sobre o que é um webhook e o que ele faz, consulte [https://docs.webhook.site/](https://docs.webhook.site/).

## Visão geral do ponto de acesso

| **Operação**                                          | **Ponto de acesso**                                                   | **Detalhes**                                                  |
| ----------------------------------------------------- | --------------------------------------------------------------------- | ------------------------------------------------------------- |
| **Criar** um webhook                                  | POST /v4/accounts/\{account\_id}/workspaces/\{workspace\_id}/webhooks | Corpo com `name`, `url`, `events[]`                           |
| **Listar** todos os webhooks de um espaço de trabalho | GET /v4/accounts/\{account\_id}/workspaces/\{workspace\_id}/webhooks  | Oferece suporte à paginação                                   |
| **Expandir** um webhook                               | GET /v4/webhooks/\{webhook\_id}                                       | Retorna o segredo de assinatura somente no momento da criação |
| **Atualizar** um webhook                              | PATCH /v4/webhooks/\{webhook\_id}                                     | Alterar `url`, `events` ou `is_active`                        |
| **Excluir**um webhook                                 | DELETE /v4/webhooks/\{webhook\_id}                                    | Interrompe imediatamente as entregas                          |

> **Warning**
>
> **Autenticação** — Todos os pontos de acessoV4 exigem um token de acesso OAuth 2.0 obtido pelo Adobe Developer Console. Tokens de desenvolvedor legado e JWTs **não** são aceitos.

## Alterações e atualizações no Frame V4

> **Info**
>
> Webhooks criados no Legacy são transferidos para a V4 com as seguintes alterações:
>
> 1. **Estrutura de conteúdo**: ID da conta adicionado ao conteúdo
> 2. **Alterações de ponto de acesso**: `team_id` não é mais fornecido na carga JSON, mas no parâmetro de caminho da URL: `https://api.frame.io/v4/accounts/:account_id/workspaces/:workspace_id/webhooks`
> 3. **Integração de API**: devido às mudanças na estrutura da API, nos pontos de acesso e nos métodos de autenticação, qualquer código existente para webhooks de entrada que faça chamadas subsequentes à API do Frame.io para enriquecimento e consulta de recursos precisará ser atualizado
> 4. **Tipos de evento**: webhooks de ativo foram divididos em eventos separados de Arquivo e Pasta. Todos os webhooks vindos do Legacy com eventos de ativo precisam ser atualizados para terem os eventos apropriados de Arquivo e Pasta

> **Warning**
>
> **Status do webhook após migração**: quando sua conta migra para o Frame.io V4, webhooks existentes de versões anteriores são desativados automaticamente. Isso garante que você possa modificar seus pontos de acesso de webhook e a lógica de integração para funcionar com as atualizações da V4 antes de reativá-los. Webhooks que não tiverem sido atualizados para compatibilidade com a V4 encontrarão erros se forem ativados sem as modificações apropriadas. Você pode verificar quais webhooks estão inativos examinando o campo `is_active` por meio da API ou revisando suas [configurações de webhook](https://next.frame.io/settings/webhooks) antes de ligá-los novamente.

## Assinaturas de eventos de webhook

Ao criar e atualizar webhooks, identifique quais eventos são de seu interesse. Escolha poucos ou muitos eventos, conforme necessário, mas observe que a experiência é melhor quando você assina menos eventos, separando seus webhooks de forma lógica com diferentes esquemas de nomenclatura e pontos de acesso diferentes, para que sua lógica de negócios no lado receptor faça menos filtragem e roteamento em funções compartilhadas.

> **Note**
>
> Escopo do evento: todos os eventos estão no escopo do Workspace fornecido durante a criação do webhook. Isso significa que os eventos serão enviados para ações realizadas em todos os projetos nesse Workspace.

### Projetos

| Evento            | Descrição                                            |
| ----------------- | ---------------------------------------------------- |
| `project.created` | Um novo Projeto foi **criado**                       |
| `project.updated` | As Configurações de um Projeto foram **atualizadas** |
| `project.deleted` | Um Projeto foi **deleted**                           |

### Arquivos

| Evento                  | Descrição                                                                                                                                                                                                                   |
| ----------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `file.created`          | Um Arquivo foi **criado** no Frame.io. *Observação:* isso é acionado antes que o arquivo termine o upload. Se o seu manipulador precisar do arquivo completo, recomendamos escutar o evento `upload.completed` em vez disso |
| `file.ready`            | Todas as transcodificações foram **concluídas** depois que um arquivo foi carregado e processado                                                                                                                            |
| `file.updated`          | O nome de um Arquivo ou outras informações foram alteradas                                                                                                                                                                  |
| `file.deleted`          | Um arquivo foi **excluído** (manual ou automaticamente)                                                                                                                                                                     |
| `file.upload.completed` | Foi feito **upload** de um arquivo                                                                                                                                                                                          |
| `file.versioned`        | Uma versão de arquivo foi **criada**                                                                                                                                                                                        |

### Pastas

| Evento           | Descrição                                           |
| ---------------- | --------------------------------------------------- |
| `folder.created` | Uma nova pasta foi **criada**                       |
| `folder.updated` | As configurações de uma pasta foram **atualizadas** |
| `folder.deleted` | Uma Pasta foi **excluída**                          |

### Comentários

| Evento                | Descrição                                        |
| --------------------- | ------------------------------------------------ |
| `comment.created`     | Um novo comentário ou resposta foi **criado**    |
| `comment.updated`     | Um comentário foi atualizado                     |
| `comment.deleted`     | Um comentário foi **excluído**                   |
| `comment.completed`   | Um comentário foi marcado como **concluído**     |
| `comment.uncompleted` | Um comentário foi marcado como **não concluído** |

### Metadados

| Evento                   | Descrição                                     |
| ------------------------ | --------------------------------------------- |
| `metadata.value.updated` | Campos de metadados atualizados para um ativo |

### Coleções

| Evento               | Descrição                       |
| -------------------- | ------------------------------- |
| `collection.created` | Uma nova coleção foi **criada** |
| `collection.updated` | Uma coleção foi **atualizada**  |
| `collection.deleted` | Uma coleção foi **excluída**    |

### Campos personalizados

| Evento                | Descrição                                  |
| --------------------- | ------------------------------------------ |
| `customfield.created` | Um novo campo personalizado foi **criado** |
| `customfield.updated` | Um campo personalizado foi **atualizado**  |
| `customfield.deleted` | Um campo personalizado foi **excluído**    |

### Compartilhamentos

| Evento          | Descrição                               |
| --------------- | --------------------------------------- |
| `share.created` | Um novo compartilhamento foi **criado** |
| `share.updated` | Um compartilhamento foi **atualizado**  |
| `share.deleted` | Um compartilhamento foi **excluído**    |
| `share.viewed`  | Um compartilhamento foi **visualizado** |

## Conteúdo da mensagem de webhook

Todos os conteúdos de webhook contêm um campo `type`, indicando o evento que ocorreu, e um objeto `resource`. O objeto `resource` contém o `type` e `ID` do recurso Frame.io relacionado ao evento.

### Exemplo de conteúdo

```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"
  }
}
```

No exemplo acima de um evento `file.created`, o `resource.id` indica o `ID` do arquivo recém-criado. Além disso, são incluídos os objetos `workspace`, `project` e `user`, que contêm os respectivos `workspace.id`, `project.id` e `user.id`. Esses valores podem ser usados para reduzir chamadas de API filtrando eventos recebidos ou consultando dados armazenados localmente em cache.

> **Warning**
>
> **Não incluímos nenhuma informação adicional além do ID do recurso sobre o recurso assinado.**
>
> Se o aplicativo exigir mais informações ou contexto, recomendamos fazer uma chamada de API para consultar mais informações sobre os recursos referenciados.

## Segurança

Por padrão, todos os webhooks têm uma chave de assinatura. Esse segredo de assinatura não configurável pode ser usado para verificar se a solicitação se origina do Frame.io.

O conteúdo da resposta do webhook configurado inclui o segredo de assinatura específico desse webhook. Esse segredo é **fornecido apenas nessa resposta inicial de criação do webhook**; portanto, armazene-o em um local seguro no seu armazenamento de segredos ou em variáveis de ambiente. Use-o posteriormente para verificar se o webhook vem diretamente dos nossos servidores e não foi interceptado nem manipulado de nenhuma forma.

### Verificação de assinaturas de webhook

Para proteger uma integração contra ataques man-in-the-middle e de repetição, é essencial verificar a assinatura do conteúdo do webhook. A verificação garante que os conteúdos de webhook tenham sido realmente enviados pelo Frame.io e que o conteúdo não tenha sido modificado durante o transporte.

Incluídos com a solicitação `POST` estão os seguintes cabeçalhos HTTP:

| Nome do cabeçalho                             | Descrição                                                 | Exemplo                                                               |
| --------------------------------------------- | --------------------------------------------------------- | --------------------------------------------------------------------- |
| `X-Frameio-Request-Timestamp`                 | O carimbo de data e hora em que a solicitação foi enviada | `1604004499`                                                          |
| `X-Frameio-Signature`                         | A assinatura calculada do webhook                         | `v0=a77ce6856e609c884575c2fd211d07a9ad1c3f72e19c06ff710e8f086ffca883` |
| `user-agent: &quot;Frame.io V4 API&quot;`     | Agente do usuário no cabeçalho para v4                    |                                                                       |
| `user-agent: &quot;Frame.io Legacy API&quot;` | Agente do usuário no cabeçalho para Legacy                |                                                                       |

**`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
```

**O carimbo de data e hora** é a hora do sistema nos sistemas do Frame.io quando o webhook de saída é enviado. Isso pode ser usado para evitar ataques de [repetição](https://en.wikipedia.org/wiki/Replay_attack). Recomendamos verificar se esse horário está dentro de 5 minutos em relação à hora local. **A assinatura** é um hash HMAC SHA256 usando a chave de assinatura fornecida quando o Webhook é criado pela primeira vez. **Siga estas etapas para verificar a assinatura:**

#### Extrair a assinatura

Extraia a assinatura dos cabeçalhos HTTP.

#### Criar mensagem para assinar

Crie uma mensagem para assinar combinando a versão, o horário de entrega e o corpo da solicitação: `v0:timestamp:body.`

#### Calcular HMAC SHA256

Calcule a assinatura HMAC SHA256 usando seu segredo de assinatura.

#### Comparar assinaturas

Compare a assinatura calculada com a fornecida.

> **Note**
>
> A assinatura fornecida tem o prefixo `v0=`. Atualmente, o Frame.io tem apenas essa versão para assinar solicitações. Certifique-se de adicionar esse prefixo à assinatura calculada.

## Novas tentativas e registro

#### Política de tentativas

* Cinco tentativas no total (a inicial + 4 novas tentativas)

* Recuo exponencial começando em 15 s (+ variação aleatória)

* Um status não `2xx` ou tempo-limite > 5 segundos aciona a nova tentativa

#### Registro de falhas

O Frame.io mantém um **log de falhas** com: `webhook_id`, `account_id`, `event_type`, `resource_id`, `user_id`.

## Tutorial de webhook

### Etapa 1: Configurar o lado receptor (feito primeiro para que você saiba qual será sua URL)

Aqui, usamos [webhook.site](http://webhook.site/), que permite criar facilmente um receptor de webhook de uso único que pode ser usado para inspecionar conteúdos e enviar respostas básicas sem nenhuma lógica de negócios real. Ao acessar [https://webhook.site](https://webhook.site/) pela primeira vez, um ponto de acesso de webhook exclusivo é criado para você, que pode ser copiado imediatamente para uso.

Essa URL é exclusiva da sua sessão.

![Exemplo da etapa 1](/_fern-files/frame-io.docs.buildwithfern.com/09ca9e64de4cd7b5b0982e6c2ae5f0978320cd11272b448b7f9f8c2aff1239ab/docs/pages/v4/guides/webhook_site_example.gif)

### Etapa 2: Escolher os eventos que você deseja assinar

Neste tutorial, vamos manter tudo simples e configurar este webhook para assinar apenas eventos `file.created`. O conteúdo JSON que usaremos para criar o webhook será o seguinte.

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

### Etapa 3: Criar um recurso de webhook usando o Postman

Usando o Postman, faça uma chamada de API para criar o recurso de webhook, fornecendo o ponto de acesso do [webhook.site](http://webhook.site/) no conteúdo.

### Etapa 4: Testar!

Agora que você criou a assinatura do webhook e configurou um ponto de acesso para receber webhooks, é hora de testar acionando o primeiro webhook por meio da ação apropriada que fará com que ele seja disparado.

Como nossa amostra foi configurada para acionar o gatilho `file.created`, vamos carregar um novo ativo em qualquer Projeto dentro da Conta e do espaço de trabalho correspondentes em que o webhook foi configurado.

![Exemplo da etapa 4](/_fern-files/frame-io.docs.buildwithfern.com/7503b906ce873425c6477487378fe9c513d5cbddc524754f0e1fe8ba10de5c16/docs/pages/v4/guides/trigger_asset_created_webhook.gif)

## Recursos adicionais

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

O **Ngrok** é uma excelente ferramenta para desenvolvedores que trabalham com webhooks que precisam ser expostos em uma URL publicamente acessível. Ele cria túneis seguros do ambiente local para a Internet, permitindo expor seu servidor local para receber conteúdos de webhook em tempo real.

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

O **Hookdeck** é uma plataforma projetada para ajudar equipes a gerenciar webhooks de forma confiável, oferecendo um gateway de eventos robusto. Ele centraliza o processamento de webhooks, garantindo que nenhum evento seja perdido, e oferece recursos como filtragem, enfileiramento e repetição de webhooks com falha.

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

O **Webhook.site** é uma excelente ferramenta para prototipar e testar webhooks, oferecendo uma plataforma simples e avançada para capturar e inspecionar solicitações HTTP enviadas para URLs exclusivas geradas automaticamente.

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

O **Val.town** é uma excelente ferramenta para prototipar rapidamente manipuladores de webhook, pois simplifica o processo de escrever, testar e implantar pequenas funções JavaScript e Python diretamente do navegador.