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

# Webhook genérico

> Envie alertas de qualquer sistema com um POST JSON simples.

## Visão geral

O webhook genérico aceita um JSON simples de qualquer sistema capaz de fazer um `POST` — scripts, CI/CD, jobs internos, ferramentas sem integração dedicada.

|                    |              |
| ------------------ | ------------ |
| **Tipo de fonte**  | `Genérico`   |
| **Mecanismo**      | `POST` JSON  |
| **Correlação**     | `externalId` |
| **Auto-resolução** | —            |

<Warning>
  O webhook genérico **não resolve acionamentos automaticamente**. Ele sempre abre ou agrega. Se a sua ferramenta tem tipo de fonte dedicado (Grafana, Prometheus, Datadog, CloudWatch, Zabbix, New Relic), use esse tipo — você ganha auto-resolução e um mapeamento de campos muito melhor.
</Warning>

## 1. Crie a fonte de alerta

Em **Fontes de alerta**, crie uma fonte do tipo **Genérico**. Copie a URL e o token.

## 2. Envie o alerta

```bash theme={null}
curl -X POST "https://ingress.aciona.me/webhooks/<idDaFonte>" \
  -H "Content-Type: application/json" \
  -H "X-Aciona-Token: <tokenDaFonte>" \
  -d '{
    "externalId": "job-etl-noturno",
    "title": "Job de ETL noturno falhou",
    "description": "Saída com código 1 após 3 tentativas",
    "severity": "high",
    "service": "pipeline-dados",
    "status": "firing",
    "labels": { "env": "prod", "job": "etl-noturno" },
    "url": "https://ci.exemplo.com/builds/4821"
  }'
```

Resposta esperada: `202 Accepted`.

## Campos aceitos

| Campo         | Tipo   | Obrigatório | Descrição                                                                   |
| ------------- | ------ | ----------- | --------------------------------------------------------------------------- |
| `title`       | string | recomendado | Título do acionamento. Sem ele, vira `Untitled alert`.                      |
| `description` | string | não         | Detalhe do problema.                                                        |
| `severity`    | string | não         | `critical`, `high`, `warning`, `info` ou sinônimos. Padrão: `warning`.      |
| `service`     | string | recomendado | Nome do serviço no aciona.me. Também aceito como `labels.service`.          |
| `externalId`  | string | recomendado | Identificador estável do problema. É a chave de correlação.                 |
| `status`      | string | não         | `firing` ou `alerting`. Qualquer outro valor faz o alerta ser **ignorado**. |
| `labels`      | objeto | não         | Rótulos livres, preservados no acionamento.                                 |
| `url`         | string | não         | Link de volta para a origem. Também aceito como `externalUrl`.              |

<Note>
  Se `status` estiver **ausente**, o alerta é tratado como disparo. Se estiver presente com um valor diferente de `firing` ou `alerting`, o alerta é aceito com `202` mas **nenhum acionamento é criado** — inclusive para `resolved`.
</Note>

## Agrupamento

Envios repetidos com o mesmo `externalId` para o mesmo serviço são **agregados** ao acionamento aberto, em vez de criar duplicatas. Use um `externalId` estável por problema — o nome do job, o identificador do check, a chave da regra.

<Tip>
  Se você omitir `externalId`, a correlação recai sobre uma assinatura calculada a partir do conteúdo. Mudanças no título ou na descrição passam a gerar acionamentos separados. Sempre que possível, envie um `externalId`.
</Tip>

## Exemplos

<CodeGroup>
  ```bash curl theme={null}
  curl -X POST "https://ingress.aciona.me/webhooks/$ACIONA_SOURCE_ID" \
    -H "Content-Type: application/json" \
    -H "X-Aciona-Token: $ACIONA_TOKEN" \
    -d "{\"externalId\":\"backup-diario\",\"title\":\"Backup diário falhou\",\"severity\":\"critical\",\"service\":\"banco-principal\",\"status\":\"firing\"}"
  ```

  ```python Python theme={null}
  import os
  import requests

  requests.post(
      f"https://ingress.aciona.me/webhooks/{os.environ['ACIONA_SOURCE_ID']}",
      headers={"X-Aciona-Token": os.environ["ACIONA_TOKEN"]},
      json={
          "externalId": "backup-diario",
          "title": "Backup diário falhou",
          "description": "pg_dump retornou código 2",
          "severity": "critical",
          "service": "banco-principal",
          "status": "firing",
          "labels": {"env": "prod"},
      },
      timeout=10,
  )
  ```

  ```javascript Node.js theme={null}
  await fetch(
    `https://ingress.aciona.me/webhooks/${process.env.ACIONA_SOURCE_ID}`,
    {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'X-Aciona-Token': process.env.ACIONA_TOKEN,
      },
      body: JSON.stringify({
        externalId: 'backup-diario',
        title: 'Backup diário falhou',
        severity: 'critical',
        service: 'banco-principal',
        status: 'firing',
      }),
    },
  );
  ```

  ```yaml GitHub Actions theme={null}
  - name: Acionar o time em caso de falha
    if: failure()
    run: |
      curl -X POST "https://ingress.aciona.me/webhooks/${{ secrets.ACIONA_SOURCE_ID }}" \
        -H "Content-Type: application/json" \
        -H "X-Aciona-Token: ${{ secrets.ACIONA_TOKEN }}" \
        -d '{
          "externalId": "deploy-${{ github.repository }}",
          "title": "Deploy falhou em ${{ github.repository }}",
          "severity": "high",
          "service": "plataforma",
          "status": "firing",
          "url": "${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}"
        }'
  ```
</CodeGroup>

## Solução de problemas

<AccordionGroup>
  <Accordion title="Respondeu 202 mas nenhum acionamento apareceu" icon="ghost">
    O campo `status` provavelmente tem um valor diferente de `firing` ou `alerting` — nesse caso o alerta é aceito e descartado. Envie `firing` ou omita o campo.
  </Accordion>

  <Accordion title="Acionamentos duplicados" icon="copy">
    O `externalId` está mudando entre os envios (por exemplo, incluindo um timestamp). Use um identificador estável por problema.
  </Accordion>

  <Accordion title="Acionamento sem serviço ou sem responsável" icon="user-x">
    O campo `service` não bate com nenhum serviço da organização, ou o serviço não tem time responsável com escala ativa.
  </Accordion>

  <Accordion title="Como resolver o acionamento?" icon="check-check">
    Pelo painel ou pelo app. O webhook genérico não resolve automaticamente.
  </Accordion>
</AccordionGroup>

<Card title="Referência completa do payload" icon="list" href="/pt-br/referencia/payload-webhook-generico" horizontal />
