Webhooks (de saída)
Envie os eventos do FreeMaint para os seus próprios sistemas, em tempo real
Webhooks são a metade «push» das integrações: em vez de o seu sistema ficar consultando o FreeMaint, é o FreeMaint que faz um POST para a sua URL assim que algo acontece. A configuração fica em Configurações da empresa > Webhooks (/company-settings/webhooks). Disponíveis a partir do Starter (100 entregas/dia; ilimitadas a partir do Business).
Eventos disponíveis
- work_order.created — uma ordem de serviço foi criada
- work_order.completed — uma ordem de serviço passou para Concluída
- work_order.status_changed — uma ordem de serviço mudou para qualquer status; o payload traz new_status. Dispara além de work_order.completed, que permanece inalterado
- request.created — uma solicitação de manutenção foi enviada
- request.status_changed — uma solicitação foi aprovada, recusada ou cancelada
- part.low_stock — uma peça chegou ao ponto de ressuprimento ou abaixo dele
- part.out_of_stock — uma peça chegou a zero
- part.low_stock_summary — um resumo diário por empresa com as peças no ponto de ressuprimento ou abaixo, inclusive as que nunca se movimentaram
- part.out_of_stock_summary — o mesmo resumo diário, para as peças zeradas
- part.consumed — uma peça foi consumida em uma ordem de serviço, ou devolvida
- compliance.chain_divergence — a cadeia de hash de auditoria foi rompida (Enterprise)
- asset.downtime_started — uma parada de máquina foi aberta
- asset.downtime_ended — uma parada de máquina foi encerrada; a duração já pode ser apropriada
- report.daily_summary — os trabalhos concluídos do dia, uma vez por dia no horário que você escolher
- purchase_order.created — um pedido de compra foi criado; o payload traz o pedido (reference, status, total_cost, currency, expected_date, erp_reference) e o fornecedor
- purchase_order.status_changed — um pedido de compra mudou de status (aprovado, pedido, cancelado…); o payload traz previous_status e new_status
- purchase_order.received — uma entrega de um pedido de compra foi recebida (enviado a cada entrega, inclusive as parciais); o payload lista cada linha com quantity_ordered, quantity_received (esta entrega), quantity_received_total e quantity_remaining, além de receipt_id, fully_received e closed_short; new_status é PARTIALLY_RECEIVED enquanto ainda se esperam mercadorias e RECEIVED quando o pedido está completo ou encerrado
part.consumed — espelhar o estoque em um ERP
É o evento a assinar quando outro sistema (ERP, faturamento, estoque, contabilidade) precisa refletir o que a manutenção realmente consumiu. quantity tem sinal: negativo quando a peça sai para o serviço, positivo quando é devolvida ao removê-la da ordem de serviço — assim um estorno no FreeMaint gera o documento de devolução correspondente do outro lado. stock_movement_id é estável entre novas tentativas e reenvios: use-o como chave de idempotência e você nunca lançará duas vezes a mesma saída. Um ponto a saber quando o tráfego corre nos dois sentidos: a mutação GraphQL adjustStock NÃO dispara esse evento. É intencional — uma correção de estoque que o seu próprio sistema grava no FreeMaint nunca deve voltar para você como eco e ser lançada duas vezes. Só o consumo registrado em uma ordem de serviço dentro do FreeMaint gera part.consumed. A peça também traz custom_reference: o seu próprio código para ela, o customReference definido com createPart ou updatePart, para que um sistema que gerencia o catálogo concilie cada linha sem manter uma tabela de IDs do FreeMaint.
{ "event": "part.consumed", "timestamp": "2026-08-19T21:04:11.000Z", "data": { "part": { "id": 812, "name": "Rolamento 6204", "part_number": "RLM-204", "reference": "PART-812", "custom_reference": "BC-10045", "unit_cost": 12.5, "unit_of_measure": "un" }, "quantity": -2, "previous_quantity": 48, "new_quantity": 46, "work_order": { "id": 5521, "reference": "WO-2026-0412", "title": "Troca de rolamento" }, "asset": { "id": 91, "name": "Desnatadeira 2" }, "location": { "id": 7, "name": "Almoxarifado da planta" }, "user": { "id": 5627, "name": "A. Técnico" }, "stock_movement_id": 88213, "occurred_at": "2026-08-19T21:04:11.000Z" } }
Entrega e assinatura
Cada entrega é um POST com corpo JSON e um cabeçalho X-FreeMaint-Signature no formato t=<segundos unix>,v1=<hex>, onde v1 é o HMAC-SHA256 da string «<t>.<corpo bruto>» usando o segredo do seu webhook como chave. Verifique sobre o corpo BRUTO, antes de qualquer parsing JSON ou reserialização. Também enviamos X-FreeMaint-Event e X-FreeMaint-Delivery-Id. Um 2xx marca a entrega como entregue; erros de rede e 5xx são repetidos até 3 vezes com backoff exponencial (cerca de 2 s, 4 s, 8 s); um 4xx é tratado como recusa definitiva e NÃO é repetido.
Reenviar uma entrega
Cada tentativa fica no histórico de entregas do webhook, com status e código de resposta. Qualquer entrega já finalizada pode ser reenviada de lá: reenvia-se o mesmo payload armazenado, então as chaves de negócio que ele contém (incluindo stock_movement_id) permanecem iguais e um receptor que deduplica corretamente não lança em duplicidade. É assim que se recupera depois de o seu endpoint ter ficado fora do ar ou ter recusado uma requisição por engano.
Fotos (opcional)
Quando "Incluir fotos" está ativado em um webhook (desativado por padrão), os objetos "work_order" e "request" trazem uma lista "photos": até 4 links HTTPS para imagens JPG, PNG, GIF ou WebP, as mais recentes primeiro. Cada link abre a imagem sem login por 7 dias, então guarde o arquivo no seu sistema se precisar dele por mais tempo. Um reenvio manda os mesmos links. Os outros eventos e webhooks não mudam. Para "work_order.created" e "request.created", um webhook com "Incluir fotos" é enviado 90 segundos após o evento (o campo "timestamp" mantém o horário do evento), para incluir as fotos enviadas logo depois do registro.
Requisitos da URL
- Somente https:// — http simples é recusado
- Somente porta 443 ou 8443
- O host precisa ser acessível publicamente — faixas loopback, privadas e CGNAT são recusadas
- Sem credenciais na URL (https://user:pass@host é recusado)
- Um sistema que só existe na sua rede interna precisa de um endpoint público ou de um relé (n8n, Make, Zapier) na frente
Limites
- Starter — 100 entregas/dia por empresa
- Business — ilimitado
- Enterprise — ilimitado
- O contador conta tentativas de entrega: três webhooks assinando o mesmo evento consomem três unidades
- O contador diário é zerado às 00:00 UTC
Dica
Artigos relacionados
Esta página foi útil?