> For the complete documentation index, see [llms.txt](https://docs.skail.dev/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.skail.dev/construa/conceitos/eventos-externos-e-correlacao.md).

# Eventos externos e correlação

Uma function pode parar e esperar algo que acontece fora dela: um webhook, uma aprovação, o retorno de outro sistema.

Esta página explica como o skail associa o disparo à espera, o que acontece quando o evento chega antes ou nunca chega, e quem dispara por onde.

<figure><img src="https://1898946878-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FsJmS5ILPG5x2x5j0WyiV%2Fuploads%2FETSEnu75UMVEGTPbcuOQ%2Fap-eventos-correlacao.svg?alt=media" alt="A espera por evento na function recebe o nome PAGAMENTO_CONFIRMADO e o instance id faturaId, e o fire de fora, POST /api/v1/fire/PAGAMENTO_CONFIRMADO/8f2c3a10-0000-4000-8000-000000000001, precisa trazer os mesmos valores, caractere a caractere. Se o evento chega antes da espera, ele fica aguardando e é entregue quando a execução alcança a espera; se nunca chega, a execução fica hibernada indefinidamente e aparece no Monitor como aguardando evento. Por isso toda espera leva um prazo: a function espera o evento e um delay, segue com o primeiro que terminar e decide entre evento ou timeout."><figcaption></figcaption></figure>

## A espera e o disparo

Na function, a espera por evento recebe um nome e um instance id e hiberna a execução até chegar um evento com esse nome e esse instance id. Do lado de fora, quem tem a informação faz `POST /api/v1/fire/{nome}/{instanceId}` na API HTTP do skail, com o payload em JSON. O disparo é uma chamada HTTP, feita de qualquer sistema, em qualquer linguagem.

{% tabs %}
{% tab title="C#" %}
{% code lineNumbers="true" %}

```csharp
var confirmacao = await SkailTask.WaitForEvent<ConfirmacaoPagamento>(Eventos.PagamentoConfirmado, faturaId.ToString());
```

{% endcode %}
{% endtab %}

{% tab title="TypeScript" %}
{% code lineNumbers="true" %}

```typescript
import { Skail, SkailFunction } from "@skail/runtime";

const Eventos = { PagamentoConfirmado: "PAGAMENTO_CONFIRMADO" } as const;

interface ConfirmacaoPagamento {
  aprovado: boolean;
  transacaoId: string;
}

export class Faturas {
  @SkailFunction()
  async aguardarPagamento(faturaId: string): Promise<ConfirmacaoPagamento> {
    const confirmacao = await Skail.waitForEvent<ConfirmacaoPagamento>(Eventos.PagamentoConfirmado, faturaId);
    return confirmacao;
  }
}
```

{% endcode %}
{% endtab %}
{% endtabs %}

```http
POST /api/v1/fire/PAGAMENTO_CONFIRMADO/8f2c3a10-0000-4000-8000-000000000001
```

## O par que correlaciona

O nome identifica o tipo do evento; o instance id identifica qual instância está sendo aguardada. Os dois precisam ser idênticos na espera e no fire, caractere a caractere. É só isso que liga o disparo à espera: o skail não olha o conteúdo do payload para decidir para quem entregar.

Por isso as duas regras práticas: o nome fica em uma constante compartilhada, nunca em strings literais espalhadas; e o instance id é um id de negócio estável que os dois lados já conhecem (o id da fatura, do pedido, da solicitação), nunca algo gerado na hora.

{% hint style="info" %}
Quando há mais de uma espera com o mesmo nome e id na mesma execução, elas são atendidas em ordem: o primeiro fire libera a primeira espera, o segundo libera a segunda.
{% endhint %}

## O evento chega antes da espera

É comum: o webhook do gateway responde em segundos, enquanto a function ainda está em um passo anterior. O evento fica aguardando e é entregue assim que a execução alcançar a espera correspondente. Você não precisa se preocupar com a ordem.

## O evento nunca chega

Se ninguém dispara, a execução fica hibernada indefinidamente. No Monitor ela aparece como aguardando evento, com o nome e o id esperados. Isso é bom para diagnosticar (nome divergente, id errado, webhook que não foi entregue) e ruim se ninguém está olhando. Por isso toda espera leva um prazo: a function espera o evento ou um delay, o que vier primeiro, e decide o que fazer no timeout. O padrão está em [Como esperar com timeout](/construa/como-fazer/esperar-um-evento-com-prazo.md).

## O payload

A espera por evento devolve o corpo do fire, que chega em JSON, no tipo que a function declarou. Quando a function só precisa saber que o evento chegou, a espera funciona como sinal e o corpo não é usado. Mantenha esse tipo pequeno, com o que a function precisa para decidir, e deixe o resto para um command carregar depois.

## Quem dispara, por onde

* O endpoint que recebe o webhook do gateway.
* A tela onde uma pessoa aprova (o BFF faz o fire).
* Um job do legado quando termina um lote.
* Um serviço em Java, Python ou outra linguagem.

Todos fazem o mesmo `POST`, com `skail-key` e `Skail-namespace` do environment. Se o disparo precisar acontecer de dentro de uma execução durável, a chamada HTTP fica em um command, como qualquer integração externa.

## Próximos passos

[Como disparar um evento pela API HTTP](/construa/como-fazer/disparar-um-evento-pela-api.md) tem o webhook completo. A referência da [espera por evento](/referencia/sdk-csharp/waitforevent.md) e de [POST /api/v1/fire](/referencia/api-http/post-fire.md) traz assinaturas, corpo e erros. [Human-in-the-loop](/construa/como-fazer/padroes-e-antipadroes/human-in-the-loop.md) é o padrão para aprovações.
