> ## Documentation Index
> Fetch the complete documentation index at: https://docs.ararahq.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Eventos

> Todos os eventos de webhook da Arara, com o corpo completo e os campos de cada um.

Esta página lista cada evento que a Arara envia para o seu webhook. Para receber, verificar a assinatura e tratar retentativas, veja [Webhooks](/webhooks).

## Envelope

Todo evento chega no mesmo formato. Só o conteúdo de `data` muda.

```json theme={null}
{
  "event": "message.status_updated",
  "apiVersion": "2026-05-13",
  "data": {
    "id": "ara_msg_k9Bf2Xq",
    "status": "delivered"
  },
  "timestamp": "2026-09-15T14:32:15.234Z",
  "organizationId": "0e4f3c1e-5b6a-4c3d-9e8f-7a6b5c4d3e2f"
}
```

| Campo | Tipo | Descrição |
| - | - | - |
| `event` | string | Tipo do evento. |
| `apiVersion` | string | Versão do contrato dos payloads. Hoje `2026-05-13`. |
| `data` | object | Conteúdo do evento. |
| `timestamp` | string (ISO 8601) | Quando a Arara gerou o evento. |
| `organizationId` | string (UUID) | Organização dona do evento. |

## Todos os eventos

| Evento | Quando dispara |
| - | - |
| **Mensagens** | |
| [`message.status_updated`](#message-status_updated) | O status de uma mensagem enviada mudou. |
| [`message.received`](#message-received) | O cliente mandou mensagem para o seu número. |
| [`message.echo`](#message-echo) | Sua equipe respondeu pelo app do WhatsApp Business. |
| [`message.link_clicked`](#message-link_clicked) | O cliente tocou no botão de link de uma mensagem. |
| [`message.flow_reply`](#message-flow_reply) | O cliente respondeu um formulário. |
| **Templates** | |
| [`template.updated`](#template-updated) | O status de um template mudou. |
| [`template.category_changed`](#template-category_changed) | A Meta mudou a categoria de um template. |
| [`template.quality_updated`](#template-quality_updated) | A Meta atualizou a qualidade de um template. |
| **Campanhas** | |
| [`campaign.completed`](#campaign-completed) | Uma campanha terminou de processar. |
| **Conversas** | |
| [`conversation.needs_human`](#conversation-needs_human) | O Brain passou a conversa para um atendente. |
| **Números** | |
| [`number.status`](#number-status) | Número banido, restringido, reabilitado ou com erro na conexão. |
| [`number.tier_updated`](#number-tier_updated) | O limite de envio ou a qualidade do número mudou. |
| [`number.name_status`](#number-name_status) | A Meta decidiu sobre o nome de exibição. |
| **Conta** | |
| [`account.review`](#account-review) | A Meta concluiu a revisão da conta WhatsApp Business. |
| [`account.capability`](#account-capability) | Os limites da conta WhatsApp Business mudaram. |
| **Cobranças** | |
| [`charge.sent`](#cobranças) | Uma cobrança foi enviada ao cliente. |
| [`charge.paid`](#cobranças) | A cobrança foi paga. |
| [`charge.failed`](#cobranças) | O pagamento falhou. |
| [`charge.canceled`](#cobranças) | A cobrança foi cancelada. |
| [`charge.expired`](#cobranças) | A cobrança venceu sem pagamento. |
| **Teste** | |
| [`webhook.test`](#webhook-test) | Você disparou o evento de teste pelo painel. |

<Warning>
  Duas armadilhas ao escrever o handler:

  * **Os nomes de campo não seguem um padrão único.** `message.received`, `message.echo`, `message.flow_reply` e `charge.*` usam snake\_case (`media_url`, `sender_name`, `flow_id`, `amount_cents`). `message.status_updated` e os demais usam camelCase (`messageId`, `providerSid`, `errorDetails`). Não reaproveite o mesmo tipo para os dois.
  * **`errorDetails` muda de tipo.** Em `message.status_updated` ele pode vir como string, como objeto ou `null`. Confira o tipo antes de ler.
</Warning>

## Mensagens

### `message.status_updated`

Dispara a cada mudança de status de uma mensagem que você enviou.

```json theme={null}
{
  "event": "message.status_updated",
  "apiVersion": "2026-05-13",
  "data": {
    "id": "ara_msg_k9Bf2Xq",
    "messageId": "0e4f3c1e-5b6a-4c3d-9e8f-7a6b5c4d3e2f",
    "internalId": "ara_msg_k9Bf2Xq",
    "providerSid": "wamid.HBgL...",
    "status": "delivered",
    "receiver": "whatsapp:+5511999999999",
    "sender": "whatsapp:+5511888888888",
    "errorDetails": null
  },
  "timestamp": "2026-09-15T14:32:15.234Z",
  "organizationId": "0e4f3c1e-5b6a-4c3d-9e8f-7a6b5c4d3e2f"
}
```

| Campo | Tipo | Descrição |
| - | - | - |
| `id` | string | ID da mensagem, o mesmo devolvido no envio. Use este. |
| `messageId` | string (UUID) \| null | ID interno. `null` quando o envio falhou antes de virar mensagem. |
| `internalId` | string | Igual a `id`. |
| `providerSid` | string \| null | ID da mensagem na Meta (`wamid`). |
| `status` | string | `queued`, `scheduled`, `processing`, `sent`, `delivered`, `read`, `failed` ou `canceled`. |
| `receiver` | string | Telefone do destinatário. |
| `sender` | string | Número que enviou. Vazio quando o envio falhou antes de virar mensagem. |
| `errorDetails` | string \| object \| null | Motivo da falha. `null` quando não houve falha. |

O `status` vem em minúsculas. Na API REST o mesmo status vem em maiúsculas, e `PENDING` aparece aqui como `queued`.

Quando `status` é `failed`, `errorDetails` traz o motivo já traduzido pela Arara, em um de dois formatos:

* **String**, com o que aconteceu e o que fazer. É o formato dos números no provedor atual.

  ```json theme={null}
  {
    "status": "failed",
    "errorDetails": "Passaram-se mais de 24h desde a última mensagem do cliente. A Meta exige um Template Aprovado para reabrir a conversa. Envie um Template Message para reabrir a janela de conversa com este cliente."
  }
  ```

* **Objeto**, com `code`, `whatHappened` e `howToAct`. É o formato dos números legados.

  ```json theme={null}
  {
    "status": "failed",
    "errorDetails": {
      "code": "ararahq-invalid-number",
      "whatHappened": "Número inválido ou sem WhatsApp...",
      "howToAct": "Verifique se o número está correto..."
    }
  }
  ```

Trate os dois:

```javascript theme={null}
function failureReason(errorDetails) {
  if (typeof errorDetails === 'string') return errorDetails;
  if (errorDetails && typeof errorDetails === 'object') {
    return typeof errorDetails.whatHappened === 'string' ? errorDetails.whatHappened : JSON.stringify(errorDetails);
  }
  return null;
}
```

O significado de cada motivo está em [Por que minha mensagem falhou](/erros-de-envio).

### `message.received`

Dispara quando o cliente manda mensagem para um número próprio da organização.

```json theme={null}
{
  "event": "message.received",
  "apiVersion": "2026-05-13",
  "data": {
    "id": "wamid.HBgL...",
    "from": "5511999999999",
    "to": "5511888888888",
    "body": "Quero pagar",
    "type": "text",
    "media_url": "",
    "media_type": "text",
    "media_content_type": "",
    "transcription_summary": "",
    "sender_name": "João Silva",
    "timestamp": "2026-09-15T14:36:00Z",
    "provider": "META",
    "reply": { "kind": "button", "id": "quero-pagar", "title": "Quero pagar" }
  },
  "timestamp": "2026-09-15T14:36:00.412Z",
  "organizationId": "0e4f3c1e-5b6a-4c3d-9e8f-7a6b5c4d3e2f"
}
```

| Campo | Tipo | Descrição |
| - | - | - |
| `id` | string | ID da mensagem na Meta (`wamid`). |
| `from` | string | Telefone do cliente, só dígitos, sem `+`. |
| `to` | string | Seu número, só dígitos. |
| `body` | string | Texto da mensagem. Vazio quando é só mídia. |
| `type` | string | `text` ou `media`. |
| `media_url` | string | URL da mídia. Vazio quando não há. |
| `media_type` | string | `text`, `audio`, `image`, `video`, `document` ou `media`. |
| `media_content_type` | string | MIME da mídia. Vazio quando não há. |
| `transcription_summary` | string | Resumo ou transcrição da mídia, quando disponível. |
| `sender_name` | string | Nome de perfil do cliente no WhatsApp. Pode vir vazio. |
| `timestamp` | string (ISO 8601) | Quando a Arara processou a mensagem. |
| `provider` | string | `META` ou `TWILIO`. |
| `reply` | object | Só aparece quando o cliente tocou num botão ou numa opção de lista. |
| `reply.kind` | string | `button` (botão de mensagem interativa), `list` (opção de lista) ou `template_button` (resposta rápida de template). |
| `reply.id` | string | O `id` que você definiu ao enviar o botão ou a opção. Em `template_button`, é o payload do botão do template. |
| `reply.title` | string | O texto que o cliente viu. |

Mensagem digitada não traz `reply`. Num toque de botão, `body` repete o texto que o cliente viu. Decida pelo `reply.id`, não pelo `title`: o texto pode mudar, o `id` é seu.

Este evento não dispara para:

* mensagem recebida no número compartilhado da Arara;
* palavras de opt-out ("SAIR", "PARAR", "STOP");
* respostas a confirmações de agendamento.

### `message.echo`

Dispara quando sua equipe manda uma mensagem pelo app do WhatsApp Business, num número em coexistência. Serve para manter o histórico completo no seu sistema.

```json theme={null}
{
  "event": "message.echo",
  "apiVersion": "2026-05-13",
  "data": {
    "id": "ara_msg_x1Y2z3W",
    "provider_id": "wamid.HBgL...",
    "conversation_id": "3f1c9a2b-7d2b-4a3f-8e11-9b1f4c2d7a66",
    "from": "5511888888888",
    "to": "5511999999999",
    "direction": "outbound",
    "source": "whatsapp_app",
    "body": "Oi João, já te ligo",
    "type": "text",
    "media_url": "",
    "media_type": "text",
    "media_content_type": "",
    "transcription_summary": "",
    "timestamp": "2026-09-15T14:37:00Z",
    "provider": "META"
  },
  "timestamp": "2026-09-15T14:37:02.118Z",
  "organizationId": "0e4f3c1e-5b6a-4c3d-9e8f-7a6b5c4d3e2f"
}
```

| Campo | Tipo | Descrição |
| - | - | - |
| `id` | string | ID da mensagem na Arara. |
| `provider_id` | string | ID da mensagem na Meta (`wamid`). |
| `conversation_id` | string | ID da conversa. Vazio quando não há conversa. |
| `from` | string | Seu número, só dígitos. O sentido é o inverso de `message.received`. |
| `to` | string | Telefone do cliente, só dígitos. |
| `direction` | string | Sempre `outbound`. |
| `source` | string | Sempre `whatsapp_app`. |
| `body` | string | Texto da mensagem. |
| `type` | string | `text` ou `media`. |
| `media_url` | string | URL da mídia. Vazio quando não há. |
| `media_type` | string | `text`, `audio`, `image`, `video`, `document` ou `media`. |
| `media_content_type` | string | MIME da mídia. Vazio quando não há. |
| `transcription_summary` | string | Resumo ou transcrição da mídia, quando disponível. |
| `timestamp` | string (ISO 8601) | Horário do aparelho que enviou. |
| `provider` | string | `META`. |

### `message.link_clicked`

Dispara quando o cliente toca no botão de link de uma mensagem. Vale para template com botão de link dinâmico que usa um [link curto](/smart-links) da Arara e leva o ID da mensagem no fim da URL. Você recebe um aviso por mensagem, no primeiro clique. Cliques de robôs não contam.

```json theme={null}
{
  "event": "message.link_clicked",
  "apiVersion": "2026-05-13",
  "data": {
    "id": "ara_msg_k9Bf2Xq",
    "messageId": "0e4f3c1e-5b6a-4c3d-9e8f-7a6b5c4d3e2f",
    "internalId": "ara_msg_k9Bf2Xq",
    "receiver": "whatsapp:+5511999999999",
    "sender": "whatsapp:+5511888888888",
    "linkCode": "aB3xK9",
    "clickedAt": "2026-09-15T14:40:12.501Z"
  },
  "timestamp": "2026-09-15T14:40:12.530Z",
  "organizationId": "0e4f3c1e-5b6a-4c3d-9e8f-7a6b5c4d3e2f"
}
```

| Campo | Tipo | Descrição |
| - | - | - |
| `id` | string | ID da mensagem que levou o link, o mesmo devolvido no envio. |
| `messageId` | string (UUID) | ID interno. |
| `internalId` | string | Igual a `id`. |
| `receiver` | string | Telefone do destinatário. |
| `sender` | string | Número que enviou. |
| `linkCode` | string | Código do link curto. |
| `clickedAt` | string (ISO 8601) | Momento do clique. |

### `message.flow_reply`

Dispara quando o cliente envia a resposta de um [formulário](/flows). As chaves de `fields` são as que você definiu ao criar o formulário e não mudam.

```json theme={null}
{
  "event": "message.flow_reply",
  "apiVersion": "2026-05-13",
  "data": {
    "id": "wamid.HBgM...",
    "from": "5588999990000",
    "to": "5588911110000",
    "flow_id": "0b7e6a52-3c1d-4f7a-9a55-2f4f6f1f9c10",
    "flow_name": "Captar contato",
    "source_message_id": "c0a8012e-7d2b-4a3f-8e11-9b1f4c2d7a66",
    "fields": { "nome": "Maria Souza", "email": "maria@exemplo.com" },
    "answers": [
      { "key": "nome", "label": "Seu nome", "value": "Maria Souza" },
      { "key": "email", "label": "Seu melhor e-mail", "value": "maria@exemplo.com" }
    ]
  },
  "timestamp": "2026-09-15T14:41:00.220Z",
  "organizationId": "0e4f3c1e-5b6a-4c3d-9e8f-7a6b5c4d3e2f"
}
```

| Campo | Tipo | Descrição |
| - | - | - |
| `id` | string | ID da resposta na Meta (`wamid`). |
| `from` | string | Telefone do cliente, só dígitos. |
| `to` | string | Seu número, só dígitos. |
| `flow_id` | string (UUID) | ID do formulário. |
| `flow_name` | string | Nome do formulário. |
| `source_message_id` | string | Mensagem da Arara que levou o botão do formulário. Vazio quando não dá para determinar. |
| `fields` | object | Respostas por chave. É o atalho para ler um campo. |
| `answers` | array | Respostas na ordem do formulário, com `key`, `label` (a pergunta) e `value`. |

Na conversa, a resposta aparece como mensagem do cliente com o texto `Formulário respondido`.

## Templates

### `template.updated`

Dispara quando o status de um template muda: aprovação, reprovação, pausa ou desativação. Inclui a pausa automática feita pela Arara.

```json theme={null}
{
  "event": "template.updated",
  "apiVersion": "2026-05-13",
  "data": {
    "templateId": "a7f3c1e2-4b5d-6789-abcd-ef0123456789",
    "name": "blackfriday_v3",
    "status": "REJECTED",
    "category": "MARKETING",
    "rejectionReason": "INVALID_FORMAT"
  },
  "timestamp": "2026-09-15T15:02:44.031Z",
  "organizationId": "0e4f3c1e-5b6a-4c3d-9e8f-7a6b5c4d3e2f"
}
```

| Campo | Tipo | Descrição |
| - | - | - |
| `templateId` | string (UUID) | ID do template. |
| `name` | string | Nome do template. |
| `status` | string \| null | Status na Meta: `APPROVED`, `REJECTED`, `PAUSED`, `PENDING`, `DISABLED`, entre outros. |
| `category` | string | `MARKETING`, `UTILITY` ou `AUTHENTICATION`. |
| `rejectionReason` | string \| null | Motivo da reprovação. `null` nos outros casos. |

### `template.category_changed`

Dispara quando a Meta muda a categoria de um template. A categoria define o preço por mensagem.

```json theme={null}
{
  "event": "template.category_changed",
  "apiVersion": "2026-05-13",
  "data": {
    "name": "aviso_pedido",
    "old": "UTILITY",
    "new": "MARKETING"
  },
  "timestamp": "2026-09-15T15:10:03.700Z",
  "organizationId": "0e4f3c1e-5b6a-4c3d-9e8f-7a6b5c4d3e2f"
}
```

| Campo | Tipo | Descrição |
| - | - | - |
| `name` | string | Nome do template. |
| `old` | string | Categoria anterior. |
| `new` | string | Categoria nova, em maiúsculas. |

### `template.quality_updated`

Dispara quando a Meta atualiza a qualidade de um template.

```json theme={null}
{
  "event": "template.quality_updated",
  "apiVersion": "2026-05-13",
  "data": {
    "name": "blackfriday_v3",
    "quality": "LOW"
  },
  "timestamp": "2026-09-15T15:12:40.905Z",
  "organizationId": "0e4f3c1e-5b6a-4c3d-9e8f-7a6b5c4d3e2f"
}
```

| Campo | Tipo | Descrição |
| - | - | - |
| `name` | string | Nome do template. |
| `quality` | string | Qualidade informada pela Meta, em maiúsculas. |

## Campanhas

### `campaign.completed`

Dispara quando a campanha termina de processar todos os contatos. Não significa que todas as mensagens foram entregues.

```json theme={null}
{
  "event": "campaign.completed",
  "apiVersion": "2026-05-13",
  "data": {
    "id": "7b3789fb-4c5d-6789-abcd-ef0123456789",
    "name": "Black Friday 2026",
    "status": "completed_with_errors",
    "totalMessages": 12500,
    "totalCost": 4793.75
  },
  "timestamp": "2026-09-15T16:20:00.000Z",
  "organizationId": "0e4f3c1e-5b6a-4c3d-9e8f-7a6b5c4d3e2f"
}
```

| Campo | Tipo | Descrição |
| - | - | - |
| `id` | string (UUID) | ID da campanha. |
| `name` | string | Nome da campanha. |
| `status` | string | `completed`, `completed_with_errors` ou `failed`. |
| `totalMessages` | number | Contatos da campanha. |
| `totalCost` | number | Valor debitado, em reais. |

<Warning>
  O nome do evento é o mesmo quando a campanha falha. Confira sempre `data.status`.
</Warning>

O evento não dispara enquanto a campanha está em teste A/B nem quando ela é cancelada. Para métricas detalhadas, consulte `GET /v1/campaigns/{id}`.

## Conversas

### `conversation.needs_human`

Dispara quando o [Brain](/brain) passa a conversa para um atendente.

```json theme={null}
{
  "event": "conversation.needs_human",
  "apiVersion": "2026-05-13",
  "data": {
    "handoffId": "ara_hof_Hk3mP9q",
    "conversationId": "3f1c9a2b-7d2b-4a3f-8e11-9b1f4c2d7a66",
    "reason": "CUSTOMER_REQUEST",
    "summary": "Cliente pediu para falar com atendente sobre troca.",
    "createdAt": "2026-09-15T14:36:00Z"
  },
  "timestamp": "2026-09-15T14:36:00.310Z",
  "organizationId": "0e4f3c1e-5b6a-4c3d-9e8f-7a6b5c4d3e2f"
}
```

| Campo | Tipo | Descrição |
| - | - | - |
| `handoffId` | string | ID da passagem para o atendente. |
| `conversationId` | string (UUID) \| null | ID da conversa. Pode vir `null`. |
| `reason` | string | Motivo. Texto livre. |
| `summary` | string | Resumo da conversa até ali. |
| `createdAt` | string (ISO 8601) | Quando a passagem foi criada. |

Valores comuns de `reason`: `CUSTOMER_REQUEST`, `LOW_CONFIDENCE`, `MAX_MESSAGES`, `QUOTA_EXCEEDED`, `LEAD_QUALIFIED_HOT`. O Brain também pode escrever um motivo próprio, então não trate a lista como fechada.

Para encerrar o atendimento: `POST /v1/brain/handoffs/{handoffId}/resolve`, com chave de API de permissão `ADMIN`.

## Números

### `number.status`

Dispara quando a Meta bane, restringe ou reabilita um número, e quando a conexão de um número não é concluída.

```json theme={null}
{
  "event": "number.status",
  "apiVersion": "2026-05-13",
  "data": {
    "status": "BANNED",
    "reason": "Violação de política",
    "phone": "5511888888888"
  },
  "timestamp": "2026-09-15T17:05:21.640Z",
  "organizationId": "0e4f3c1e-5b6a-4c3d-9e8f-7a6b5c4d3e2f"
}
```

Os campos mudam conforme o `status`:

| `status` | Outros campos | Quando |
| - | - | - |
| `BANNED` | `reason`, `phone` | A Meta baniu o número. O envio por ele fica bloqueado. |
| `RESTRICTED` | `restriction`, `phone` | A Meta restringiu o número. |
| `ACTIVE` | `phone` | A Meta reabilitou o número. |
| `ONBOARDING_ERROR` | `reason` | A conexão do número não foi concluída. |

| Campo | Tipo | Descrição |
| - | - | - |
| `status` | string | Um dos quatro valores acima. |
| `phone` | string | Número afetado. |
| `reason` | string | Motivo informado pela Meta. |
| `restriction` | string | Tipos de restrição, separados por vírgula. |

### `number.tier_updated`

Dispara quando o limite de envio ou a sinalização de qualidade do número muda.

```json theme={null}
{
  "event": "number.tier_updated",
  "apiVersion": "2026-05-13",
  "data": {
    "event": "upgrade",
    "tier": "TIER_10K"
  },
  "timestamp": "2026-09-15T17:30:00.118Z",
  "organizationId": "0e4f3c1e-5b6a-4c3d-9e8f-7a6b5c4d3e2f"
}
```

| Campo | Tipo | Descrição |
| - | - | - |
| `event` | string | Evento da Meta, em minúsculas. Contém `flagged` quando a qualidade caiu e `unflagged` quando voltou. |
| `tier` | string | `TIER_50`, `TIER_250`, `TIER_1K`, `TIER_2K`, `TIER_10K`, `TIER_100K`, `UNLIMITED` ou vazio quando a Meta não informou. |

O que cada limite significa está em [Números](/numbers).

### `number.name_status`

Dispara quando a Meta decide sobre o nome de exibição do número.

```json theme={null}
{
  "event": "number.name_status",
  "apiVersion": "2026-05-13",
  "data": {
    "decision": "approved",
    "reason": ""
  },
  "timestamp": "2026-09-15T18:00:09.450Z",
  "organizationId": "0e4f3c1e-5b6a-4c3d-9e8f-7a6b5c4d3e2f"
}
```

| Campo | Tipo | Descrição |
| - | - | - |
| `decision` | string | Decisão da Meta, como ela enviou. Exemplos: `approved`, `rejected`, `declined`. Compare sem diferenciar maiúsculas. |
| `reason` | string | Motivo. Pode vir vazio. |

## Conta

### `account.review`

Dispara quando a Meta conclui a revisão da conta WhatsApp Business.

```json theme={null}
{
  "event": "account.review",
  "apiVersion": "2026-05-13",
  "data": {
    "decision": "APPROVED"
  },
  "timestamp": "2026-09-15T18:20:31.002Z",
  "organizationId": "0e4f3c1e-5b6a-4c3d-9e8f-7a6b5c4d3e2f"
}
```

| Campo | Tipo | Descrição |
| - | - | - |
| `decision` | string | Resultado da revisão, como a Meta enviou. |

### `account.capability`

Dispara quando a Meta muda os limites da conta WhatsApp Business.

```json theme={null}
{
  "event": "account.capability",
  "apiVersion": "2026-05-13",
  "data": {
    "maxDailyConversationPerPhone": "1000",
    "maxPhoneNumbersPerBusiness": "2"
  },
  "timestamp": "2026-09-15T18:25:47.390Z",
  "organizationId": "0e4f3c1e-5b6a-4c3d-9e8f-7a6b5c4d3e2f"
}
```

| Campo | Tipo | Descrição |
| - | - | - |
| `maxDailyConversationPerPhone` | string | Conversas por dia, por número. |
| `maxPhoneNumbersPerBusiness` | string | Quantidade de números permitida na conta. |

Os dois valores vêm como string, não como número. Podem vir vazios.

## Cobranças

### `charge.sent`, `charge.paid`, `charge.failed`, `charge.canceled`, `charge.expired`

Disparam quando uma [cobrança](/cobrancas) é enviada ou muda de status, venha de onde vier: conversa, template, automação ou [link da automação](/automacoes-webhook). Os cinco eventos têm o mesmo `data`.

```json theme={null}
{
  "event": "charge.paid",
  "apiVersion": "2026-05-13",
  "data": {
    "id": "3f1c9a20-5b7d-4e8a-9c11-2d4e6f8a0b12",
    "reference_id": "pedido-1042",
    "status": "paid",
    "method": "pix",
    "amount_cents": 5990,
    "description": "Plano mensal",
    "phone": "5588999990000",
    "contact_id": "a1b2c3d4-5e6f-4a7b-8c9d-0e1f2a3b4c5d",
    "automation_id": "0e4f3c1e-5b6a-4c3d-9e8f-7a6b5c4d3e2f",
    "run_id": "7c1d2e90-4b3a-4c8e-9f21-5a6b7c8d9e01",
    "source": "hook",
    "created_at": "2026-09-20T14:02:11Z",
    "paid_at": "2026-09-20T14:09:40Z"
  },
  "timestamp": "2026-09-20T14:09:41.077Z",
  "organizationId": "0e4f3c1e-5b6a-4c3d-9e8f-7a6b5c4d3e2f"
}
```

| Campo | Tipo | Descrição |
| - | - | - |
| `id` | string (UUID) | ID da cobrança na Arara. |
| `reference_id` | string | O seu número da cobrança. |
| `status` | string | `pending`, `paid`, `failed`, `canceled` ou `expired`. |
| `method` | string | `pix`, `payment_link` ou `boleto`. |
| `amount_cents` | number | Total, em centavos. |
| `description` | string \| null | Descrição da cobrança. |
| `phone` | string | Telefone do cliente. |
| `contact_id` | string (UUID) \| null | Contato ligado à cobrança. |
| `automation_id` | string (UUID) \| null | Automação que enviou, quando houver. |
| `run_id` | string (UUID) \| null | Execução da automação que enviou, quando houver. |
| `source` | string \| null | `conversation`, `template`, `automation` ou `hook`. |
| `created_at` | string (ISO 8601) \| null | Criação da cobrança. |
| `paid_at` | string (ISO 8601) \| null | Pagamento. Só vem preenchido em cobrança paga. |

Em `charge.sent`, `status` é o status da cobrança no momento do envio, normalmente `pending`.

O código Pix e o link de pagamento nunca vão no evento. `charge.expired` dispara quando o `expiresAt` passa sem pagamento.

## Teste

### `webhook.test`

Dispara quando você usa o botão de teste na tela de [Webhooks](https://app.ararahq.com/dashboard/webhooks) do painel. Gera uma entrega real no histórico, sem efeito em mensagens, templates ou campanhas.

```json theme={null}
{
  "event": "webhook.test",
  "apiVersion": "2026-05-13",
  "data": {
    "test": true,
    "message": "Este é um teste disparado pelo dashboard. Se você está vendo isso, sua URL funciona.",
    "dispatchedAt": "2026-09-15T17:00:00Z"
  },
  "timestamp": "2026-09-15T17:00:00.052Z",
  "organizationId": "0e4f3c1e-5b6a-4c3d-9e8f-7a6b5c4d3e2f"
}
```

| Campo | Tipo | Descrição |
| - | - | - |
| `test` | boolean | Sempre `true`. |
| `message` | string | Texto fixo. |
| `dispatchedAt` | string (ISO 8601) | Quando o teste foi disparado. |

## Próximos passos

<CardGroup cols={2}>
  <Card title="Webhooks" icon="gear" href="/webhooks">
    Receptor, assinatura, retentativas e teste local.
  </Card>

  <Card title="Por que minha mensagem falhou" icon="triangle-exclamation" href="/erros-de-envio">
    O que cada motivo de falha significa.
  </Card>
</CardGroup>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.