# Webhooks (https://docs.pulsarml.com/pt/webhooks)

Receba uma notificação no momento em que uma paragem de máquina começa ou termina, ou é classificada, reclassificada ou deixa de estar classificada no Pulsar.



Em vez de consultar a API periodicamente, pode fazer com que o Pulsar chame a sua aplicação quando algo acontece. Um webhook é um endpoint HTTPS alojado por si. O Pulsar envia-lhe um pedido `POST` com um corpo JSON sempre que ocorre um evento que subscreveu.

De momento, os webhooks abrangem as [paragens de máquina e as suas classificações](/pt/webhooks/events): o Pulsar avisa-o quando uma paragem começa e termina, quando uma paragem é classificada, quando uma classificação muda e quando uma é eliminada.

## Configure um webhook [#set-up-a-webhook]

<Steps>
  <Step>
    ### Crie um endpoint [#build-an-endpoint]

    Adicione à sua aplicação uma rota que aceite um `POST` com um corpo JSON e responda com um estado `2XX`. Tem de cumprir os [requisitos do endpoint](#endpoint-requirements) descritos mais abaixo.
  </Step>

  <Step>
    ### Peça ao Pulsar que o registe [#ask-pulsar-to-register-it]

    Envie ao seu contacto do Pulsar:

    * **Nome**: uma etiqueta para o endpoint, como `ERP`.
    * **URL**: o URL HTTPS completo do seu endpoint.
    * **Tipo de evento**: o [evento](/pt/webhooks/events) que deve receber.

    Cada registo recebe um único tipo de evento. Para receber vários, registe o mesmo URL uma vez por cada tipo de evento e distinga os casos por `eventType` no seu handler.
  </Step>

  <Step>
    ### Guarde o seu segredo de assinatura [#store-your-signing-secret]

    O Pulsar fornece-lhe um **segredo de assinatura**. Cada pedido que o Pulsar envia é assinado com ele, para que possa [verificar que vem realmente do Pulsar](/pt/webhooks/signatures). Mantenha-o fora do controlo de versões, como qualquer outra credencial. Há um segredo por empresa, partilhado por todos os seus endpoints.
  </Step>

  <Step>
    ### Envie um ping de teste [#send-a-test-ping]

    Peça ao Pulsar que faça ping ao seu endpoint. Receberá um [evento `Ping`](#ping-events), que confirma que o seu endpoint está acessível e que a sua verificação de assinatura funciona, antes de começarem a chegar eventos reais.
  </Step>
</Steps>

## Requisitos do endpoint [#endpoint-requirements]

O Pulsar só entrega a endpoints que sejam:

* **HTTPS públicos.** O URL tem de usar `https://`, ter no máximo 255 caracteres e não incluir credenciais (`user:pass@`) nem `#fragmento`. O nome de anfitrião tem de resolver para endereços IP públicos. Os endereços privados, de loopback e link-local são recusados.
* **Rápidos.** Cada pedido tem um limite de **10 segundos**, incluindo a resolução DNS e o estabelecimento da ligação.
* **Definitivos.** Os redirecionamentos **não são seguidos**. Uma resposta `3XX` conta como entrega falhada, por isso registe o URL final.

## O pedido [#the-request]

Cada notificação é um `POST` com um corpo JSON e estes cabeçalhos:

```http
POST /webhooks/pulsar HTTP/1.1
Host: example.com
Content-Type: application/json
X-Pulsar-Signature: 5c0e2f4a1b9d8e7f6a5b4c3d2e1f0a9b8c7d6e5f4a3b2c1d0e9f8a7b6c5d4e3f
X-Pulsar-Event-Type: MachineStopClassificationCreated
X-Pulsar-Event-Id: 8d2f6c1e-4b7a-4f0e-9a3c-5e1d7b9f2a64
X-Pulsar-Timestamp: 2026-09-25T14:03:12.482Z
X-Pulsar-Request-Id: 3f9b2c7d-1e4a-4c8b-b6d2-9a0e5f7c1b38

{
  "eventId": "8d2f6c1e-4b7a-4f0e-9a3c-5e1d7b9f2a64",
  "eventTimestamp": "2026-09-25T14:03:12.482Z",
  "eventType": "MachineStopClassificationCreated",
  "event": { ... }
}
```

### Cabeçalhos [#headers]

| Cabeçalho             | Descrição                                                                                                    |
| --------------------- | ------------------------------------------------------------------------------------------------------------ |
| `Content-Type`        | Sempre `application/json`.                                                                                   |
| `X-Pulsar-Signature`  | Assinatura HMAC-SHA256 do corpo em bruto. [Verifique-a](/pt/webhooks/signatures) antes de confiar no pedido. |
| `X-Pulsar-Event-Type` | O tipo de evento, igual a `eventType` no corpo.                                                              |
| `X-Pulsar-Event-Id`   | O ID do evento, igual a `eventId` no corpo.                                                                  |
| `X-Pulsar-Timestamp`  | Igual a `eventTimestamp` no corpo.                                                                           |
| `X-Pulsar-Request-Id` | O ID desta tentativa de entrega. Inclua-o quando contactar o suporte do Pulsar sobre uma entrega.            |

Os nomes dos cabeçalhos não distinguem maiúsculas de minúsculas, por isso a sua framework pode mostrá-los em minúsculas.

### Corpo [#body]

Todas as notificações têm o mesmo envelope:

| Campo            | Tipo   | Descrição                                                                                                                               |
| ---------------- | ------ | --------------------------------------------------------------------------------------------------------------------------------------- |
| `eventId`        | string | ID único do evento. **Mantém-se igual entre novas tentativas**, por isso use-o para detetar duplicados.                                 |
| `eventTimestamp` | string | Quando o Pulsar colocou o evento em fila, como carimbo de data/hora UTC ISO 8601. Não é o momento em que a alteração ocorreu no Pulsar. |
| `eventType`      | string | O [tipo de evento](/pt/webhooks/events), por exemplo `MachineStopClassificationCreated`.                                                |
| `event`          | object | Os dados do evento. A sua forma depende de `eventType`; consulte [Eventos](/pt/webhooks/events).                                        |

## Responda com um 2XX, rapidamente [#respond-with-a-2xx-quickly]

Devolva um estado `2XX` assim que tiver [verificado a assinatura](/pt/webhooks/signatures). O Pulsar só lê o código de estado e ignora o corpo da resposta.

* Devolva `200` se já processou o evento.
* Devolva `202` se o colocou em fila para mais tarde.

Faça qualquer tarefa lenta, como chamar outros sistemas ou trabalho pesado de base de dados, numa tarefa em segundo plano depois de responder. Uma resposta que demore mais de 10 segundos conta como falha e é repetida, mesmo que o seu código acabe por terminar.

## Novas tentativas [#retries]

O que o Pulsar faz com uma entrega falhada depende do motivo da falha:

| O seu endpoint...                                                          | O Pulsar...                                                                                                                                                  |
| -------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| Devolve `2XX`                                                              | Marca a entrega como concluída.                                                                                                                              |
| Excede o tempo limite, não está acessível ou devolve `408`, `429` ou `5XX` | Faz até 3 tentativas seguidas, com backoff exponencial, respeitando um cabeçalho `Retry-After` curto. Se as 3 falharem, volta a tentar a entrega mais tarde. |
| Devolve qualquer outro `4XX`, ou um redirecionamento `3XX`                 | **Não volta a tentar.** A entrega fica registada como falhada, e o Pulsar pode reenviá-la quando o seu endpoint estiver corrigido.                           |

<Callout type="warn" title="Uma resposta 4XX interrompe as novas tentativas">
  O Pulsar interpreta `400`, `401`, `403`, `404` e a maioria dos outros códigos `4XX` como uma rejeição deliberada do evento por parte do seu endpoint, por isso não volta a tentar. Se um erro no seu handler devolver um `4XX` para eventos válidos, esses eventos ficam à espera até o Pulsar os reenviar. Use `5XX` para problemas temporários do seu lado.
</Callout>

Um endpoint que falha não atrasa as entregas aos seus outros endpoints.

## Duplicados e ordem [#duplicates-and-ordering]

A entrega é **pelo menos uma vez**. Ocasionalmente, o mesmo evento chega ao seu endpoint mais de uma vez, por exemplo quando o seu endpoint processou um pedido mas o Pulsar não registou a resposta a tempo. Um evento repetido também chega mais tarde do que os eventos entregues à primeira tentativa, por isso a ordem não é garantida.

Faça com que o seu handler possa ser executado duas vezes sem problemas: guarde cada `eventId` que processar e ignore os que já tiver visto. Uma nova tentativa ou um reenvio leva sempre o `eventId` original.

## Eventos Ping [#ping-events]

Um ping testa o seu endpoint sem esperar por um evento real. Usa os mesmos cabeçalhos e a mesma assinatura que qualquer outra notificação, tem `eventType` igual a `Ping` e o seu `event` é sempre `{ "text": "ping" }`:

```json
{
  "eventId": "0b6f3d2a-9c1e-4a7b-8f5d-2e4c6a8b0d1f",
  "eventTimestamp": "2026-09-25T14:00:00.000Z",
  "eventType": "Ping",
  "event": {
    "text": "ping"
  }
}
```

Um ping pode chegar a um endpoint seja qual for o tipo de evento para que está registado, por isso responda `2XX` a `Ping` em vez de rejeitar os tipos de evento que não esperava.

## Próximos passos [#next-steps]

<Cards>
  <Card title="Verificar assinaturas" href="/pt/webhooks/signatures" description="Confirme que cada pedido vem realmente do Pulsar." />

  <Card title="Eventos" href="/pt/webhooks/events" description="Todos os tipos de evento e os campos que incluem." />
</Cards>
