API
Webhooks
Receber notificações de eventos em tempo real via webhooks.
Webhooks
Receba notificações em tempo real quando eventos ocorrem no OctaBuild. Webhooks permitem que sua aplicação reaja automaticamente a mudanças em terrenos, empreendimentos, unidades e registros financeiros.
Webhooks estão em desenvolvimento. Esta documentação descreve a interface planejada.
Como Funciona
OctaBuild Sua Aplicação
│ │
│ 1. Evento ocorre │
│ (ex: terreno criado) │
│ │
│ 2. POST com payload ──────────► │
│ │
│ ◄──────── 3. Responde 200 OK │
│ │Eventos Disponíveis
Terrenos
| Evento | Descrição |
|---|---|
land_plot.created | Terreno cadastrado |
land_plot.updated | Terreno atualizado |
land_plot.status_changed | Status do terreno alterado |
land_plot.score_updated | Score IA recalculado |
land_plot.deleted | Terreno removido |
Empreendimentos
| Evento | Descrição |
|---|---|
development.created | Empreendimento criado |
development.updated | Empreendimento atualizado |
development.phase_changed | Fase do empreendimento alterada |
development.archived | Empreendimento arquivado |
Unidades
| Evento | Descrição |
|---|---|
unit.created | Unidade cadastrada |
unit.updated | Unidade atualizada |
unit.status_changed | Status da unidade alterado |
unit.bulk_created | Unidades criadas em lote |
Clientes
| Evento | Descrição |
|---|---|
client.created | Cliente cadastrado |
client.updated | Cliente atualizado |
client.deactivated | Cliente desativado |
Financeiro
| Evento | Descrição |
|---|---|
financial.payable_created | Conta a pagar criada |
financial.payable_paid | Conta a pagar quitada |
financial.receivable_created | Conta a receber criada |
financial.receivable_confirmed | Recebimento confirmado |
financial.overdue | Conta vencida sem pagamento |
Formato do Payload
Todos os webhooks enviam um payload JSON via POST:
{
"id": "wh_evt_550e8400e29b41d4a716446655440000",
"event": "land_plot.status_changed",
"created_at": "2026-02-25T10:30:00Z",
"data": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"name": "Terreno Alphaville",
"status": "due_diligence",
"previous_status": "negociacao"
}
}Headers
Cada requisição webhook inclui os seguintes headers:
| Header | Descrição |
|---|---|
Content-Type | application/json |
X-OctaBuild-Event | Nome do evento (ex: land_plot.created) |
X-OctaBuild-Signature | Assinatura HMAC-SHA256 do payload |
X-OctaBuild-Timestamp | Timestamp Unix da requisição |
X-OctaBuild-Delivery | ID único da entrega |
Verificando a Assinatura
Para garantir que o webhook veio do OctaBuild, verifique a assinatura:
import crypto from 'crypto';
function verifyWebhookSignature(payload, signature, secret) {
const expected = crypto
.createHmac('sha256', secret)
.update(payload)
.digest('hex');
return crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(expected)
);
}
// No seu endpoint
app.post('/webhooks/octabuild', (req, res) => {
const signature = req.headers['x-octabuild-signature'];
const isValid = verifyWebhookSignature(
JSON.stringify(req.body),
signature,
process.env.OCTABUILD_WEBHOOK_SECRET
);
if (!isValid) {
return res.status(401).send('Invalid signature');
}
const { event, data } = req.body;
switch (event) {
case 'land_plot.status_changed':
console.log(`Terreno ${data.name}: ${data.previous_status} → ${data.status}`);
break;
case 'development.created':
console.log(`Empreendimento criado: ${data.name}`);
break;
case 'financial.overdue':
console.log(`Conta vencida: ${data.description}`);
break;
}
res.status(200).send('OK');
});import hmac
import hashlib
def verify_webhook_signature(payload, signature, secret):
expected = hmac.new(
secret.encode(),
payload.encode(),
hashlib.sha256
).hexdigest()
return hmac.compare_digest(signature, expected)
# No seu endpoint Flask
@app.route('/webhooks/octabuild', methods=['POST'])
def handle_webhook():
signature = request.headers.get('X-OctaBuild-Signature')
is_valid = verify_webhook_signature(
request.data.decode(),
signature,
os.environ['OCTABUILD_WEBHOOK_SECRET']
)
if not is_valid:
return 'Invalid signature', 401
event = request.json['event']
data = request.json['data']
if event == 'land_plot.status_changed':
print(f"Terreno {data['name']}: {data['previous_status']} → {data['status']}")
return 'OK', 200Política de Retry
Se sua aplicação não responder com 2xx dentro de 10 segundos, o OctaBuild tentará novamente:
| Tentativa | Intervalo |
|---|---|
| 1ª | Imediata |
| 2ª | 1 minuto |
| 3ª | 5 minutos |
| 4ª | 30 minutos |
| 5ª | 2 horas |
Após 5 tentativas sem sucesso, o webhook é marcado como falho.
Boas Práticas
- Responda rápido — Retorne
200 OKimediatamente e processe o evento em background - Seja idempotente — O mesmo evento pode ser entregue mais de uma vez
- Verifique a assinatura — Sempre valide o header
X-OctaBuild-Signature - Use HTTPS — Registre apenas URLs com HTTPS
- Monitore falhas — Acompanhe o dashboard de webhooks para identificar problemas
Suporte
- Email: suporte@octabuild.com.br
- Documentação: Você está aqui!