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

# Saber na hora quando a paciente assina

> Assine signature_request.completed e libere o procedimento, a nota fiscal ou a agenda no momento em que o último documento é assinado.

A pergunta mais comum de quem integra é "a paciente já assinou?". Não pergunte: assine o evento.

**1. Cadastre o webhook**

```bash theme={null}
curl https://api.westhetics.io/v1/webhooks \
  -H "Authorization: Bearer $WESTHETICS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://crm.exemplo.com.br/webhooks/westhetics",
    "description": "Assinaturas",
    "events": ["signature_request.completed", "signature_request.declined", "signature_request.expired"]
  }'
```

O app precisa de **Documentos e assinaturas · Ler** para ver esses eventos e de **Gerenciar os próprios webhooks pela API** para cadastrar. Sem o segundo, a gestora cadastra na tela do app.

**2. Receba e confira**

```javascript theme={null}
import { Webhook } from 'standardwebhooks'

const wh = new Webhook(process.env.WESTHETICS_WEBHOOK_SECRET)

app.post('/webhooks/westhetics', express.raw({ type: 'application/json' }), async (req, res) => {
  let event
  try {
    event = wh.verify(req.body, req.headers)
  } catch {
    return res.status(400).end()
  }
  if (await alreadyHandled(req.headers['webhook-id'])) return res.status(204).end()

  if (event.type === 'signature_request.completed') {
    await markSaleAsSigned(event.data.appointmentId, event.data.protocolNumber)
  }
  res.status(204).end()
})
```

Responda `2xx` em até 10 segundos e deixe o trabalho pesado para uma fila. A verificação completa, em outras linguagens, está em [verificar a assinatura](https://docs.westhetics.io/webhooks/verificar-assinatura.md).

**3. Busque o que precisar**

O evento é fino: traz os ids e o protocolo. O atendimento inteiro, com valor, procedimentos e documentos, vem de `GET /v1/appointments/{appointmentId}`; o PDF assinado, de `GET /v1/documents/{id}/file`.

## Os eventos de uma assinatura

| Evento | Quando |
| - | - |
| `signature_request.sent` | o link saiu, depois da janela de 10 segundos |
| `signature_request.viewed` | a paciente abriu o link |
| `signature_request.signed` | alguém assinou; `data.signer` diz quem: `patient`, `guardian` ou `clinic` |
| `signature_request.completed` | todos assinaram todos os documentos: é este que marca a venda |
| `signature_request.declined` | a paciente recusou |
| `signature_request.expired` | o link de 7 dias venceu sem todas as assinaturas |
| `signature_request.canceled` | a clínica cancelou o envio |
| `signature_request.delivery_failed` | a mensagem não chegou por um canal (`data.channel`) |

A ordem de chegada não é garantida. Ordene por `createdAt` e trate `completed` como estado final, mesmo que um `signed` chegue depois.


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