# API pública O365Sign — v1

Autenticação: `Authorization: Bearer o365_...` (crie a chave em **Contratos → Configurações →
Integrações**, com os escopos `contracts:read` e/ou `contracts:write`).
Base: `https://sign365.com.br/public/v1`

## Endpoints

| Método | Rota | Escopo | O que faz |
|---|---|---|---|
| GET  | /contracts | contracts:read | Lista contratos (`status`, `page`, `page_size`) |
| POST | /contracts | contracts:write | Cria e (opcional) envia |
| GET  | /contracts/{id} | contracts:read | Detalhe + signatários + links |
| POST | /contracts/{id}/send | contracts:write | Envia para assinatura |
| POST | /contracts/{id}/remind | contracts:write | Cobra quem não assinou |
| POST | /contracts/{id}/cancel | contracts:write | Cancela (`?motivo=`) |
| GET  | /contracts/{id}/evidence | contracts:read | Pacote de comprovação (JSON) |
| GET  | /templates | contracts:read | Modelos disponíveis |

## Criar e enviar

```bash
curl -X POST https://sign365.com.br/public/v1/contracts \
  -H "Authorization: Bearer o365_sua_chave" \
  -H "Content-Type: application/json" \
  -d '{
    "titulo": "Prestação de serviços — Obra X",
    "template_id": 3,
    "contraparte": {"razao_social": "Cliente LTDA", "doc": "11222333000181"},
    "financeiro": {"valor_total": 48500, "parcelas": 4},
    "valores": {"escopo": "instalação elétrica", "prazo": "90 dias"},
    "signatarios": [
      {"nome": "Ana Souza", "email": "ana@cliente.com.br", "whatsapp": "19999998888"}
    ],
    "canais": ["whatsapp", "email"],
    "enviar": true
  }'
```

A resposta traz `numero`, `status`, `hash_documento` e o `link` individual de cada signatário.

## Webhooks

Configure a URL em **Configurações → Integrações**. Cada evento chega assim:

```json
{"evento":"contract.signed","enviado_em":"2026-07-26T09:00:00Z","ambiente_id":12,
  "dados":{"envelope_id":98,"numero":"CT-2026-00007","status":"completed","crm_item_id":2425}}
```

Eventos: `contract.sent`, `contract.viewed`, `contract.signed`, `contract.declined`,
`contract.expired`.

**Confira a assinatura** antes de confiar no corpo — header
`X-O365Sign-Signature: sha256=<hmac>`, HMAC-SHA256 do corpo cru com o seu segredo:

```python
import hmac, hashlib
esperado = "sha256=" + hmac.new(segredo.encode(), corpo_cru, hashlib.sha256).hexdigest()
assert hmac.compare_digest(esperado, request.headers["X-O365Sign-Signature"])
```

Retentativas: 6 tentativas com espera crescente (1, 5, 15, 60, 180 e 720 minutos).
Responda 2xx para confirmar o recebimento.

## Verificação pública de um documento

`GET https://sign365.com.br/verificar/{hash_sha256}` — página aberta, sem autenticação, que confirma
se um PDF em mãos é o mesmo que foi assinado.
