Webhooks (de saída)
Envie os eventos do FreeMaint para os seus próprios sistemas, em tempo real
Os webhooks são a metade «push» das integrações: em vez de o seu sistema consultar o FreeMaint, é o FreeMaint que faz um POST para o seu URL assim que algo acontece. Configuram-se em Definiçõ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 — foi criada uma ordem de trabalho
- work_order.completed — uma ordem de trabalho passou a Concluída
- work_order.status_changed — uma ordem de trabalho mudou para qualquer estado; o payload traz new_status. Dispara além de work_order.completed, que se mantém inalterado
- request.created — foi submetido um pedido de manutenção
- request.status_changed — um pedido foi aprovado, recusado ou cancelado
- part.low_stock — uma peça desceu ao ponto de encomenda ou abaixo
- 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 encomenda ou abaixo, incluindo as que nunca se movimentaram
- part.out_of_stock_summary — o mesmo resumo diário, para as peças a zero
- part.consumed — uma peça foi consumida numa ordem de trabalho, ou devolvida
- compliance.chain_divergence — a cadeia de hash de auditoria quebrou (Enterprise)
- asset.downtime_started — foi aberta uma paragem de máquina
- asset.downtime_ended — foi fechada uma paragem de máquina; a duração já pode ser imputada
- report.daily_summary — os trabalhos concluídos do dia, uma vez por dia à hora que escolher
- purchase_order.created — foi criada uma encomenda de compra; a carga útil contém a encomenda (reference, status, total_cost, currency, expected_date, erp_reference) e o fornecedor
- purchase_order.status_changed — uma encomenda de compra mudou de estado (aprovada, encomendada, cancelada…); a carga útil contém previous_status e new_status
- purchase_order.received — foi recebida uma entrega de uma nota de encomenda (enviado em cada entrega, incluindo as parciais); a carga útil 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 se espera mercadoria e RECEIVED quando a encomenda está completa ou fechada
part.consumed — espelhar o stock num ERP
É o evento a subscrever quando outro sistema (ERP, faturação, stocks, contabilidade) tem de refletir o que a manutenção consumiu de facto. quantity tem sinal: negativo quando a peça sai para o trabalho, positivo quando é devolvida ao retirá-la da ordem de trabalho — assim um estorno no FreeMaint produz o documento de devolução correspondente do outro lado. stock_movement_id é estável entre tentativas e reenvios: use-o como chave de idempotência e 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 este evento. É intencional — uma correção de existências que o seu próprio sistema escreve no FreeMaint nunca lhe deve voltar como eco e ser lançada duas vezes. Só o consumo registado numa ordem de trabalho dentro do FreeMaint gera part.consumed. A peça inclui também custom_reference: o seu próprio código para ela, o customReference definido com createPart ou updatePart, para que um sistema que gere o catálogo concilie cada linha sem manter uma tabela de identificadores 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": "Substituição de rolamento" }, "asset": { "id": 91, "name": "Desnatadeira 2" }, "location": { "id": 7, "name": "Armazém da fábrica" }, "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>, em que v1 é o HMAC-SHA256 da cadeia «<t>.<corpo em bruto>» com o segredo do seu webhook como chave. Verifique sobre o corpo EM BRUTO, antes de qualquer parsing JSON ou re-serialização. Enviamos também 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 recuo 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 o estado e o código de resposta. Qualquer entrega já concluída pode ser reenviada a partir daí: reenvia-se o mesmo payload guardado, pelo que as chaves de negócio que contém (incluindo stock_movement_id) permanecem iguais e um recetor que deduplica corretamente não lança em duplicado. É assim que se recupera depois de o seu endpoint estar em baixo ou ter recusado um pedido por engano.
Fotografias (opcional)
Quando «Incluir fotografias» está ativo num webhook (desativado por predefinição), os objetos "work_order" e "request" incluem uma lista "photos": até 4 ligações HTTPS para imagens JPG, PNG, GIF ou WebP, as mais recentes primeiro. Cada ligação abre a imagem sem sessão iniciada durante 7 dias, por isso guarde o ficheiro do seu lado se precisar dele por mais tempo. Um reenvio volta a enviar as mesmas ligações. Os outros eventos e webhooks não mudam. Para "work_order.created" e "request.created", um webhook com «Incluir fotografias» é enviado 90 segundos após o evento (o campo "timestamp" mantém a hora do evento), para incluir as fotografias carregadas logo a seguir ao registo.
Requisitos do URL
- Apenas https:// — o http simples é recusado
- Apenas porta 443 ou 8443
- O host tem de ser acessível publicamente — gamas loopback, privadas e CGNAT são recusadas
- Sem credenciais no URL (https://user:pass@host é recusado)
- Um sistema que só existe na sua rede interna precisa de um ponto de entrada público ou de um relé (n8n, Make, Zapier) à frente
Limites
- Starter — 100 entregas/dia por empresa
- Business — ilimitado
- Enterprise — ilimitado
- O contador conta tentativas de entrega: três webhooks subscritos ao mesmo evento consomem três unidades
- O contador diário é reposto às 00:00 UTC
Dica
Artigos relacionados
Esta página foi útil?