# Ser avisado quando ganho ou perco uma venda

> Crie um webhook no GS Engage para receber os eventos prospection.won e prospection.lost em tempo real, sem precisar ficar consultando a API.

- URL canônica: https://docs.growthstation.app/docs/api/guias/avisos-de-venda-webhook
- Idioma: pt-BR
- Última atualização: 2026-09-20T08:21:20.450Z
- Produto: GS Engage
- Mantido por: Produto GS Engage



<PageHero emoji="🔔" title="Ser avisado quando ganho ou perco uma venda" description="Crie um webhook e deixe o GS Engage avisar seu sistema no exato momento em que uma prospecção é ganha ou perdida." gradient="brand" />

Imagine que toda vez que um vendedor marca uma prospecção como <TextHighlight>Ganha</TextHighlight> ou <TextHighlight>Perdida</TextHighlight>, você quer disparar uma comemoração no canal do time, atualizar seu CRM ou registrar a venda numa planilha. Você poderia ficar perguntando à API de tempos em tempos "e agora, mudou?" — mas isso é trabalhoso e desperdiça requisições.

Existe um jeito melhor: o **webhook**. Um webhook é um aviso automático — em vez de você perguntar, o GS Engage é quem te avisa. Você diz "quando acontecer X, me mande um recado nesta URL", e a partir daí cada evento chega sozinho no seu sistema.

Este guia é para quem quer reagir em tempo real ao resultado de uma venda: `prospection.won` (ganhou) e `prospection.lost` (perdeu).

<Callout type="info">
  Uma **prospecção** é o trabalho de um vendedor em cima de um lead dentro de uma **Cadência**. Quando ela termina, recebe um status: `WON` (Ganha) ou `LOST` (Perdida). É exatamente esse momento que os eventos deste guia capturam.
</Callout>

🎯 O que você vai conseguir no final [#-o-que-você-vai-conseguir-no-final]

<Checklist id="webhook-vendas-objetivo" title="Ao terminar este guia, você terá">
  <ChecklistItem>
    Escolhido os eventos que interessam (ganho e perda de venda).
  </ChecklistItem>

  <ChecklistItem>
    Criado um webhook apontando para a sua URL.
  </ChecklistItem>

  <ChecklistItem>
    Guardado o 

    <TextHighlight>secret</TextHighlight>

     (a senha da assinatura) com segurança.
  </ChecklistItem>

  <ChecklistItem>
    Recebido e entendido um evento de exemplo (

    `prospection.won`

    ).
  </ChecklistItem>
</Checklist>

🗺️ Como funciona, em um desenho [#️-como-funciona-em-um-desenho]

<Mermaid
  chart={`sequenceDiagram
  participant V as Vendedor (no app)
  participant GS as GS Engage
  participant U as Sua URL
  V->>GS: Marca a prospecção como Ganha
  GS->>U: POST com o evento prospection.won
  U-->>GS: Responde 200 OK
  Note over GS,U: Se sua URL falhar, o GS reenvia (retries)`}
/>

🧩 Passo 1 — Escolha os eventos [#-passo-1--escolha-os-eventos]

Antes de criar o webhook, decida **o que** você quer ouvir. Para "ganhei ou perdi uma venda", os eventos são:

| Evento             | Quando dispara                                | Rótulo no app    |
| ------------------ | --------------------------------------------- | ---------------- |
| `prospection.won`  | O vendedor finaliza a prospecção como ganha   | Ganha (`WON`)    |
| `prospection.lost` | O vendedor finaliza a prospecção como perdida | Perdida (`LOST`) |

Existem outros eventos disponíveis, caso você queira acompanhar mais coisas depois:

| Evento                | O que sinaliza                            |
| --------------------- | ----------------------------------------- |
| `prospection.started` | Uma prospecção começou                    |
| `activity.finished`   | Uma atividade da cadência foi concluída   |
| `call.started`        | Uma ligação começou                       |
| `call.finished`       | Uma ligação terminou                      |
| `call.transcribed`    | A transcrição de uma ligação ficou pronta |

<Callout type="tip">
  Assine só os eventos que você realmente vai usar. Menos eventos = menos ruído chegando na sua URL e menos código para tratar.
</Callout>

🛠️ Passo 2 — Crie o webhook [#️-passo-2--crie-o-webhook]

Agora é hora de registrar o webhook. Você faz isso chamando o **endpoint** (um endereço da API que executa uma ação) `POST /api/v1/webhooks`.

Você precisa informar três coisas:

<FieldInfoGroup>
  <FieldInfo title="name" required>
    Um nome para você reconhecer o webhook depois. Ex.: "Avisos de venda".
  </FieldInfo>

  <FieldInfo title="url" required>
    O endereço público que vai receber os avisos. É para essa URL que o GS Engage vai enviar cada evento.
  </FieldInfo>

  <FieldInfo title="events" required>
    A lista de eventos que você escolheu no passo anterior.
  </FieldInfo>
</FieldInfoGroup>

Lembre-se: a autenticação do GS Engage vai na URL, como um parâmetro `?apiKey=SUA_CHAVE`. A chave (com cerca de 40 caracteres) é criada na plataforma em <TextHighlight>Configurações › Configurações de API</TextHighlight>.

<Callout type="danger" title="Sua apiKey é uma senha">
  Como a chave vai na URL, ela aparece em logs de servidor, histórico do navegador e links compartilhados. Trate como senha: guarde em variável de ambiente e nunca cole em canais públicos.
</Callout>

Veja a criação, com curl e com JSON puro:

<Tabs items={['curl', 'Corpo (JSON)']}>
  <Tab value="curl">
    ```bash
    curl -X POST "https://api.gsengage.com/api/v1/webhooks?apiKey=$GS_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{
        "name": "Avisos de venda",
        "url": "https://seu-sistema.com.br/webhooks/gsengage",
        "events": ["prospection.won", "prospection.lost"]
      }'
    ```
  </Tab>

  <Tab value="Corpo (JSON)">
    ```json
    {
      "name": "Avisos de venda",
      "url": "https://seu-sistema.com.br/webhooks/gsengage",
      "events": ["prospection.won", "prospection.lost"]
    }
    ```
  </Tab>
</Tabs>

A resposta traz os dados do webhook criado — e, junto, o campo `secret`:

```json
{
  "id": "6650f1a2b3c4d5e6f7a8b9c0",
  "name": "Avisos de venda",
  "url": "https://seu-sistema.com.br/webhooks/gsengage",
  "events": ["prospection.won", "prospection.lost"],
  "secret": "whsec_9f8e7d6c5b4a3210fedcba9876543210"
}
```

O `secret` é o segredo usado para confirmar que o aviso veio mesmo do GS Engage (e não de um impostor). Você vai precisar dele para validar a assinatura de cada entrega.

🔐 Passo 3 — Guarde o secret AGORA [#-passo-3--guarde-o-secret-agora]

<Callout type="danger" title="O secret aparece uma única vez">
  O campo `secret` é retornado **apenas** nesta resposta de criação. Ele **não** aparece de novo em nenhuma outra chamada. Se você fechar o terminal sem copiá-lo, não tem como recuperá-lo — só criando um novo webhook.
</Callout>

<DoDont>
  <DoDontItem type="do">
    Copie o 

    `secret`

     e guarde-o em uma variável de ambiente ou cofre de segredos assim que a resposta chegar.
  </DoDontItem>

  <DoDontItem type="do">
    Use o 

    `secret`

     para validar a assinatura de cada entrega recebida.
  </DoDontItem>

  <DoDontItem type="dont">
    Não deixe o 

    `secret`

     só rolando no histórico do terminal ou colado num chat.
  </DoDontItem>

  <DoDontItem type="dont">
    Não confie em um evento recebido sem antes conferir a assinatura.
  </DoDontItem>
</DoDont>

<Callout type="warning">
  Não existe ambiente de teste (sandbox) separado no GS Engage: toda chamada é real e afeta dados de produção. Criar um webhook é seguro, mas tenha atenção redobrada com endpoints de escrita ao experimentar.
</Callout>

📦 Passo 4 — Entenda o aviso que você recebe [#-passo-4--entenda-o-aviso-que-você-recebe]

Quando um evento acontece, o GS Engage faz um `POST` para a sua URL. O corpo sempre vem no mesmo formato — chamamos isso de **envelope**:

<FieldInfoGroup>
  <FieldInfo title="id">
    Identificador único desta entrega.
  </FieldInfo>

  <FieldInfo title="test">
    `true`

     se for um disparo de teste; 

    `false`

     para eventos reais.
  </FieldInfo>

  <FieldInfo title="event">
    O nome do evento, ex.: 

    `prospection.won`

    .
  </FieldInfo>

  <FieldInfo title="data">
    Os dados do que aconteceu (a prospecção, o lead, etc.).
  </FieldInfo>

  <FieldInfo title="retries">
    Quantas vezes o GS Engage já tentou reenviar automaticamente.
  </FieldInfo>

  <FieldInfo title="manualRetries">
    Quantas vezes a entrega foi reenviada manualmente.
  </FieldInfo>

  <FieldInfo title="createdAt">
    Data e hora em que a entrega foi gerada.
  </FieldInfo>
</FieldInfoGroup>

Exemplo de um evento `prospection.won` chegando na sua URL:

```json
{
  "id": "del_7a1b2c3d4e5f6a7b8c9d0e1f",
  "test": false,
  "event": "prospection.won",
  "data": {
    "prospection": {
      "id": "6650a1b2c3d4e5f6a7b8c9d0",
      "status": "WON",
      "lead": {
        "id": "6650000011112222aaaabbbb",
        "name": "Marina Souza - Padaria Pão Quente"
      }
    }
  },
  "retries": 0,
  "manualRetries": 0,
  "createdAt": "2026-07-17T14:32:10.000Z"
}
```

O que isso significa para o negócio: a prospecção com status `WON` (Ganha) fechou. É o gatilho perfeito para comemorar no time, marcar a venda no seu CRM ou atualizar um painel de metas. Para uma perda, o mesmo envelope chega com `"event": "prospection.lost"` e o status `LOST`.

<Callout type="tip" title="Responda rápido">
  Ao receber um aviso, responda `200 OK` o mais rápido possível. Se a sua URL demorar ou falhar, o GS Engage entende que a entrega não chegou e vai reenviar — por isso o campo `retries` existe.
</Callout>

🧪 Como testar sem escrever um servidor [#-como-testar-sem-escrever-um-servidor]

Você não precisa ter um sistema pronto para ver os avisos chegando. Use um **coletor de webhooks** — uma URL temporária que mostra na tela tudo o que recebe.

<Steps>
  <Step num={1} title="Pegue uma URL de teste">
    Abra um coletor como o [webhook.site](https://webhook.site) e copie a URL única que ele gera para você.
  </Step>

  <Step num={2} title="Crie o webhook apontando para ela">
    Use o `POST /api/v1/webhooks` do Passo 2, colocando essa URL de teste no campo `url`.
  </Step>

  <Step num={3} title="Provoque um evento no app">
    Peça a um vendedor para finalizar uma prospecção como <TextHighlight>Ganha</TextHighlight> (ou finalize você mesmo). Em segundos, o envelope aparece na tela do coletor.
  </Step>

  <Step num={4} title="Inspecione o corpo">
    Confira os campos `event`, `data` e o cabeçalho de assinatura. Assim você entende o formato antes de escrever qualquer linha de código.
  </Step>
</Steps>

<Callout type="warning">
  Coletores públicos mostram tudo que recebem para qualquer um com o link. Use-os só para **entender o formato** — nunca deixe dados sensíveis de produção fluindo para uma URL pública em definitivo.
</Callout>

✅ Confirme que o aviso é autêntico [#-confirme-que-o-aviso-é-autêntico]

Como a sua URL é pública, qualquer um poderia tentar enviar um POST fingindo ser o GS Engage. Para garantir que o aviso é legítimo, cada entrega vem **assinada**.

A assinatura usa **HMAC SHA-256** — uma técnica que combina o corpo da mensagem com o seu `secret` para gerar um código. Você recalcula esse código do seu lado e compara com o que veio no cabeçalho. Se baterem, o aviso é autêntico.

<Callout type="info">
  A assinatura migrou de SHA-1 para SHA-256. Certifique-se de usar **SHA-256** ao validar.
</Callout>

O passo a passo completo, com código de exemplo, está no guia dedicado:

<CardGrid cols={1}>
  <CardLink href="/docs/api/guias/validar-assinatura-webhook" icon="🔐" title="Validar a assinatura de um webhook" span>
    Recalcule o HMAC SHA-256 com o seu secret e confirme que o evento veio mesmo do GS Engage.
  </CardLink>
</CardGrid>

🧹 Listar e remover webhooks [#-listar-e-remover-webhooks]

Depois de criar, você vai querer conferir o que está ativo e, eventualmente, desligar o que não usa mais.

Ver os webhooks que existem [#ver-os-webhooks-que-existem]

Use `GET /api/v1/webhooks`. Atenção: essa rota devolve os itens em `data`, mas **sem** `meta` (retorna todos, sem paginação): `{ "data": [ ... ] }`.

```bash
curl "https://api.gsengage.com/api/v1/webhooks?apiKey=$GS_API_KEY"
```

```json
[
  {
    "id": "6650f1a2b3c4d5e6f7a8b9c0",
    "name": "Avisos de venda",
    "url": "https://seu-sistema.com.br/webhooks/gsengage",
    "events": ["prospection.won", "prospection.lost"]
  }
]
```

O `secret` **não** volta aqui — ele só existiu na resposta de criação.

Remover um webhook [#remover-um-webhook]

Use `DELETE /api/v1/webhooks/{webhookId}`, colocando o `id` do webhook. Uma remoção bem-sucedida responde com **HTTP 204** (sucesso, sem conteúdo no corpo).

```bash
curl -X DELETE "https://api.gsengage.com/api/v1/webhooks/6650f1a2b3c4d5e6f7a8b9c0?apiKey=$GS_API_KEY"
```

<Callout type="tip">
  Remover um webhook para os avisos imediatamente. Se você só quer trocar a URL ou os eventos, o caminho é remover o antigo e criar um novo — lembrando de guardar o novo `secret`.
</Callout>

🚦 Fique de olho no rate limit [#-fique-de-olho-no-rate-limit]

A API tem um **rate limit** (limite de requisições em um intervalo): janela fixa de 60 segundos, com 200 leituras/min e 100 escritas/min. Ao exceder, você recebe **HTTP 429** com o cabeçalho `Retry-After` (em segundos).

Isso vale para as suas chamadas de **gerenciamento** dos webhooks (criar, listar, remover) — não para os avisos que você recebe. A boa prática é usar backoff exponencial, respeitando o `Retry-After`.

🔌 Prefere não escrever código? [#-prefere-não-escrever-código]

Dá para reagir a esses eventos sem programar. O GS Engage expõe gatilhos nativos no **Zapier**, e ferramentas como **Make** e **n8n** também conseguem receber webhooks e consumir a API REST.

<PromoCard href="https://zapier.com" icon="⚡" title="Integrar via Zapier" color="amber">
  Use os gatilhos de webhook do GS Engage para acionar milhares de apps sem escrever código.
</PromoCard>

❓ Perguntas frequentes [#-perguntas-frequentes]

<FAQ>
  <FAQItem question="Perdi o secret. E agora?">
    O `secret` só aparece na resposta de criação e não pode ser recuperado. Remova o webhook antigo com `DELETE` e crie um novo com `POST` — desta vez, guarde o `secret` na hora.
  </FAQItem>

  <FAQItem question="Preciso ter um servidor pronto para criar o webhook?">
    Não. Para testar, use um coletor como o webhook.site e aponte a `url` para ele. Assim você vê os eventos chegando antes de construir qualquer coisa.
  </FAQItem>

  <FAQItem question="Como sei se é uma venda ganha ou perdida?">
    Pelo campo `event` do envelope: `prospection.won` é ganha (`WON`) e `prospection.lost` é perdida (`LOST`). O status também aparece dentro de `data`.
  </FAQItem>

  <FAQItem question="Um mesmo webhook pode ouvir vários eventos?">
    Sim. Basta listar todos no array `events` na criação, por exemplo `["prospection.won", "prospection.lost"]`.
  </FAQItem>

  <FAQItem question="O que faço se minha URL ficar fora do ar na hora do evento?">
    O GS Engage tenta reenviar automaticamente — é o que o campo `retries` acompanha. Ainda assim, responda `200 OK` rápido para evitar reenvios desnecessários.
  </FAQItem>
</FAQ>

Artigos Relacionados [#artigos-relacionados]

<RelatedArticles>
  <RelatedArticle href="/docs/api/guias/validar-assinatura-webhook" title="Validar a assinatura de um webhook" description="Confirme que o evento veio mesmo do GS Engage usando HMAC SHA-256." />

  <RelatedArticle href="/docs/api/comece-aqui/quickstart" title="Primeiros passos com a API" description="Crie sua apiKey e valide a chave com uma chamada de leitura." />

  <RelatedArticle href="/docs/api/referencia" title="Finalizar uma prospecção" description="Marque uma prospecção como Ganha ou Perdida — o gatilho destes eventos." />

  <RelatedArticle href="/docs/api/referencia" title="Referência de Webhooks" description="Todos os endpoints, campos e eventos de webhook em um só lugar." />
</RelatedArticles>
