Os webhooks do UNO permitem que o seu sistema receba notificações HTTP em tempo quase real sempre que determinados eventos de negócio acontecem — criação, edição e remoção de agendamentos, e criação e mudanças fortes de status de vendas. Em vez de consultar a API periodicamente (polling), você cadastra uma URL do seu sistema e o UNO envia um POST com um payload JSON a cada evento assinado.
Como funciona, em resumo:
- Você cadastra um webhook pela interface do UNO, informando a URL de destino, um token de autenticação e quais eventos deseja receber.
- Quando um evento assinado acontece (e a operação é concluída com sucesso), o UNO envia de forma assíncrona um
POSTpara a sua URL, com o payload do recurso e o token no cabeçalho. - Cada tentativa de entrega — com sucesso ou falha — fica registrada na aba Log de webhooks, de onde é possível reenviar manualmente as chamadas que falharam.
Como configurar
A configuração é feita pela interface do UNO, no menu Configurações → Integrações. É necessário ter permissão de acesso a essa tela (a mesma usada para Credenciais).
- Acesse Configurações → Integrações.
- Clique na aba Webhooks (a tela abre na aba Credenciais).
- Clique em adicionar para abrir o formulário de cadastro.
Campos do formulário
| Campo | Descrição |
|---|---|
| Ativo | Liga/desliga o webhook. É possível cadastrar quantos webhooks quiser, mas no máximo 3 podem estar ativos ao mesmo tempo. Ao atingir o limite, o campo fica bloqueado com o aviso "Máximo de 3 webhooks ativos simultâneos atingido" — desative outro webhook antes de ativar um novo. |
| Nome | Nome de identificação do webhook (obrigatório). Aparece na listagem e no log. |
| URL de destino (https) | URL do seu sistema que receberá as notificações. Deve obrigatoriamente começar com https:// e apontar para um host público — endereços privados, loopback ou link-local são rejeitados tanto no cadastro quanto no momento do envio. |
| Token | Token de autenticação enviado em cada notificação no cabeçalho X-UNO-Webhook-Token. Você pode digitar um valor próprio ou clicar no botão Gerar token para gerar um automaticamente. |
| Agendamentos | Eventos de agendamento que o webhook receberá: Criação, Edição (inclui reagendamento/troca de horário) e Remoção. |
| Vendas | Eventos de venda que o webhook receberá: Criação e Transições fortes de status (fechada, cancelada ou desistência). |
Sobre o token
- O token é armazenado criptografado e nunca é reexibido. Ao editar um webhook, o campo aparece vazio: deixe em branco para manter o token atual, ou preencha/gere um novo para substituí-lo.
- Ao gerar um novo token, o anterior deixa de ser enviado imediatamente — atualize a validação no seu sistema antes de trocar.
É possível salvar um webhook sem nenhum evento selecionado — nesse caso ele não recebe nenhuma notificação. Confira se ao menos um evento está marcado.
Como funciona a entrega
Cada notificação é um POST HTTP para a URL cadastrada:
| Item | Comportamento |
|---|---|
| Método | POST |
| Corpo | JSON (ver Payloads) |
| Cabeçalhos | Content-Type: application/json e X-UNO-Webhook-Token: <seu token> |
| Timeout | 10 segundos — se o seu endpoint não responder nesse tempo, a chamada é registrada como falha |
| Tentativas | 1 única tentativa por evento, sem retry automático |
| Resposta esperada | Qualquer status HTTP é aceito e registrado no log; status 2xx marca a entrega como sucesso, status ≥ 400 ou ausência de resposta marca como falha |
| Redirecionamentos | Seguidos apenas se o destino também for HTTPS e host público |
Entrega assíncrona e pós-confirmação. A notificação só é enviada depois que a operação de origem (por exemplo, a criação do agendamento) é confirmada no UNO. Se a operação falhar, nenhum webhook é disparado. O envio acontece por uma fila de processamento, então pode haver alguns segundos entre o evento e o recebimento.
Duplicidade e ordem. A entrega é at-least-once: em situações raras de reprocessamento interno, o mesmo evento pode ser entregue mais de uma vez. A ordem das notificações é garantida apenas para o mesmo webhook e o mesmo recurso (por exemplo, eventos do agendamento 123 chegam na ordem em que ocorreram); entre recursos diferentes, não há garantia de ordem.
Log e reenvio manual. Toda tentativa gera um registro na aba Log de webhooks (Configurações → Integrações), com o conteúdo enviado, a resposta recebida e o status HTTP. Por padrão a tela lista as chamadas do dia atual, com filtros por período e por webhook. Chamadas com falha têm a ação Reenviar, que reconstrói a notificação com os dados atuais do recurso e gera um novo registro de log.
Eventos
| Evento | Quando dispara |
|---|---|
APPOINTMENT_CREATED | Um agendamento é criado — individualmente, em lote, por recorrência (1 evento por agendamento criado) ou junto da criação de uma venda. |
APPOINTMENT_UPDATED | Um agendamento é editado: reagendamento (troca de horário ou sala), edição de campos (serviço, profissional, observação etc.) ou mudança de status (check-in, atendido, falta etc.). Edições em lote geram 1 evento por agendamento. |
APPOINTMENT_REMOVED | Um agendamento é removido (individualmente ou em lote). |
ORDER_CREATED | Uma venda é criada. |
ORDER_UPDATED | Uma venda passa para um status forte: fechada (CLOSED), cancelada (CANCELED) ou desistência (ABANDONMENT). Mudanças em itens da venda ou outros status não geram notificação. |
Um agendamento gera várias notificações ao longo do ciclo de vida. Como toda mudança de status dispara
APPOINTMENT_UPDATED, um mesmo agendamento pode notificar na criação e a cada check-in, atendimento, falta etc.
Trate
ORDER_UPDATEDcomo idempotente. O evento reflete o status atual da venda no momento do disparo. Em determinadas operações, uma venda que já está em um status forte pode gerar uma nova notificação com o mesmo status — processe o evento como "a venda está neste estado", não como "a venda acabou de mudar para este estado".
Payloads
Todo payload tem um envelope comum:
{
"event": "NOME_DO_EVENTO",
"schema": "identificador-da-empresa",
"appointment": { "...": "presente nos eventos de agendamento" },
"order": { "...": "presente nos eventos de venda" }
}
event— o tipo do evento (um dos 5 da tabela acima).schema— identificador da empresa no UNO. Se você integra mais de uma empresa/unidade no mesmo endpoint, use este campo para distingui-las.
As relações (cliente, profissional, serviço etc.) trazem sempre apenas id e name — nunca o objeto completo. Qualquer relação pode vir null quando não se aplica.
As datas estão em formato ISO 8601 com o offset do fuso horário da empresa (por exemplo 2026-08-19T14:30:00-03:00) — não em UTC.
Agendamento (APPOINTMENT_CREATED / APPOINTMENT_UPDATED / APPOINTMENT_REMOVED)
APPOINTMENT_CREATED / APPOINTMENT_UPDATED / APPOINTMENT_REMOVED){
"event": "APPOINTMENT_UPDATED",
"schema": "empresa_x",
"appointment": {
"id": 123,
"startDate": "2026-08-19T14:30:00-03:00",
"endDate": "2026-08-19T15:30:00-03:00",
"observation": "Observação do agendamento ou null",
"serviceSession": 1,
"status": { "id": 5, "name": "Atendido" },
"customer": { "id": 10, "name": "Maria Silva" },
"employee": { "id": 4, "name": "João Souza" },
"room": { "id": 2, "name": "Sala 2" },
"service": { "id": 7, "name": "Limpeza de pele" }
}
}
| Campo | Tipo | Descrição |
|---|---|---|
appointment.id | número | Identificador do agendamento |
startDate / endDate | string (ISO 8601) | Início e fim do agendamento, no fuso da empresa |
observation | string ou null | Observação livre do agendamento |
serviceSession | número ou null | Número da sessão do serviço |
status | objeto ou null | Status atual do agendamento (id + name, ex.: Agendado, Confirmado, Atendido, Falta) |
customer / employee / room / service | objeto ou null | Cliente, profissional, sala e serviço, sempre como { id, name } |
O payload é o mesmo nos três eventos de agendamento — o que os distingue é o campo
event. NoAPPOINTMENT_REMOVED, o payload traz os dados do agendamento no momento da remoção.
Venda (ORDER_CREATED / ORDER_UPDATED)
ORDER_CREATED / ORDER_UPDATED){
"event": "ORDER_UPDATED",
"schema": "empresa_x",
"order": {
"id": 456,
"status": "CLOSED",
"totalPrice": 300.0,
"totalDiscount": 0,
"totalPaid": 300.0,
"serviceTotalPrice": 300.0,
"productTotalPrice": 0,
"planTotalPrice": 0,
"courseTotalPrice": 0,
"canceledAt": null,
"abandonedAt": null,
"cancellationReason": null,
"abandonmentReason": null,
"customer": { "id": 10, "name": "Maria Silva" },
"seller": { "id": 4, "name": "João Souza" },
"items": [
{
"type": "SERVICE",
"quantity": 1,
"price": 300.0,
"discount": 0,
"service": { "id": 7, "name": "Limpeza de pele" }
}
]
}
}
| Campo | Tipo | Descrição |
|---|---|---|
order.id | número | Identificador da venda |
status | string | Status atual: PENDING_BALANCE, BILLED, CLOSED, CANCELED ou ABANDONMENT |
totalPrice / totalDiscount / totalPaid | número | Totais da venda |
serviceTotalPrice / productTotalPrice / planTotalPrice / courseTotalPrice | número | Totais por tipo de item |
canceledAt / abandonedAt | string (ISO 8601) ou null | Data do cancelamento/desistência, quando houver |
cancellationReason / abandonmentReason | objeto ou null | Motivo do cancelamento/desistência, como { id, name } |
customer / seller | objeto ou null | Cliente e vendedor, como { id, name } |
items | array | Itens da venda (ver abaixo) |
Cada item de items tem o formato:
{ "type": "PRODUCT | SERVICE | COURSE | PLAN", "quantity": 1, "price": 0, "discount": 0 }
e, além desses campos, apenas uma chave correspondente ao tipo — product, service, course ou plan — com { id, name }. As demais chaves não existem no objeto (não vêm como null). Para itens do tipo COURSE e PLAN, quantity é sempre 1.
O que o payload de venda não inclui: dados de pagamento (formas, parcelas, valores pagos por transação) não são enviados.
O que nenhum payload inclui
- Identificador único da entrega (delivery ID) ou timestamp do evento — use o corpo recebido e o
iddo recurso para correlação. - Versão do payload — o formato documentado aqui é o vigente.
- Vínculo entre agendamento e venda (o payload de agendamento não traz o id da venda, e vice-versa).
Boas práticas para o seu endpoint
Valide o token em toda requisição. Compare o valor do cabeçalho X-UNO-Webhook-Token com o token cadastrado no UNO e rejeite requisições que não conferem. Esse cabeçalho é a única autenticação da notificação — não há assinatura do corpo.
Responda rápido, processe depois. O UNO aguarda no máximo 10 segundos pela resposta. Receba a notificação, persista-a (em fila ou banco) e responda 2xx imediatamente; faça o processamento pesado de forma assíncrona. Respostas lentas ou status >= 400 marcam a entrega como falha no log.
Implemente idempotência. Como a entrega é at-least-once e não há delivery ID, o mesmo evento pode chegar mais de uma vez. Deduplique usando a combinação event + schema + appointment.id/order.id + conteúdo relevante, e garanta que processar duas vezes a mesma notificação não cause efeito duplicado no seu sistema.
Não dependa de ordem global. A ordem só é garantida entre eventos do mesmo recurso. Se o seu fluxo depende do estado mais recente, trate o payload como um retrato do estado atual do recurso.
Monitore o Log de webhooks. Não há retry automático: se o seu endpoint estiver indisponível no momento do envio, o evento não será entregue novamente por conta própria. Acompanhe a aba Log de webhooks e use a ação Reenviar nas falhas. Atenção: o reenvio reconstrói a notificação com os dados atuais do recurso — não é uma reprodução do estado no momento do evento original.
Mantenha a URL válida. A URL precisa continuar HTTPS e pública; a validação é refeita a cada envio, e uma URL que deixar de atender aos requisitos fará as entregas falharem.
