[{"data":1,"prerenderedAt":2649},["ShallowReactive",2],{"docs-nav-docs_pt":3,"docs-search-docs_pt":148,"doc-docs_pt-\u002Fdocs\u002Fapi\u002Fsdks":1085,"surround-docs_pt-\u002Fdocs\u002Fapi\u002Fsdks":2645},[4],{"title":5,"path":6,"stem":7,"children":8,"page":42},"Docs","\u002Fdocs","docs",[9,13,17,21,43,64,77,98,111,115,140,144],{"title":10,"path":11,"stem":12},"Introdução","\u002Fdocs\u002Fintroduction","docs\u002F01.introduction",{"title":14,"path":15,"stem":16},"Primeiros passos","\u002Fdocs\u002Fgetting-started","docs\u002F02.getting-started",{"title":18,"path":19,"stem":20},"Como funciona","\u002Fdocs\u002Fhow-it-works","docs\u002F03.how-it-works",{"title":22,"path":23,"stem":24,"children":25,"page":42},"Conceitos","\u002Fdocs\u002Fconcepts","docs\u002F04.concepts",[26,30,34,38],{"title":27,"path":28,"stem":29},"Workspaces e recursos","\u002Fdocs\u002Fconcepts\u002Fworkspaces-and-resources","docs\u002F04.concepts\u002F1.workspaces-and-resources",{"title":31,"path":32,"stem":33},"Serviços e disponibilidade","\u002Fdocs\u002Fconcepts\u002Fservices-and-availability","docs\u002F04.concepts\u002F2.services-and-availability",{"title":35,"path":36,"stem":37},"Agendamentos e pré-reservas","\u002Fdocs\u002Fconcepts\u002Fbookings-and-holds","docs\u002F04.concepts\u002F3.bookings-and-holds",{"title":39,"path":40,"stem":41},"Automatizações","\u002Fdocs\u002Fconcepts\u002Fautomations","docs\u002F04.concepts\u002F4.automations",false,{"title":44,"path":45,"stem":46,"children":47,"page":42},"Canais","\u002Fdocs\u002Fchannels","docs\u002F05.channels",[48,52,56,60],{"title":49,"path":50,"stem":51},"WhatsApp","\u002Fdocs\u002Fchannels\u002Fwhatsapp","docs\u002F05.channels\u002F01.whatsapp",{"title":53,"path":54,"stem":55},"Chat web","\u002Fdocs\u002Fchannels\u002Fwebchat","docs\u002F05.channels\u002F02.webchat",{"title":57,"path":58,"stem":59},"Telegram","\u002Fdocs\u002Fchannels\u002Ftelegram","docs\u002F05.channels\u002F03.telegram",{"title":61,"path":62,"stem":63},"Pausas e Estado","\u002Fdocs\u002Fchannels\u002Fpauses-and-status","docs\u002F05.channels\u002F04.pauses-and-status",{"title":65,"path":66,"stem":67,"children":68,"page":42},"Bot e conhecimento","\u002Fdocs\u002Fbot","docs\u002F06.bot",[69,73],{"title":70,"path":71,"stem":72},"O bot e a IA","\u002Fdocs\u002Fbot\u002Foverview","docs\u002F06.bot\u002F01.overview",{"title":74,"path":75,"stem":76},"Conhecimento do bot","\u002Fdocs\u002Fbot\u002Fknowledge","docs\u002F06.bot\u002F02.knowledge",{"title":78,"path":79,"stem":80,"children":81,"page":42},"Trabalho, mapa e fluxos","\u002Fdocs\u002Fwork","docs\u002F07.work",[82,86,90,94],{"title":83,"path":84,"stem":85},"Trabalho e ações","\u002Fdocs\u002Fwork\u002Ftasks-and-actions","docs\u002F07.work\u002F01.tasks-and-actions",{"title":87,"path":88,"stem":89},"Mapa e endereços","\u002Fdocs\u002Fwork\u002Fmap-and-addresses","docs\u002F07.work\u002F02.map-and-addresses",{"title":91,"path":92,"stem":93},"Fluxos","\u002Fdocs\u002Fwork\u002Fflows","docs\u002F07.work\u002F03.flows",{"title":95,"path":96,"stem":97},"Condições dos fluxos","\u002Fdocs\u002Fwork\u002Fconditions","docs\u002F07.work\u002F04.conditions",{"title":99,"path":100,"stem":101,"children":102,"page":42},"Equipe","\u002Fdocs\u002Fteam","docs\u002F08.team",[103,107],{"title":104,"path":105,"stem":106},"Telegram da equipe","\u002Fdocs\u002Fteam\u002Ftelegram-team","docs\u002F08.team\u002F01.telegram-team",{"title":108,"path":109,"stem":110},"Papéis e permissões","\u002Fdocs\u002Fteam\u002Froles","docs\u002F08.team\u002F02.roles",{"title":112,"path":113,"stem":114},"Início rápido","\u002Fdocs\u002Fquickstart","docs\u002F09.quickstart",{"title":116,"path":117,"stem":118,"children":119,"page":42},"API","\u002Fdocs\u002Fapi","docs\u002F10.api",[120,124,128,132,136],{"title":121,"path":122,"stem":123},"Autenticação","\u002Fdocs\u002Fapi\u002Fauthentication","docs\u002F10.api\u002F1.authentication",{"title":125,"path":126,"stem":127},"Convenções","\u002Fdocs\u002Fapi\u002Fconventions","docs\u002F10.api\u002F2.conventions",{"title":129,"path":130,"stem":131},"Endpoints","\u002Fdocs\u002Fapi\u002Fendpoints","docs\u002F10.api\u002F3.endpoints",{"title":133,"path":134,"stem":135},"Webhooks","\u002Fdocs\u002Fapi\u002Fwebhooks","docs\u002F10.api\u002F4.webhooks",{"title":137,"path":138,"stem":139},"SDKs de TypeScript e Python","\u002Fdocs\u002Fapi\u002Fsdks","docs\u002F10.api\u002F5.sdks",{"title":141,"path":142,"stem":143},"MCP e agentes de IA","\u002Fdocs\u002Fmcp","docs\u002F11.mcp",{"title":145,"path":146,"stem":147},"Receitas","\u002Fdocs\u002Frecipes","docs\u002F12.recipes",[149,153,159,164,168,173,176,181,186,191,196,201,206,211,216,219,224,229,234,239,243,248,253,256,261,266,271,276,279,284,289,294,299,304,307,312,317,322,327,332,335,340,346,351,356,359,364,369,374,379,384,389,394,397,402,407,412,417,422,426,430,433,438,443,448,452,457,461,464,469,474,479,484,489,492,497,502,507,512,517,522,526,529,534,539,544,549,554,559,562,567,572,577,582,587,592,597,602,607,612,615,620,625,630,635,640,645,648,653,658,663,668,673,676,681,686,691,696,701,704,709,714,719,724,729,734,737,742,747,752,757,762,767,770,775,780,785,790,795,800,805,809,812,817,822,827,832,835,840,845,850,855,860,863,868,873,878,883,888,892,897,902,907,912,917,922,925,930,935,940,945,950,953,958,963,968,972,977,982,986,990,994,999,1002,1007,1012,1017,1022,1027,1030,1035,1040,1045,1050,1055,1060,1065,1070,1075,1080],{"id":11,"title":10,"titles":150,"content":151,"level":152},[],"O que é a Wagend, para quem serve e os blocos que você vai usar para atender, agendar e trabalhar com a sua equipe. A Wagend é um motor de agenda e de trabalho com um assistente de IA que atende os seus clientes por WhatsApp, Telegram e pelo chat do seu site. Seus clientes reservam conversando; o sistema oferece só horários que existem de verdade, faz a pré-reserva, confirma e avisa a sua equipe. Você gerencia tudo em um painel, e os desenvolvedores integram por API REST, webhooks, SDK e MCP. Esta documentação descreve o que já está disponível. O que ainda não existe aparece marcado como Em breve.",1,{"id":154,"title":155,"titles":156,"content":157,"level":158},"\u002Fdocs\u002Fintroduction#para-quem-é","Para quem é",[10],"Qualquer negócio que vende o tempo de alguém ou de algo. A Wagend usa um vocabulário genérico (tarefa, recurso, serviço) e se adapta ao seu ramo com um modelo inicial: NegócioO que se reserva ou se fazBarbeariaUm barbeiro por 30 a 45 minutosEstéticaUm profissional e uma máquina e uma cabine, ao mesmo tempoClínicaUm médico e um consultórioRestauranteLugares no salão conforme o tamanho do grupoEntregasTarefas que um entregador pega de uma fila, com destino no mapa",2,{"id":160,"title":161,"titles":162,"content":163,"level":158},"\u002Fdocs\u002Fintroduction#o-que-você-vai-usar","O que você vai usar",[10],"Hoje: o que precisa ser feito agora, com o seu trabalho ou o de toda a equipe, conforme o seu papel.Inbox: todas as conversas de todos os canais em um só lugar; você assume o controle quando precisar.Trabalho: todas as tarefas, em lista, calendário ou mapa, com ações por etapa (pegar, soltar, concluir, \"não estava\").Clientes, Serviços, Equipe e recursos: seu catálogo e sua gente.Bot: personalidade, conhecimento e simulador. Automação: regras e fluxos.Wagy: o assistente do painel que ajuda você a configurar tudo conversando.Configuração: Negócio, Estado, Equipe, Canais, Desenvolvedores, Webhooks e Uso de IA.",{"id":165,"title":44,"titles":166,"content":167,"level":158},"\u002Fdocs\u002Fintroduction#canais",[10],"Todos os canais usam o mesmo motor: um horário reservado pelo WhatsApp some na hora do painel, do chat web e da API. WhatsApp com assistente de IA (texto e áudio).Chat web para colar no seu site.Telegram com o bot próprio do seu negócio.Telegram da equipe: avisos e o Mini App \"Meu dia\".",{"id":169,"title":170,"titles":171,"content":172,"level":158},"\u002Fdocs\u002Fintroduction#por-onde-continuar","Por onde continuar",[10],"Primeiros passos: do modelo de negócio à sua primeira tarefa, com o Wagy.Como funciona: a vida de uma mensagem e as garantias do motor.Trabalho e ações e Fluxos.Se você desenvolve: Início rápido da API, SDK e MCP.",{"id":15,"title":14,"titles":174,"content":175,"level":152},[],"Guia passo a passo para montar o seu negócio na Wagend com a ajuda do Wagy, conectar um canal, testar o bot e fazer a sua primeira tarefa. Este guia leva você do zero a um negócio atendendo. Leva cerca de 20 minutos e você pode pedir ajuda ao Wagy em cada passo.",{"id":177,"title":178,"titles":179,"content":180,"level":158},"\u002Fdocs\u002Fgetting-started#_1-criar-o-negócio-a-partir-de-um-modelo","1. Criar o negócio a partir de um modelo",[14],"Cada negócio (ou unidade) é um projeto. Ao criá-lo você escolhe o tipo de negócio e a Wagend carrega um modelo com serviços, recursos, horários e etapas típicas desse ramo: barbearia, estética, clínica, restaurante ou entregas. Entre no painel e abra o seletor de projetos.Toque em Criar projeto, informe o nome, escolha o tipo de negócio, o fuso horário e o idioma.Entre no projeto novo. O seu plano define quantos projetos você pode ter; se atingiu o limite, o seletor avisa. Tudo o que vem no modelo pode ser alterado depois. Os nomes se adaptam ao ramo (por exemplo \"Aceitar entrega\" em entregas), mas por baixo é o mesmo motor.",{"id":182,"title":183,"titles":184,"content":185,"level":158},"\u002Fdocs\u002Fgetting-started#_2-configurar-com-o-wagy","2. Configurar com o Wagy",[14],"O Wagy é o assistente de configuração do painel: um bot simpático a quem você conta o que faz e que monta o seu negócio com você. Você o abre com o botão Falar com o Wagy. Só proprietário e gerentes o usam. Conte sobre o seu negócio (\"Tenho uma barbearia com três barbeiros\").O Wagy propõe um plano de mudanças: um cartão com o que vai criar ou modificar (serviços, horários, recursos, regras do bot, automações).Revise o plano e toque em Confirmar, Ajustar (você continua conversando e ele monta outro) ou Descartar. Nada é aplicado sem a sua confirmação.Se não gostar do resultado, toque em Desfazer: dá para desfazer o último plano aplicado por 24 horas. O Wagy também mostra uma lista de Primeiros passos que se marca sozinha com os seus dados reais: perfil do negócio, horário de atendimento, serviços, equipe, canal conectado, bot testado, primeira reserva e primeira tarefa concluída. E envia avisos discretos (no máximo dois por dia) que você pode fechar ou silenciar. O Wagy nunca pede senhas nem tokens: para conectar um canal ele leva você à tela correspondente. As primeiras mensagens com o Wagy são pagas pela plataforma; depois consomem a cota de IA do seu plano.",{"id":187,"title":188,"titles":189,"content":190,"level":158},"\u002Fdocs\u002Fgetting-started#_3-revisar-o-básico-manualmente","3. Revisar o básico manualmente",[14],"Se preferir o painel, estas são as telas: Configuração → Negócio: nome, fuso horário, moeda, idioma, endereço e política de cancelamento.Serviços: duração, preço, sinal e quais recursos cada serviço pede.Equipe e recursos: pessoas, salas ou máquinas com seus horários. Convide a equipe em Configuração → Equipe (veja papéis e permissões).",{"id":192,"title":193,"titles":194,"content":195,"level":158},"\u002Fdocs\u002Fgetting-started#_4-conectar-um-canal","4. Conectar um canal",[14],"Vá em Configuração → Canais: WhatsApp: escaneie um QR. Veja WhatsApp.Chat web: cole uma linha de código no seu site. Veja Chat web.Telegram: cole o token do seu bot. Veja Telegram. Todas as conversas chegam à mesma caixa, o Inbox.",{"id":197,"title":198,"titles":199,"content":200,"level":158},"\u002Fdocs\u002Fgetting-started#_5-testar-o-bot","5. Testar o bot",[14],"Antes de abrir para clientes reais, use o Simulador em Automação → Bot. Você conversa com o bot como se fosse um cliente, sem enviar mensagens reais; as reservas que ele faz são de teste. Experimente frases como \"quero reservar\", \"quanto custa?\" ou \"até que horas abrem?\". Ajuste a personalidade e carregue conhecimento (veja Bot e conhecimento).",{"id":202,"title":203,"titles":204,"content":205,"level":158},"\u002Fdocs\u002Fgetting-started#_6-sua-primeira-tarefa","6. Sua primeira tarefa",[14],"Toque em Nova tarefa (fica na barra superior, em qualquer tela).Escolha o serviço, busque ou crie o cliente e escolha o horário.Salve. A tarefa aparece em Hoje e em Trabalho.",{"id":207,"title":208,"titles":209,"content":210,"level":158},"\u002Fdocs\u002Fgetting-started#_7-ver-o-dia-em-hoje","7. Ver o dia em Hoje",[14],"Hoje mostra o que precisa ser feito agora. Proprietários e gerentes veem tudo; a equipe vê o que é seu. Em cada tarefa você avança de etapa com as ações disponíveis. Continue em Trabalho e ações.",{"id":212,"title":213,"titles":214,"content":215,"level":158},"\u002Fdocs\u002Fgetting-started#próximos-passos","Próximos passos",[14],"Fluxos e condições: lembretes e avisos automáticos.Telegram da equipe: avisos e \"Meu dia\" no celular.Pausas e Estado: o que fazer se algo se complicar.",{"id":19,"title":18,"titles":217,"content":218,"level":152},[],"Arquitetura, princípios e a vida de uma mensagem, desde que chega por um canal até virar uma tarefa, uma ação ou um aviso.",{"id":220,"title":221,"titles":222,"content":223,"level":158},"\u002Fdocs\u002Fhow-it-works#princípios","Princípios",[18],"Núcleo determinístico, IA como intérprete. A IA entende o cliente e chama ferramentas. O motor calcula disponibilidade, pré-reserva e confirma. A IA nunca inventa um horário nem um preço.O banco de dados garante as regras. O overbooking é impossível porque o PostgreSQL rejeita alocações sobrepostas, não porque o app \"confere antes\".Uma verdade operacional, várias visões. Uma tarefa é um único objeto; você a vê em Hoje, em lista, em calendário ou no mapa.API primeiro. O painel, o bot, o MCP e o Wagy usam os mesmos serviços. Se algo não dá para fazer por API, falta na API.A credencial define o negócio. Uma chave ou sessão sempre pertence a um projeto.",{"id":225,"title":226,"titles":227,"content":228,"level":158},"\u002Fdocs\u002Fhow-it-works#arquitetura","Arquitetura",[18],"Canais:     WhatsApp · Chat web · Telegram · Painel · Wagy · API · MCP\n                 │\nGateway:    credencial → projeto · permissões · limites · pausas · webhooks assinados\n                 │\nNúcleo:     conversas + IA │ motor de agenda e tarefas │ fluxos │ conhecimento\n                 │\nDados:      PostgreSQL (segurança por linha, constraints de exclusão) · Redis\nExternos:   modelos de IA · transcrição de áudio · provedores de canal · mapas",{"id":230,"title":231,"titles":232,"content":233,"level":158},"\u002Fdocs\u002Fhow-it-works#a-vida-de-uma-mensagem","A vida de uma mensagem",[18],"Chega. O canal (WhatsApp, chat web ou Telegram) entrega a mensagem. Verifica-se a assinatura ou a chave, descartam-se duplicadas e salva-se no Inbox. Se o canal está pausado, a pausa é aplicada antes de qualquer outra coisa.É entendida. Os áudios são transcritos. Identifica-se o cliente (um cliente pode ter várias identidades: telefone, Telegram) e a conversa. Se uma pessoa assumiu o controle, o bot não responde. As regras do canal (por exemplo pedir telefone e e-mail no chat web) são aplicadas antes de chamar a IA.A IA pede. O modelo recebe o contexto do negócio, a data e a hora locais e as últimas mensagens. Só pode chamar ferramentas: buscar horários, pré-reservar, confirmar, consultar o conhecimento, salvar uma localização compartilhada ou encaminhar para uma pessoa.O motor decide. Cada chamada é validada contra as regras do negócio e só depois executada. Se algo mudou, o motor devolve alternativas e a IA pergunta de novo.Resposta exata. Datas, horas, serviços, preços e endereços saem de modelos preenchidos com o resultado real.Trabalho e eventos. A reserva é uma tarefa com etapas. Cada mudança de etapa ou ação gera eventos que disparam fluxos, avisos à equipe (por Telegram ou WhatsApp) e webhooks.",{"id":235,"title":236,"titles":237,"content":238,"level":158},"\u002Fdocs\u002Fhow-it-works#tarefas-etapas-e-ações","Tarefas, etapas e ações",[18],"Cada negócio define as etapas por onde passa o seu trabalho e as ações que movem uma tarefa de uma para outra (pegar, soltar, concluir, \"não estava\"). Uma ação pode ter efeitos: atribuir a quem a executa, liberar, encerrar com um resultado. Veja Trabalho e ações.",{"id":240,"title":91,"titles":241,"content":242,"level":158},"\u002Fdocs\u002Fhow-it-works#fluxos",[18],"Um fluxo diz \"quando isto acontecer, se esta condição for atendida, faça aquilo\": enviar uma mensagem, avisar a equipe, esperar, executar uma ação. As condições são expressões simples sobre a tarefa, o cliente ou a hora.",{"id":244,"title":245,"titles":246,"content":247,"level":158},"\u002Fdocs\u002Fhow-it-works#segurança","Segurança",[18],"Cada negócio é isolado no próprio banco de dados, os segredos são cifrados e cada mudança fica num registro de auditoria. Você é o responsável pelos dados dos seus clientes; a Wagend os trata em seu nome.",{"id":249,"title":250,"titles":251,"content":252,"level":158},"\u002Fdocs\u002Fhow-it-works#para-onde-ir-depois","Para onde ir depois",[18],"Reservas e pré-reservas: as garantias da agenda.Bot e IA: o que o assistente pode e não pode fazer.",{"id":28,"title":27,"titles":254,"content":255,"level":152},[],"Organizações, workspaces, papéis, recursos, modos de capacidade e grupos de recursos.",{"id":257,"title":258,"titles":259,"content":260,"level":158},"\u002Fdocs\u002Fconcepts\u002Fworkspaces-and-resources#organização-e-workspaces","Organização e workspaces",[27],"No painel, um workspace se chama projeto: você pode ter vários e trocar entre eles com o seletor de projetos. Uma organização é a conta que paga. Ela contém um ou mais workspaces. Um workspace é um negócio ou unidade com seus próprios: fuso horário, idioma e moeda,número(s) de WhatsApp,bot, serviços, recursos e equipe. Uma rede de três barbearias é uma organização com três workspaces.",{"id":262,"title":263,"titles":264,"content":265,"level":158},"\u002Fdocs\u002Fconcepts\u002Fworkspaces-and-resources#papéis","Papéis",[27],"Detalhes de cada papel e das permissões em Papéis e permissões. PapelPodeownerTudo, em todos os workspaces da organizaçãomanagerTudo dentro de um workspacestaffVer e gerenciar só os próprios recursos (por exemplo, o barbeiro vê só a sua agenda)viewerSomente leitura A equipe também pode agir pelo WhatsApp depois de vincular o número com um código de uso único. Ações de administrador pelo WhatsApp sempre pedem confirmação SIM\u002FNÃO.",{"id":267,"title":268,"titles":269,"content":270,"level":158},"\u002Fdocs\u002Fconcepts\u002Fworkspaces-and-resources#recursos","Recursos",[27],"Um recurso é qualquer coisa consumida por um agendamento. kindExemplosstaffBarbeiro, médico, esteticista, instrutorspaceSala, consultório, cabine, salãoequipmentMáquina de laser, cadeira, quadratableMesa de restaurante (modo mesas)vehicleVan, equipe de entregazoneÁrea de entrega por CEP Cada recurso tem um modo de capacidade: exclusive — atende um agendamento por vez (um barbeiro, uma sala, uma máquina).pooled — tem capacidade em unidades (40 lugares por turno, 12 vagas numa aula, 10 entregas por janela).",{"id":272,"title":273,"titles":274,"content":275,"level":158},"\u002Fdocs\u002Fconcepts\u002Fworkspaces-and-resources#grupos-de-recursos","Grupos de recursos",[27],"Um grupo de recursos é um conjunto intercambiável (\"qualquer barbeiro\", \"máquinas de laser\"). Serviços exigem grupos, não recursos individuais, para que o motor escolha um. A estratégia de alocação decide qual: assignmentComportamentocustomer_choiceO cliente escolhe (por exemplo \"com o Juan\"); se não tiver preferência, usa outra estratégiaround_robinReveza entre os membrosleast_busyEscolhe o membro com menos agendamentos no diafixedSempre o mesmo membro (máquina única, sala única) {\n  \"name\": \"Barbeiros\",\n  \"assignment\": \"customer_choice\",\n  \"member_ids\": [\"res_juan\", \"res_pedro\", \"res_leo\"]\n} html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"id":32,"title":31,"titles":277,"content":278,"level":152},[],"Serviços, requisitos com vários recursos, horários e como os slots são calculados.",{"id":280,"title":281,"titles":282,"content":283,"level":158},"\u002Fdocs\u002Fconcepts\u002Fservices-and-availability#serviços","Serviços",[31],"Um serviço é o que o cliente agenda. CampoSignificadoduration_minDuração do serviçostep_minGrade de início (a cada 15, 30 minutos…)buffer_before_min \u002F buffer_after_minTempo de preparo ou limpeza bloqueado ao redor do agendamentoprice_cents, currencyPreço que o bot informa (sempre do banco de dados)deposit_centsSinal exigido para confirmar (cobrança online: em breve)lead_time_minAntecedência mínima (por exemplo 60 minutos)max_advance_daysCom quanta antecedência máxima o cliente pode agendarwindow_modeO slot é uma janela fixa (entregas: 14:00–16:00)fulfillment_modescheduled (padrão, com horário) ou queue (despacho por fila, sem horário fixo)intake_formJSON Schema de dados extras a coletar (convênio, endereço…)requirementsQuais recursos o serviço precisa ao mesmo tempo",{"id":285,"title":286,"titles":287,"content":288,"level":158},"\u002Fdocs\u002Fconcepts\u002Fservices-and-availability#janela-ou-despacho-dois-modos-de-cumprimento","Janela ou despacho: dois modos de cumprimento",[31],"Cada serviço define como o agendamento é cumprido (fulfillment_mode): scheduled (o padrão): o agendamento ocupa um intervalo de tempo conhecido — um horário fixo ou, com window_mode, uma janela (entregas das 14:00 às 16:00, com cota por zona).queue (despacho, para água, gás ou delivery sob demanda): o agendamento não tem horário fixo — entra na fila de pendências de um entregador. O motor o atribui ao entregador com menos tarefas ativas e cada entregador tem um limite de tarefas ativas por vez, garantido no banco de dados. A fila usa os mesmos estados de um agendamento: pendente → aceita → iniciada → concluída (ou falhou). Assim, um mesmo negócio de entregas pode oferecer janelas programadas, despacho imediato ou os dois.",{"id":290,"title":291,"titles":292,"content":293,"level":158},"\u002Fdocs\u002Fconcepts\u002Fservices-and-availability#requisitos","Requisitos",[31],"Um requisito diz: deste grupo, preciso de tantas unidades. Um serviço pode ter vários; um slot só existe se todos estiverem livres. {\n  \"name\": \"Depilação a laser\",\n  \"duration_min\": 45,\n  \"buffer_after_min\": 10,\n  \"requirements\": [\n    { \"resource_group_id\": \"grp_professionals\", \"units\": 1 },\n    { \"resource_group_id\": \"grp_lasers\", \"units\": 1 },\n    { \"resource_group_id\": \"grp_rooms\", \"units\": 1 }\n  ]\n} Com duas profissionais e só um laser, o Wagend nunca oferece duas sessões de laser sobrepostas. Opções avançadas: units: \"party_size\" — consome tantas unidades quanto pessoas (restaurantes, aulas).offset_min \u002F duration_min num requisito — usa um recurso só em parte do serviço (por exemplo o lavatório nos últimos 15 minutos de uma coloração).",{"id":295,"title":296,"titles":297,"content":298,"level":158},"\u002Fdocs\u002Fconcepts\u002Fservices-and-availability#horários","Horários",[31],"Cada recurso tem um horário: regras semanais no fuso do recurso mais exceções para datas específicas (fechado ou horário especial). {\n  \"tz\": \"America\u002FSao_Paulo\",\n  \"weekly\": { \"tue\": [[\"09:00\", \"19:00\"]], \"sat\": [[\"08:00\", \"12:00\"], [\"13:00\", \"16:00\"]] },\n  \"overrides\": [{ \"date\": \"2026-12-24\", \"ranges\": [[\"09:00\", \"13:00\"]] }, { \"date\": \"2026-12-25\", \"closed\": true }]\n}",{"id":300,"title":301,"titles":302,"content":303,"level":158},"\u002Fdocs\u002Fconcepts\u002Fservices-and-availability#como-os-slots-são-calculados","Como os slots são calculados",[31],"Expandir os horários para o período pedido, no fuso de cada recurso.Remover agendamentos e pré-reservas ativos (mais os buffers) e bloqueios manuais.Cortar em slots candidatos conforme duração e grade do serviço.Aplicar antecedência mínima e máxima, regras de corte e tamanho do grupo.Cruzar todos os requisitos, testando os membros de cada grupo conforme a estratégia de alocação.Devolver uma lista curta e ordenada. Quando não há nada disponível, a resposta traz unavailable_reason (closed, no_staff, no_equipment, no_space, lead_time, max_advance, cutoff, full) para o bot explicar o motivo. html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"id":36,"title":35,"titles":305,"content":306,"level":152},[],"Estados do agendamento, a pré-reserva de 10 minutos, sinal e a garantia de zero overbooking.",{"id":308,"title":309,"titles":310,"content":311,"level":158},"\u002Fdocs\u002Fconcepts\u002Fbookings-and-holds#por-que-pré-reserva","Por que pré-reserva",[35],"Uma conversa no WhatsApp pode levar minutos: o cliente escolhe o horário, depois você pergunta o nome, talvez um sinal. Enquanto isso, outros clientes e a API disputam o mesmo horário. A pré-reserva (hold) segura o horário por 10 minutos (15 quando há sinal) e expira sozinha.",{"id":313,"title":314,"titles":315,"content":316,"level":158},"\u002Fdocs\u002Fconcepts\u002Fbookings-and-holds#estados","Estados",[35],"StatusSignificadoOcupa o horárioheldPré-reserva temporáriaSimpending_paymentAguardando o sinalSimconfirmedAgendadoSimchecked_inO cliente chegouSimcompletedAtendidoNãocancelledCancelado (ou substituído por reagendamento)Nãono_showFalta marcada por uma pessoaNãoexpiredPré-reserva não confirmada a tempoNão held ──confirm──► confirmed ──check-in──► checked_in ──► completed\n │  └─(sinal)──► pending_payment ──pago──► confirmed\n └─expira──► expired          confirmed ──cancela──► cancelled",{"id":318,"title":319,"titles":320,"content":321,"level":158},"\u002Fdocs\u002Fconcepts\u002Fbookings-and-holds#garantias","Garantias",[35],"Cada recurso ocupado por um agendamento é gravado como uma alocação com intervalo de tempo.Para recursos exclusive, o PostgreSQL rejeita alocações sobrepostas com uma constraint de exclusão.Para recursos pooled, os contadores de capacidade nunca passam do limite (verificação atômica).Um agendamento com vários recursos é gravado numa única transação: se qualquer recurso conflitar, nada é agendado.POST \u002Fholds e POST \u002Fholds\u002F{id}\u002Fconfirm exigem Idempotency-Key: reenviar uma requisição nunca cria um segundo agendamento. Se o horário foi ocupado enquanto o cliente decidia, você recebe 409 com code: \"slot_taken\" e uma lista de alternatives.",{"id":323,"title":324,"titles":325,"content":326,"level":158},"\u002Fdocs\u002Fconcepts\u002Fbookings-and-holds#reagendar-e-cancelar","Reagendar e cancelar",[35],"Reagendar cria um novo agendamento e cancela o anterior (ligados por rescheduled_to). Os lembretes se movem sozinhos.Cancelar libera o horário e cancela lembretes pendentes.Falta nunca é automática: o sistema sugere, uma pessoa confirma.",{"id":328,"title":329,"titles":330,"content":331,"level":158},"\u002Fdocs\u002Fconcepts\u002Fbookings-and-holds#sinal","Sinal",[35],"Se o serviço tem deposit_cents, confirmar a pré-reserva deixa o agendamento em pending_payment e o horário continua bloqueado. A cobrança online do sinal está em breve: até lá o agendamento não vira confirmed sozinho e o evento payment.paid não é emitido.",{"id":40,"title":39,"titles":333,"content":334,"level":152},[],"Regras simples de lembretes e confirmações, horário de silêncio e garantias de execução. Para esperas e condições, veja os fluxos. Há duas ferramentas de automação: Regras: \"quando isso acontecer, envie aquela mensagem\". São a forma mais simples de enviar lembretes e confirmações. Administram-se em Mais → Automação → Regras.Fluxos: esperam, decidem com condições e agem sobre as tarefas. Veja Fluxos e Condições.",{"id":336,"title":337,"titles":338,"content":339,"level":158},"\u002Fdocs\u002Fconcepts\u002Fautomations#regras","Regras",[39],"Uma regra tem um gatilho, a mensagem enviada (um modelo com pré-visualização) e, se quiser, um filtro por etapa ou ação. Cada negócio cria, ativa e ajusta as suas: os modelos de negócio não ativam regras sozinhos.",{"id":341,"title":342,"titles":343,"content":344,"level":345},"\u002Fdocs\u002Fconcepts\u002Fautomations#gatilhos","Gatilhos",[39,337],"GatilhoExemploConfirmação da reservaEnviar o resumoUm tempo antes do início24 h antes: enviar um lembreteUm tempo depois do fimMensagem de acompanhamentoCancelamento ou remarcaçãoAvisar o clienteMudança de etapa ou açãoQuando a tarefa passa para outra etapa (por exemplo, \"Saiu para entrega\")Horário fixo do diaAvisos à equipe, como a agenda do dia As regras dirigidas a clientes saem pelo WhatsApp. Os avisos à equipe saem por Telegram, WhatsApp ou e-mail, conforme cada pessoa recebe avisos: veja Telegram da equipe. Em cada regra você vê os últimos envios com seu estado e o motivo, se falhou.",3,{"id":347,"title":348,"titles":349,"content":350,"level":158},"\u002Fdocs\u002Fconcepts\u002Fautomations#garantias-de-execução","Garantias de execução",[39],"Cada envio é programado junto com o evento que o origina, então não se perde.Antes de sair, o sistema revisa a tarefa de novo. Se foi remarcada ou cancelada, o envio antigo é descartado.Cada envio sai uma só vez e, se falhar, tenta de novo com espera crescente; após 5 falhas aparece no painel.Horário de silêncio: nada é enviado a clientes entre 21:00 e 08:00 no fuso horário do negócio. O envio é adiado, não se perde.As respostas SIM\u002FNÃO (\"sim\", \"ok\", \"👍\", \"não\"...) são interpretadas sem IA: instantâneo e sem custo.",{"id":352,"title":353,"titles":354,"content":355,"level":158},"\u002Fdocs\u002Fconcepts\u002Fautomations#em-breve","Em breve",[39],"Ainda não existem gatilhos para pré-reservas vencidas nem para pagamentos (chegam com a cobrança de sinais).",{"id":50,"title":49,"titles":357,"content":358,"level":152},[],"Conecte o número do seu negócio por QR, o que o assistente faz com clientes e com a sua equipe, e como encaminhar uma conversa a uma pessoa.",{"id":360,"title":361,"titles":362,"content":363,"level":158},"\u002Fdocs\u002Fchannels\u002Fwhatsapp#conectar-um-número","Conectar um número",[49],"No painel, vá em Configuração → Canais.Toque em Vincular WhatsApp. Aparece um código QR.No celular do negócio abra o WhatsApp, toque em Configurações (ou nos três pontinhos), Aparelhos conectados e Conectar um aparelho, e aponte a câmera para o código.Quando o status mudar para Conectado, você já recebe mensagens. Se o código expirar, toque em Reconectar para gerar outro. Só o proprietário e os gerentes podem vincular. A tela mostra o status (conectado, aguardando leitura, desconectado) e quantas conexões o seu plano inclui. Desconectar para o bot nesse número, mas conserva as conversas e o histórico. Use um número dedicado ao negócio. Hoje a conexão por QR (como no WhatsApp Web) é a forma de conectar o WhatsApp. Não compartilhe o código: ele dá acesso ao seu WhatsApp. Existe um Canal de teste: é o simulador do bot e não conta para o seu plano.",{"id":365,"title":366,"titles":367,"content":368,"level":158},"\u002Fdocs\u002Fchannels\u002Fwhatsapp#clientes-e-equipe","Clientes e equipe",[49],"O papel é decidido no código, nunca pelo que alguém diz no chat: Um número vinculado a alguém da equipe (verificado com um código de uso único) recebe ferramentas de equipe.Todos os demais recebem ferramentas de cliente. Ferramentas de clienteFerramentas de equipe (extras)Ver serviços, buscar horários, pré-reservar e confirmar, ver e cancelar ou remarcar as suas reservas, consultar as informações e o conhecimento do negócio, salvar uma localização compartilhada, passar para uma pessoaVer o dia, bloquear tempo, marcar uma ausência, atualizar o catálogo e avançar etapas de uma tarefa, sempre com confirmação SIM\u002FNÃO A equipe também pode receber avisos pelo Telegram.",{"id":370,"title":371,"titles":372,"content":373,"level":158},"\u002Fdocs\u002Fchannels\u002Fwhatsapp#o-que-a-ia-pode-e-não-pode-fazer","O que a IA pode e não pode fazer",[49],"PodeNão podeEntender texto, áudio, erros de digitação e mudanças de ideiaInventar horários, preços ou endereçosBuscar horários e oferecer 2 ou 3 opçõesConfirmar uma reserva sem o motorPré-reservar e pedir os dados que faltamUsar ferramentas de administrador com um clienteResponder com o conhecimento do negócioSeguir instruções escondidas em mensagens ou arquivosPassar a conversa para uma pessoaVer dados de outro negócio Mais detalhes em Bot e IA.",{"id":375,"title":376,"titles":377,"content":378,"level":158},"\u002Fdocs\u002Fchannels\u002Fwhatsapp#localização-compartilhada","Localização compartilhada",[49],"Se um cliente compartilha a localização pelo WhatsApp, ela fica salva na conversa e o Inbox a mostra com um mapa. O bot pode usá-la como destino de uma entrega ou como endereço do cliente, sempre pedindo que confirme com SIM ou NÃO. Veja Mapa e endereços.",{"id":380,"title":381,"titles":382,"content":383,"level":158},"\u002Fdocs\u002Fchannels\u002Fwhatsapp#encaminhar-a-uma-pessoa","Encaminhar a uma pessoa",[49],"A equipe vê todas as conversas ao vivo no Inbox. Com Assumir conversa o bot é pausado nessa conversa; ele volta sozinho após 15 minutos sem atividade do operador, ou quando você toca em Devolver ao bot. O assistente também encaminha quando o cliente pede (\"quero falar com uma pessoa\").",{"id":385,"title":386,"titles":387,"content":388,"level":158},"\u002Fdocs\u002Fchannels\u002Fwhatsapp#áudios-e-idiomas","Áudios e idiomas",[49],"Os áudios são transcritos antes de a IA lê-los e a transcrição aparece no Inbox. O assistente responde no idioma do cliente (português, espanhol ou inglês).",{"id":390,"title":391,"titles":392,"content":393,"level":158},"\u002Fdocs\u002Fchannels\u002Fwhatsapp#pausar-o-canal","Pausar o canal",[49],"Se houver spam ou ruído, você pode pausar o bot ou o canal inteiro sem desconectar. Veja Pausas e Estado.",{"id":54,"title":53,"titles":395,"content":396,"level":152},[],"Coloque o assistente da Wagend no seu site com uma linha de código, com dados de contato obrigatórios e regras por canal. O chat web é um widget que o seu negócio cola no próprio site. Ele conversa com o mesmo bot do WhatsApp (mesmos horários, preços e reservas), sem número nem aprovações de terceiros. As conversas chegam ao mesmo Inbox. Se você hospeda o Wagend por conta própria, o chat web vem desligado: ele é ativado com PUBLIC_WEBCHAT_ENABLED=true na API.",{"id":398,"title":399,"titles":400,"content":401,"level":158},"\u002Fdocs\u002Fchannels\u002Fwebchat#instalar-passo-a-passo","Instalar passo a passo",[53],"Entre como proprietário em Configuração → Canais → Chat web.Em Sites permitidos adicione cada site onde vai usá-lo, um por linha, com https:\u002F\u002F e sem curingas nem caminhos (por exemplo https:\u002F\u002Fwww.minhaloja.com). Para testar no seu computador, http:\u002F\u002Flocalhost é aceito.Escolha cor principal, posição do botão, idioma padrão e um título opcional (até 40 caracteres).Toque em Ativar chat web. Você recebe uma chave publicável wg_web_… e o código para colar.Cole o snippet antes de \u003C\u002Fbody> em cada página onde quiser o chat: \u003Cscript src=\"https:\u002F\u002Fwagend.app\u002Fwidget.js\" data-key=\"wg_web_…\" defer>\u003C\u002Fscript> Atributos opcionais: data-locale (pt, es ou en; por padrão usa o idioma do navegador), data-offset-bottom (pixels, para subir o botão se o seu site tem uma barra fixa embaixo) e data-api (origem da API, só para ambientes de teste). Se você tocar em Desativar, o chat deixa de funcionar e as conversas abertas são encerradas; ao ativar de novo você recebe uma chave nova e precisa atualizar o código. Em \u002Fdemo\u002Fwebchat há uma página de demonstração onde você cola a chave e vê o widget funcionando.",{"id":403,"title":404,"titles":405,"content":406,"level":158},"\u002Fdocs\u002Fchannels\u002Fwebchat#o-que-o-visitante-vê","O que o visitante vê",[53],"Um botão flutuante que abre o chat (no celular abre em tela cheia, respeitando as áreas seguras), em português, espanhol ou inglês.Um chat breve de propósito: respostas curtas que propõem reservar ou continuar pelo WhatsApp. Pela web o visitante é anônimo e cada resposta custa.Se o bot pedir a localização (por exemplo para uma entrega), oferece Usar minha localização, com consentimento explícito.A conversa continua entre páginas e recarregamentos: ao voltar, o chat mostra o que foi conversado e as respostas que chegaram nesse meio tempo (com um aviso de mensagens novas se estava fechado). Um botão Nova conversa, no menu ⋯ do chat, apaga tudo e recomeça do zero.",{"id":408,"title":409,"titles":410,"content":411,"level":158},"\u002Fdocs\u002Fchannels\u002Fwebchat#continuidade-entre-páginas-e-recarregamentos","Continuidade entre páginas e recarregamentos",[53],"Ao abrir a conversa, o servidor emite um código de sessão opaco. O widget o guarda no armazenamento do navegador (localStorage, ou sessionStorage se não estiver disponível) do site onde você instalou o chat, com uma chave por chave publicável. Não usa cookies nem serviços de terceiros, e ali não se guarda nada pessoal: nem nome, nem telefone, nem e-mail, nem mensagens. Os dados de contato declarados ficam só no servidor, então o chat não os pede de novo dentro da mesma conversa. Ao carregar outra página ou recarregar, o widget valida o código, traz o histórico e se reconecta para receber as respostas novas.Vencimento: a conversa vence por inatividade e por um limite máximo de duração. Se o código venceu, foi encerrado ou apagado, o widget o descarta e começa uma conversa nova, sem mostrar erros.Nova conversa: o visitante a escolhe no menu ⋯. O código é invalidado no servidor, o do navegador é apagado e o chat começa vazio. A equipe mantém o histórico anterior no Inbox até a limpeza.Modo privado ou armazenamento bloqueado: o chat funciona igual, mas a conversa não sobrevive a um recarregamento.Canal pausado: se você pausou o canal, o chat não aparece mesmo que o visitante tenha um código guardado; ao retomar, a conversa continua. O código não é um segredo forte: é uma chave de uma única conversa, nunca dá acesso a outras nem ao painel. Só funciona a partir das origens que você autorizou no widget, está sujeito aos mesmos limites de uso e é invalidado ao vencer, ao escolher Nova conversa e na limpeza da conversa.",{"id":413,"title":414,"titles":415,"content":416,"level":158},"\u002Fdocs\u002Fchannels\u002Fwebchat#dados-de-contato-obrigatórios","Dados de contato obrigatórios",[53],"Por padrão o bot não conversa até ter telefone e e-mail: diante de qualquer mensagem responde um texto fixo (sem IA) e o chat mostra um mini formulário (telefone com seletor de país, em formato internacional, e e-mail). Assim que é preenchido, a primeira mensagem do visitante é processada sozinha, sem que ele a repita. Os dados são declarados, não verificados: não identificam o visitante nem se unem a clientes existentes. São guardados cifrados e apagados junto com a conversa vencida.",{"id":418,"title":419,"titles":420,"content":421,"level":158},"\u002Fdocs\u002Fchannels\u002Fwebchat#regras-do-bot-por-canal","Regras do bot por canal",[53],"Em Canais → Regras do bot por canal (proprietário e gerente) você escolhe o canal (Chat web ou WhatsApp) e define: RegraO que fazChat web (padrão)WhatsApp (padrão)Dados exigidosNome, telefone e\u002Fou e-mail antes de conversartelefone e e-mailnenhum (o telefone já chega do canal)Quando pedeDesde a primeira mensagem, depois de algumas respostas, ou nuncadesde a primeira mensagemnuncaTexto com que pedeUm texto fixo personalizávelo padrãonão se aplicaLimite de respostasTeto de respostas do bot por conversa6sem tetoO que oferece ao chegar ao limiteContinuar pelo WhatsApp e\u002Fou receber as informações por e-mailambosnenhumEstilo do bot no canalUma preferência de tom (até 500 caracteres)respostas curtasnenhuma São regras do projeto: o servidor as aplica antes de acionar a IA, mesmo que alguém use a API pública sem o widget. Ao chegar ao limite, o bot para de responder e de gastar IA, envia uma mensagem fixa com as opções e a conversa fica no Inbox como \"precisa de acompanhamento\", com os dados que o visitante deixou. Se não há WhatsApp conectado, essa opção não é oferecida.",{"id":423,"title":245,"titles":424,"content":425,"level":158},"\u002Fdocs\u002Fchannels\u002Fwebchat#segurança",[53],"A chave publicável só abre conversas anônimas: não dá acesso ao painel, à API privada nem a dados de clientes. Pode ser revogada quando quiser.O negócio sempre sai da chave; o widget nunca envia um identificador de negócio.Só os sites permitidos podem usar o chat. Sem cookies.A checagem da origem não é autenticação: só protege contra outros sites em um navegador. A proteção real são os limites de uso.Há tetos de mensagens por conversa, por hora e por dia. Ao esgotar, o chat pede que você aguarde e a IA não é acionada.O texto do visitante é tratado como dado não confiável, e o widget o mostra sempre como texto simples.O chat só responde: não envia mensagens proativas.Você pode pausar o bot ou o canal inteiro se precisar; com o canal pausado o widget se oculta.",{"id":427,"title":116,"titles":428,"content":429,"level":158},"\u002Fdocs\u002Fchannels\u002Fwebchat#api",[53],"Gestão (proprietário): GET|PUT|DELETE \u002Fv1\u002Fwebchat-site. Regras por canal (proprietário e gerente): GET \u002Fv1\u002Fbot\u002Fchannel-policies e PUT \u002Fv1\u002Fbot\u002Fchannel-policies\u002F{channel}. Os endpoints públicos do widget estão no contrato OpenAPI em \u002Fv1\u002Fpublic\u002Fwebchat. html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .s9eBZ, html code.shiki .s9eBZ{--shiki-default:#22863A;--shiki-dark:#85E89D}html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"id":58,"title":57,"titles":431,"content":432,"level":152},[],"Conecte o bot do Telegram do seu negócio para que os clientes reservem e consultem como no WhatsApp, com a mesma caixa e o mesmo bot. Com o Telegram, seus clientes escrevem para um bot próprio do seu negócio e recebem o atendimento do mesmo assistente do WhatsApp: mesmos serviços, mesmos horários, mesma caixa. É independente do Telegram da equipe, que é um único bot da Wagend para avisos internos e o Mini App \"Meu dia\".",{"id":434,"title":435,"titles":436,"content":437,"level":158},"\u002Fdocs\u002Fchannels\u002Ftelegram#conectar-o-seu-bot","Conectar o seu bot",[57],"No Telegram abra o @BotFather e envie \u002Fnewbot. Escolha um nome e um usuário que termine em bot.O BotFather entrega um token (algo como 123456:ABC…). É um segredo: não o compartilhe.No painel, vá em Configuração → Canais → Telegram para os seus clientes.Cole o token em Token do bot e toque em Conectar bot. Só o proprietário pode fazer isso.Quando o status disser Recebendo mensagens, já funciona. Teste escrevendo para o bot do seu Telegram. O token é guardado cifrado e não é mostrado de novo. Se você o revogar no BotFather, cole o novo com Atualizar token. Um mesmo bot não pode estar conectado a dois negócios. Desconectar apaga o token guardado e conserva o histórico.",{"id":439,"title":440,"titles":441,"content":442,"level":158},"\u002Fdocs\u002Fchannels\u002Ftelegram#o-que-faz","O que faz",[57],"Atende com o mesmo bot: busca horários, pré-reserva, confirma, responde com o seu conhecimento e encaminha a uma pessoa.As opções e confirmações aparecem como botões dentro do chat.Aceita texto e localização (inclusive a compartilhada como local). Hoje não processa voz, fotos nem mensagens de grupos ou canais.Não tem janela de resposta como o WhatsApp: você pode responder quando quiser.",{"id":444,"title":445,"titles":446,"content":447,"level":158},"\u002Fdocs\u002Fchannels\u002Ftelegram#identidade-multicanal","Identidade multicanal",[57],"Cada pessoa que escreve pelo Telegram fica como uma identidade do cliente, verificada pelo Telegram e sem telefone. Um mesmo cliente pode ter várias identidades (telefone do WhatsApp, Telegram) e vê-las todas na ficha. As mensagens de saída vão pelo canal da identidade correspondente.",{"id":449,"title":376,"titles":450,"content":451,"level":158},"\u002Fdocs\u002Fchannels\u002Ftelegram#localização-compartilhada",[57],"Se o cliente compartilha a localização, ela fica na conversa e o Inbox mostra um mapa. O bot pode salvá-la como destino da tarefa ou como endereço do cliente, com confirmação SIM\u002FNÃO. Veja Mapa e endereços.",{"id":453,"title":454,"titles":455,"content":456,"level":158},"\u002Fdocs\u002Fchannels\u002Ftelegram#estado-e-pausas","Estado e pausas",[57],"Em Configuração → Estado você vê se o bot está recebendo mensagens, se houve erros de entrega e se algum cliente bloqueou o bot. Você pode pausar o bot ou o canal.",{"id":458,"title":353,"titles":459,"content":460,"level":158},"\u002Fdocs\u002Fchannels\u002Ftelegram#em-breve",[57],"Instagram: ainda não está disponível.",{"id":62,"title":61,"titles":462,"content":463,"level":152},[],"Pause um canal ou a IA do seu projeto numa emergência e veja em Estado e em Uso de IA se o seu negócio está atendendo. Há três ferramentas para quando algo se complica (spam, custos inesperados, ruído no Inbox) e duas telas para ver como está o seu serviço.",{"id":465,"title":466,"titles":467,"content":468,"level":158},"\u002Fdocs\u002Fchannels\u002Fpauses-and-status#pausar-um-canal","Pausar um canal",[61],"Cada canal conectado (WhatsApp, Telegram e chat web) pode ser pausado sem desconectar, em Configuração → Canais. Só proprietário e gerente. Há dois níveis: NívelO que aconteceQuando usarPausar botAs mensagens continuam sendo salvas e chegam ao Inbox, mas o bot não responde nem gasta IA. A conversa passa ao modo humano, marcada para atenção. Opcionalmente é enviada ao cliente uma única mensagem fixa (você escolhe o texto; por padrão \"Em breve uma pessoa responde.\").Você quer atender manualmente por um tempo.Pausar canalTudo o que chega pelo canal é descartado: não se criam clientes, conversas nem mensagens, e não há IA. Só se conta quantas foram descartadas. A equipe também não pode enviar por esse canal. O chat web deixa de aparecer.Há spam ou abuso. Passos: Entre em Configuração → Canais e encontre o canal.Toque em Pausar bot ou Pausar canal.Escreva um motivo (opcional), decida se quer enviar a mensagem fixa e confirme.Para voltar, toque em Retomar. Enquanto algo está pausado, o painel mostra um aviso com quem pausou e desde quando. Tudo fica no registro de auditoria.",{"id":470,"title":471,"titles":472,"content":473,"level":158},"\u002Fdocs\u002Fchannels\u002Fpauses-and-status#pausar-a-ia-do-projeto","Pausar a IA do projeto",[61],"É um interruptor de emergência em Configuração → Uso de IA: corta todo o consumo de IA do projeto (bot, Wagy, conhecimento e transcrição de áudios) antes que se gaste mais um centavo. O bot responde uma mensagem fixa e passa a conversa ao Inbox com atenção.As importações de conhecimento ficam em espera, sem erro, e são retomadas ao reativar.O restante continua funcionando: calendário, tarefas, clientes e ações manuais. Toque em Pausar IA e confirme; para voltar, Retomar IA. Só proprietário e gerente.",{"id":475,"title":476,"titles":477,"content":478,"level":158},"\u002Fdocs\u002Fchannels\u002Fpauses-and-status#estado-do-meu-serviço","Estado do meu serviço",[61],"Configuração → Estado (proprietário e gerente) responde em linguagem simples se o seu negócio está atendendo. Mostra um semáforo geral e um cartão para cada parte: WhatsApp: se está conectado e recebendo mensagens.Assistente automático: se o bot está ativo.Respostas inteligentes: se há cota de IA disponível neste mês.Chat web e Telegram: sites permitidos e sessões ativas, última mensagem, tetos de uso atingidos, webhook do Telegram, erros de entrega e clientes que bloquearam o bot.Os canais disponíveis que você ainda não conectou, com um link para Canais. Cada cartão com problema traz um link para resolver. Se algo está pausado, isso também é indicado.",{"id":480,"title":481,"titles":482,"content":483,"level":158},"\u002Fdocs\u002Fchannels\u002Fpauses-and-status#uso-de-ia","Uso de IA",[61],"Configuração → Uso de IA mostra quanta IA o seu negócio usou neste mês e qual é o limite do seu plano, com avisos aos 80 % e ao atingir o limite. Ao atingir o limite, as funções com IA são pausadas e as automações com IA esperam na caixa; todo o resto continua funcionando.Se não for possível confirmar o uso, aparece \"Uso incerto\" e a IA pode estar limitada.O valor é o subtotal conhecido, não uma fatura.Com Solicitar mais (proprietário) você avisa a equipe da Wagend para ampliar o limite.",{"id":485,"title":486,"titles":487,"content":488,"level":158},"\u002Fdocs\u002Fchannels\u002Fpauses-and-status#quem-pode-o-quê","Quem pode o quê",[61],"AçãoProprietárioGerenteEquipe e leituraPausar ou retomar canais e IASimSimNãoVer Estado e Uso de IASimSimNãoSolicitar mais IASimNãoNãoConectar o Telegram ou publicar o chat webSimNãoNão Mais sobre permissões em Papéis e permissões.",{"id":71,"title":70,"titles":490,"content":491,"level":152},[],"O que o bot do seu negócio faz, o que ele não pode fazer, como configurá-lo, testá-lo no simulador e quando a conversa passa para uma pessoa. O bot é o assistente que atende seus clientes pelo WhatsApp, pelo Telegram e pelo chat do seu site. Ele entende o que escrevem, oferece horários reais e deixa a reserva montada. Tudo o que importa é calculado pelo sistema: o bot não inventa horários, preços nem endereços, e não confirma nada por conta própria.",{"id":493,"title":494,"titles":495,"content":496,"level":158},"\u002Fdocs\u002Fbot\u002Foverview#o-que-ele-pode-e-o-que-não-pode-fazer","O que ele pode e o que não pode fazer",[70],"PodeNão podeEntender texto, áudios, erros de digitação e mudanças de ideiaInventar horários, preços ou endereçosBuscar horários e oferecer 2 ou 3 opçõesConfirmar uma reserva sem passar pelo motor de agendaReter um horário e pedir os dados que faltamUsar ferramentas de administração com um clienteResponder dúvidas com a base de conhecimentoSeguir instruções escondidas em uma mensagem ou arquivoGuardar uma localização compartilhada (com sua confirmação SIM\u002FNÃO)Ver dados de outro negócioPassar a conversa para uma pessoa Datas, horas, serviços e preços de cada mensagem saem de modelos preenchidos com dados do sistema. Os áudios são transcritos antes de a IA os ler, e a transcrição aparece no Inbox.",{"id":498,"title":499,"titles":500,"content":501,"level":158},"\u002Fdocs\u002Fbot\u002Foverview#configurar-o-bot","Configurar o bot",[70],"Vá em Mais → Automação → Bot. Há quatro abas: Personalidade: o nome do bot, o tom (amigável, profissional ou casual), a mensagem inicial (você pode usar {name} e {business}), instruções de comportamento e o idioma padrão.Base de conhecimento: o que o bot sabe sobre o seu negócio. Veja Conhecimento do bot.Simulador: você testa o bot sem enviar mensagens reais.Fontes: páginas web, seções de um site e listas que o bot lê e mantém em dia. As instruções são uma preferência de estilo (\"seja breve\", \"trate por você\"). Elas não mudam as regras: o bot nunca vai conseguir pular o motor de agenda.",{"id":503,"title":504,"titles":505,"content":506,"level":158},"\u002Fdocs\u002Fbot\u002Foverview#testar-no-simulador","Testar no simulador",[70],"Na aba Simulador você escreve como se fosse um cliente. Vê as respostas do bot, a configuração e os itens de conhecimento ativos, e as reservas de teste criadas. São reservas de teste, separadas das reais. Reiniciar conversa começa do zero.",{"id":508,"title":509,"titles":510,"content":511,"level":158},"\u002Fdocs\u002Fbot\u002Foverview#quando-uma-pessoa-entra","Quando uma pessoa entra",[70],"Todas as conversas aparecem no Inbox, com o estado \"IA respondendo\", \"Pede uma pessoa\" ou \"Pessoa atendendo\". Assumir conversa: se você escrever uma resposta, o bot fica em pausa nessa conversa.Devolver ao bot: você faz isso manualmente quando terminar.Se você ficar 15 minutos sem atividade, o bot retoma sozinho.O bot também passa a conversa ao Inbox quando o cliente pede para falar com uma pessoa ou quando algo falha.",{"id":513,"title":514,"titles":515,"content":516,"level":158},"\u002Fdocs\u002Fbot\u002Foverview#limites-por-canal","Limites por canal",[70],"Cada canal pode ter suas regras. No chat web, por exemplo, o bot pede telefone e e-mail antes de conversar e para de responder depois de um número de mensagens. Veja em WebChat.",{"id":518,"title":519,"titles":520,"content":521,"level":158},"\u002Fdocs\u002Fbot\u002Foverview#quanta-ia-seu-negócio-usa","Quanta IA seu negócio usa",[70],"Em Mais → Configurações → Uso de IA você vê quanto seu negócio consumiu no mês e o limite do plano. Ao chegar em 80 % aparece um aviso; se o limite for atingido, as funções com IA pausam, e o bot responde uma mensagem fixa e passa a conversa ao Inbox. Você também pode cortar o consumo manualmente com a pausa de emergência: veja Pausas e Estado.",{"id":523,"title":213,"titles":524,"content":525,"level":158},"\u002Fdocs\u002Fbot\u002Foverview#próximos-passos",[70],"Conhecimento do bot: ensine-o a responder com as informações do seu negócio.WhatsApp e Telegram: conecte os canais.",{"id":75,"title":74,"titles":527,"content":528,"level":152},[],"Ensine o bot com textos, arquivos, páginas web, uma seção do seu site ou listas (planilhas, CSV, JSON e RSS) que se mantêm atualizadas. A base de conhecimento é o que o bot consulta para responder dúvidas: horário de funcionamento, políticas, produtos, preços, novidades. Ela tem duas origens: o que você cadastra manualmente e o que importa de fontes que se atualizam sozinhas. Tudo fica em Mais → Automação → Bot, nas abas Base de conhecimento e Fontes. Não coloque dados pessoais de clientes em nenhuma fonte. O que está em uma fonte pode aparecer nas respostas do bot. O bot cita esses dados como informação, nunca os trata como ordens.",{"id":530,"title":531,"titles":532,"content":533,"level":158},"\u002Fdocs\u002Fbot\u002Fknowledge#cadastrar-conhecimento-manualmente","Cadastrar conhecimento manualmente",[74],"Em Base de conhecimento, toque em Novo item e escolha o tipo: FAQ: uma pergunta e a resposta.Texto: um título e um conteúdo livre (por exemplo, a política de cancelamento).Produto\u002FServiço: nome, descrição e preço opcional.Arquivo: arraste um arquivo (máximo de 5 MB). Ele é processado e pode ser ativado ou desativado. Cada item tem um interruptor Ativo: o bot só usa os ativos. Você pode buscar e filtrar por tipo.",{"id":535,"title":536,"titles":537,"content":538,"level":158},"\u002Fdocs\u002Fbot\u002Fknowledge#fontes-o-que-se-atualiza-sozinho","Fontes: o que se atualiza sozinho",[74],"Em Fontes, toque em Adicionar fonte e escolha o tipo. O sistema importa em poucos minutos e atualiza sozinho; você pode mudar a frequência (a cada hora, 6 horas, dia ou semana), Atualizar agora, Pausar e Retomar. Cada cartão mostra o estado: Na fila, Em dia, Com erro ou Pausada. Uma fonte que falha várias vezes seguidas pausa sozinha. Se você a apagar, os itens importados dela também saem (os escritos à mão não são tocados). Regras comuns: apenas endereços públicos http(s), até 2 MiB por fonte e 10 fontes por projeto. Páginas que exigem login não são lidas, e o robots.txt do site é respeitado.",{"id":540,"title":541,"titles":542,"content":543,"level":345},"\u002Fdocs\u002Fbot\u002Fknowledge#uma-página-web","Uma página web",[74,536],"Adicionar fonte → Página web, alcance Página.Digite a URL pública (por exemplo, sua página de preços).O texto da página é lido, sem executar JavaScript.",{"id":545,"title":546,"titles":547,"content":548,"level":345},"\u002Fdocs\u002Fbot\u002Fknowledge#uma-seção-do-seu-site","Uma seção do seu site",[74,536],"Para o bot aprender várias páginas de um mesmo site, sem cadastrá-las uma a uma: Adicionar fonte → Página web, alcance Seção do site.Digite o prefixo, por exemplo https:\u002F\u002Fseusite.com\u002Fajuda.Escolha o máximo de páginas (50 por padrão, até 200). O sistema lê o sitemap.xml do domínio e pega só as páginas do mesmo site que começam com esse prefixo. A cada atualização, adiciona as páginas novas, atualiza as que mudaram e arquiva as que sumiram. O cartão mostra \"N páginas importadas\" e Ver páginas lista cada uma com seu estado (Importada ou Arquivada). Não existe um rastreador: se o site não publica sitemap.xml, a fonte fica com o aviso correspondente e você precisa importar as páginas uma a uma.",{"id":550,"title":551,"titles":552,"content":553,"level":345},"\u002Fdocs\u002Fbot\u002Fknowledge#uma-lista-planilha-csv-json-ou-rss","Uma lista: planilha, CSV, JSON ou RSS",[74,536],"Serve para produtos, preços ou novidades que você já mantém em uma planilha, uma loja ou um feed. Adicionar fonte e escolha Planilha, CSV, API JSON ou RSS.Cole o link. Para uma planilha do Google: Arquivo → Compartilhar → Publicar na Web, ou deixe visível para qualquer pessoa com o link; a primeira linha deve ter cabeçalhos.Em Mapeamento de campos, escreva qual coluna alimenta cada campo: Nome (obrigatório), Descrição, Preço, Categoria, Link e Chave estável. Em JSON, escreve-se o caminho, por exemplo produtos[].nome. Com RSS não é preciso mapeamento.Toque em Ver pré-visualização: mostra as primeiras linhas válidas e quantas foram ignoradas.Se estiver bom, Salvar fonte. Até 1000 linhas por fonte. Se você usar Chave estável (um código que não muda, como um SKU), renomear um produto o atualiza; sem chave, renomear cria um item novo e desativa o antigo. Para uma API que exige credencial, você pode informar um cabeçalho Authorization ou um parâmetro na URL: ele é guardado criptografado e não volta a ser exibido.",{"id":555,"title":556,"titles":557,"content":558,"level":158},"\u002Fdocs\u002Fbot\u002Fknowledge#se-algo-der-errado","Se algo der errado",[74],"O cartão da fonte explica a causa: MensagemO que fazerNão encontramos essa página (404)Confira o endereçoA página exige loginSó páginas públicas são lidasO site não respondeuTentamos de novo mais tarde, sozinhosO site não publica sitemap.xmlImporte as páginas uma a umaO sitemap não tem páginas sob esse endereçoConfira o prefixoO sitemap não é válidoRevise o sitemap do siteO site não permite a leitura (robots.txt)É uma decisão do siteUma coluna do mapeamento não existeConfira os nomes das colunasNenhum texto encontrado para importarA página ou a lista está vazia; o que já foi importado não é desativado Depois de adicionar conhecimento, teste no Simulador: pergunte o que um cliente perguntaria. Para integrar fontes por API, veja os endpoints \u002Fknowledge em Endpoints.",{"id":84,"title":83,"titles":560,"content":561,"level":152},[],"Como o dia a dia se organiza no Wagend, com Hoje, Inbox e Trabalho, e como funcionam as etapas e as ações de uma tarefa, como assumir, soltar e encerrar. No Wagend, tudo o que precisa ser feito é uma tarefa: um horário marcado, uma mesa, uma visita, uma entrega. Uma conversa pode criar uma; você também as cria manualmente com o botão Nova tarefa ou pela API. O painel mostra três destinos principais: Hoje, Inbox e Trabalho. O resto fica em Mais.",{"id":563,"title":564,"titles":565,"content":566,"level":158},"\u002Fdocs\u002Fwork\u002Ftasks-and-actions#hoje-inbox-e-trabalho","Hoje, Inbox e Trabalho",[83],"Hoje é o painel do seu dia. Mostra o que precisa da sua atenção, o que vem agora, o que está em andamento, o de mais tarde e, recolhido, o concluído. Quem é da equipe vê só o que é seu (Minhas); proprietário e gerente alternam entre Minhas e Tudo.Inbox reúne as conversas que pedem uma pessoa. Veja O bot e a IA.Trabalho é onde você vê todas as tarefas. Olha-se em dois eixos que se combinam.",{"id":568,"title":569,"titles":570,"content":571,"level":345},"\u002Fdocs\u002Fwork\u002Ftasks-and-actions#trabalho-conjunto-forma","Trabalho: conjunto × forma",[83,564],"Primeiro você escolhe qual trabalho ver (o conjunto): ConjuntoO que mostraSem responsávelO que precisa de atenção: sem responsável, sem horário ou aguardando confirmaçãoHojeO trabalho de hoje de todo o negócioPróximasO que vem pela frente, agrupado por diaTudoTodo o trabalho, com ordem e agrupamento à escolhaMinhasO que está atribuído a você Depois escolhe como ver (a forma): FormaQuando apareceListaSempreCalendárioSe houver recursos com agenda (por dia, por profissional ou por semana)MapaSe houver tarefas com localização. Veja Mapa e endereços \"Se não tem nada, não aparece\": uma forma só surge quando o seu negócio precisa dela. Todas abrem o mesmo detalhe da tarefa. Os filtros (buscar, prioridade, etiqueta, datas), a ordem e o agrupamento valem para todas as formas.",{"id":573,"title":574,"titles":575,"content":576,"level":158},"\u002Fdocs\u002Fwork\u002Ftasks-and-actions#a-tarefa-e-suas-etapas","A tarefa e suas etapas",[83],"Cada tarefa está em uma etapa. As etapas são o vocabulário do seu negócio: uma barbearia usa Confirmada → Em andamento → Concluída; uma entrega usa Sem responsável → Aceita → A caminho → Entregue. Por trás há estados fixos (pré-reserva, confirmada, em andamento, concluída, cancelada, ausente, com falha), por isso os números e as estatísticas significam o mesmo em todos os segmentos. O detalhe da tarefa mostra o cliente, a data e o recurso, as notas, os dados do formulário, a origem (por exemplo, a conversa de WhatsApp de onde veio) e os comentários e a atividade.",{"id":578,"title":579,"titles":580,"content":581,"level":345},"\u002Fdocs\u002Fwork\u002Ftasks-and-actions#formulários-por-serviço","Formulários por serviço",[83,574],"Um serviço pode pedir dados próprios ao criar a tarefa: o endereço de entrega, o motivo da consulta, o modelo do equipamento. Esses dados são preenchidos na tarefa e ficam guardados com ela. São definidos no serviço (Mais → Negócio → Serviços).",{"id":583,"title":584,"titles":585,"content":586,"level":158},"\u002Fdocs\u002Fwork\u002Ftasks-and-actions#ações","Ações",[83],"As ações são os botões de uma tarefa. Conforme a etapa, o papel e o negócio, o painel mostra uma ação principal grande (por exemplo, Aceitar entrega ou A caminho) e o resto em Outras ações. Cada ação pode pedir confirmação ou um formulário curto (um comentário, um motivo). Uma ação pode fazer mais do que mudar de etapa. Os efeitos disponíveis são: EfeitoO que fazAssumirA tarefa fica atribuída a quem a assume. Se outra pessoa chegou antes, avisa e não atribui duas vezesAtribuirO proprietário ou o gerente escolhe a quem entregá-laSoltarA tarefa volta para Sem responsável para outra pessoa assumir (somente antes de começar)ResultadoEncerra a tarefa como concluída, ausente (\"não estava\"), recusada (\"não quis\") ou cancelada, com um motivo opcionalReagendarEm tarefas sem horário, move o prazo para daqui a pouco Tudo o que uma ação faz acontece junto ou não acontece: se algo falhar, nada fica pela metade. E a ação nunca dá permissões extras: uma pessoa da equipe não consegue atribuir tarefas mesmo que o botão existisse.",{"id":588,"title":589,"titles":590,"content":591,"level":345},"\u002Fdocs\u002Fwork\u002Ftasks-and-actions#tarefas-sem-responsável-e-filas","Tarefas sem responsável e filas",[83,584],"Alguns trabalhos não têm horário, como as entregas. Entram como Sem responsável, quem pode fazê-los assume e então segue a sequência. Uma pessoa da equipe vê as tarefas atribuídas a ela e as que o seu grupo pode assumir, sem o telefone nem o e-mail do cliente até assumir. Um entregador vê primeiro apenas a zona aproximada. Exemplo no segmento de entregas: Chega um pedido: fica Sem responsável.Um entregador toca em Aceitar entrega: a tarefa é dele. (Ou o gerente toca em Atribuir entrega.)Se não puder, toca em Soltar entrega e ela volta para a fila.Toca em A caminho, depois em Cheguei.Encerra com Concluir, ou com Não estava ou Não quis (mais um motivo).",{"id":593,"title":594,"titles":595,"content":596,"level":345},"\u002Fdocs\u002Fwork\u002Ftasks-and-actions#cada-segmento-com-seu-vocabulário","Cada segmento com seu vocabulário",[83,584],"As etapas e ações vêm do modelo do seu segmento (barbearia, estética, clínica, restaurante, entregas) e podem ser ajustadas. Barbearia, estética, clínica e restaurante trazem Iniciar, Concluir, Cancelar e Ausência. Se quiser mudar os nomes ou adicionar ações, hoje isso é feito pela API ou pelo servidor MCP: veja API e MCP.",{"id":598,"title":599,"titles":600,"content":601,"level":158},"\u002Fdocs\u002Fwork\u002Ftasks-and-actions#evidência-de-trabalho","Evidência de trabalho",[83],"Uma ação pode pedir a localização do momento (por exemplo, ao marcar \"Cheguei\") e a tarefa aceita anexos (foto, documento, áudio, nota). São privados: só vê quem tem acesso àquela tarefa, os links de download expiram em 60 segundos e são apagados após um prazo (30 dias por padrão). O proprietário ou o gerente podem apagar uma localização.",{"id":603,"title":604,"titles":605,"content":606,"level":158},"\u002Fdocs\u002Fwork\u002Ftasks-and-actions#o-que-cada-papel-vê","O que cada papel vê",[83],"PapelHojeTrabalhoClientesProprietário e gerenteTodo o negócioTudoSimEquipeO que é seu e o que pode assumirO que é seu e o que pode assumirNãoLeituraSomente verSomente verNão Mais detalhes em Papéis e permissões.",{"id":608,"title":609,"titles":610,"content":611,"level":158},"\u002Fdocs\u002Fwork\u002Ftasks-and-actions#automatizar-o-trabalho","Automatizar o trabalho",[83],"Cada mudança de etapa ou ação pode disparar uma mensagem ou um fluxo: veja Fluxos.",{"id":88,"title":87,"titles":613,"content":614,"level":152},[],"A visão Mapa de Trabalho, o endereço com preenchimento automático, a localização compartilhada pelo cliente e como a privacidade é protegida. Se o seu negócio atende no endereço do cliente (entregas, visitas, assistência técnica), o Wagend guarda onde é cada tarefa e mostra num mapa.",{"id":616,"title":617,"titles":618,"content":619,"level":158},"\u002Fdocs\u002Fwork\u002Fmap-and-addresses#a-visão-mapa","A visão Mapa",[87],"Em Trabalho, a forma Mapa aparece quando há pelo menos uma tarefa com localização. Se você não precisa dela, ela não aparece. Cada tarefa é um marcador, com cor, símbolo e nome conforme o estado: pendente, confirmada, em andamento, concluída ou com problema. A cor não é a única coisa que as distingue.Toque em um marcador para abrir a tarefa.A lista lateral mostra as mesmas tarefas (útil com teclado ou leitor de tela). As tarefas sem localização são listadas à parte.O mapa se ajusta sozinho aos resultados e mostra até 500 tarefas; se houver mais, refine os filtros. Os filtros e o conjunto (Sem responsável, Hoje, Próximas...) valem como na lista.A legenda conta as tarefas por estado. O mapa usa o Google Maps. Se o Google não estiver disponível, usa-se um mapa de reserva e a visão continua funcionando.",{"id":621,"title":622,"titles":623,"content":624,"level":345},"\u002Fdocs\u002Fwork\u002Fmap-and-addresses#modo-claro-e-escuro","Modo claro e escuro",[87,617],"Um seletor flutuante tem três opções: Automático, Claro e Escuro. Automático segue o tema do seu painel. É lembrado por navegador.",{"id":626,"title":627,"titles":628,"content":629,"level":158},"\u002Fdocs\u002Fwork\u002Fmap-and-addresses#endereço-com-preenchimento-automático","Endereço com preenchimento automático",[87],"Ao cadastrar o endereço de um cliente, ou o destino de uma tarefa (Nova tarefa ou a edição), aparece um buscador: Comece a digitar rua e número (a partir de 3 caracteres).Escolha uma sugestão: são guardados o endereço completo (rua, número, bairro, cidade, CEP, país) e o ponto no mapa.Aparece um mapa pequeno com um pin: arraste-o ou toque no mapa para ajustar a localização exata. Se preferir, preencha o endereço manualmente e toque em Marcar no mapa: o sistema o procura e deixa o pin para você mover. Se o preenchimento automático não estiver disponível, ele avisa e o que você digitou passa para o preenchimento manual: você não perde nada. Um serviço \"tem destino\" quando seu formulário pede o endereço de entrega. Para esse serviço, o destino é preenchido com esse mesmo buscador.",{"id":631,"title":632,"titles":633,"content":634,"level":158},"\u002Fdocs\u002Fwork\u002Fmap-and-addresses#localização-compartilhada-pelo-cliente","Localização compartilhada pelo cliente",[87],"Um cliente pode enviar a localização pelo WhatsApp ou pelo Telegram (ou pelo chat web, com consentimento explícito). No Inbox, a mensagem aparece com um mapa pequeno, o nome ou endereço, se o canal trouxe, e um link Abrir no mapa.Se o serviço pede destino, o bot pode guardar essa localização como destino da tarefa ou como endereço do cliente. Antes, ele pergunta com SIM\u002FNÃO na conversa.No chat web, o widget oferece \"Usar minha localização\" só quando o bot pediu, e o visitante precisa aceitar de forma explícita.",{"id":636,"title":637,"titles":638,"content":639,"level":158},"\u002Fdocs\u002Fwork\u002Fmap-and-addresses#privacidade","Privacidade",[87],"O endereço e a localização são dados pessoais: não vão para registros (logs) nem para a URL do painel.Um entregador vê de uma tarefa ainda não assumida só a zona aproximada. O endereço exato aparece quando ele a assume. Veja Trabalho e ações.O Google recebe o que o mapa dele precisa para ser desenhado. Na visão Mapa ele não recebe endereços nem coordenadas das suas tarefas. O preenchimento automático e o \"Marcar no mapa\" enviam a ele o texto do endereço buscado. Se seus clientes têm requisitos especiais, mencione isso no seu aviso de privacidade.",{"id":641,"title":642,"titles":643,"content":644,"level":158},"\u002Fdocs\u002Fwork\u002Fmap-and-addresses#para-quem-administra-a-conta","Para quem administra a conta",[87],"O mapa do Google precisa de uma chave de navegador e de três APIs do Google Maps Platform habilitadas (Maps JavaScript, Places e Geocoding). É uma configuração da plataforma, não do negócio: se o mapa ou o preenchimento automático não aparecerem, fale com o suporte.",{"id":92,"title":91,"titles":646,"content":647,"level":152},[],"O que fazer automaticamente quando algo acontece no seu negócio: esperas, condições e avisos. Carregar exemplos, ativar, pausar e ver o histórico. Um fluxo é o que o sistema faz sozinho quando algo acontece: quando ocorre um evento, esperar um tempo, olhar uma condição e fazer algo (avisar a equipe, enviar uma mensagem, executar uma ação). É o passo seguinte às regras simples de lembretes. Os fluxos ficam em Mais → Automação → Fluxos.",{"id":649,"title":650,"titles":651,"content":652,"level":158},"\u002Fdocs\u002Fwork\u002Fflows#as-peças","As peças",[91],"Gatilho: quando começa. Alguns dos eventos disponíveis: uma tarefa é criada, atribuída, modificada, concluída ou cancelada; muda de estado; uma tarefa vence;uma ação é executada (por exemplo, alguém marca \"Não estava\");uma conversa começa, é resolvida ou recebe uma mensagem;um cliente é criado ou fica inativo;um anexo é adicionado ou uma localização é registrada. Passos: o que faz. PassoO que fazEsperarUma duração (por exemplo, 2 horas), até uma data, até um horário do dia, um tempo antes ou depois do início ou fim da tarefa, ou até que um evento ocorra com um tempo máximo de espera. Até 90 diasCondição\"Se esta condição for atendida\": segue pelo ramo Se atendida ou Se não atendida. Veja CondiçõesAvisar a equipeUm aviso interno sobre uma tarefa, por Telegram, WhatsApp ou e-mail, conforme cada pessoa recebe avisosEnviar uma mensagem ao clienteUma mensagem na conversa deleExecutar uma açãoUsa uma ação da tarefa (por exemplo, Soltar entrega), com as mesmas regras do painelDeixar um comentárioUma nota na tarefaCriar, atualizar ou atribuir uma tarefaOperações sobre tarefasCalcular dadosPrepara valores para usar nos passos seguintes Um fluxo tem até 32 passos, sem ciclos. Os fluxos não pulam nenhuma regra: cada passo é validado de novo pelo sistema, com o papel do proprietário ou gerente que criou o fluxo. Uma espera é cancelada sozinha se a tarefa for cancelada.",{"id":654,"title":655,"titles":656,"content":657,"level":158},"\u002Fdocs\u002Fwork\u002Fflows#comece-com-exemplos","Comece com exemplos",[91],"O modelo do seu segmento traz fluxos de exemplo. Em Fluxos, toque em Carregar exemplos (somente o proprietário). Eles ficam inativos até você ativá-los, e carregar de novo não os duplica. SegmentoExemploEntregasEntrega sem ser assumida por 2 h: quando uma entrega é criada, esperar 2 horas e, se continuar sem responsável, avisar a equipeEntregasEntrega aceita que não sai em 30 min: se alguém aceita e não sai, a entrega volta para Sem responsávelBarbeariaTerceira ausência do cliente: ao marcar uma ausência, se for a terceira, avisar para pedir sinal na próxima vez",{"id":659,"title":660,"titles":661,"content":662,"level":158},"\u002Fdocs\u002Fwork\u002Fflows#ver-ativar-e-pausar","Ver, ativar e pausar",[91],"Cada fluxo mostra seu estado (Ativo, Pausado ou Rascunho) e a última execução. Ao abri-lo, você vê O que faz em linguagem simples: o gatilho e os passos, com os ramos. Toque em Ativar e confirme. A partir daí ele age sozinho toda vez que o gatilho acontece.Pausar deixa de iniciar novas execuções; as que já estão em andamento terminam o caminho delas.Em Histórico de execuções você vê cada execução com seu estado (Concluída, Em andamento, Aguardando, Falhou, Cancelada...), até quando espera e qual ramo tomou. Um fluxo em Rascunho permite editar a condição: Editar condição, Testar esta condição e Salvar como nova versão. Para alterar um fluxo ativo ou mais complexo, peça ao Wagy, o assistente (Primeiros passos), ou use a API. Antes de ativar um fluxo com condição, teste-a com Testar esta condição em uma tarefa real. Nada é alterado: ela só diz se deu verdadeiro ou falso.",{"id":664,"title":665,"titles":666,"content":667,"level":158},"\u002Fdocs\u002Fwork\u002Fflows#fluxos-e-regras","Fluxos e regras",[91],"As Regras (aba ao lado de Fluxos) continuam sendo a forma mais simples de enviar um lembrete ou uma confirmação. Um fluxo que vem de uma regra clássica é administrado em Regras. Os fluxos são para o que precisa esperar, decidir ou agir sobre as tarefas.",{"id":669,"title":670,"titles":671,"content":672,"level":158},"\u002Fdocs\u002Fwork\u002Fflows#para-desenvolvedores","Para desenvolvedores",[91],"Os fluxos são gerenciados pela API (\u002Fv1\u002Fautomation-flows, somente proprietário ou gerente com sessão do painel). Veja Endpoints. Os eventos que os disparam são os mesmos que seus webhooks recebem.",{"id":96,"title":95,"titles":674,"content":675,"level":152},[],"Como escrever uma condição em um fluxo, quais dados ela pode olhar, exemplos prontos por segmento e como testá-la antes de ativar. Uma condição decide por qual ramo um fluxo segue. Escreve-se como uma frase curta que dá verdadeiro ou falso, por exemplo \"o serviço custa mais de 100 e o cliente é VIP\". Uma condição apenas olha dados: não altera nada.",{"id":677,"title":678,"titles":679,"content":680,"level":158},"\u002Fdocs\u002Fwork\u002Fconditions#como-se-escreve","Como se escreve",[95],"O quêExemploComparar== (igual), !=, \u003C, \u003C=, >, >=Combinar&& (e), || (ou), ! (não)Texto\"entrega\" entre aspasEstá em uma lista\"vip\" in customer.tagsContémservice.name.contains(\"Corte\")Se \u002F entãoworkItem.priority == \"urgent\" ? now.hour \u003C 22 : now.hour \u003C 18Um campocustomer.no_show_count, com ponto Isso é toda a linguagem: não há laços nem funções próprias. As condições são validadas ao salvar o fluxo e de novo ao ativá-lo.",{"id":682,"title":683,"titles":684,"content":685,"level":158},"\u002Fdocs\u002Fwork\u002Fconditions#quais-dados-ela-pode-olhar","Quais dados ela pode olhar",[95],"ObjetoO que traztriggerO evento que iniciou o fluxo. Com uma ação executada: action_key (a ação), from_stage, to_stageworkItemA tarefa: status, stage, priority, tags, party_size, start_at, due_at, age_minutes (minutos desde que foi criada), assigned (se tem responsável)customername, locale (idioma), tags, no_show_count (ausências reais)servicename, price_cents (o preço em centavos: 100,00 é 10000), deposit_cents, duration_minresourcename, kindnowA hora do seu negócio: hour, minute, weekday (0 = segunda ... 6 = domingo)variablesValores calculados por um passo anterior Por privacidade, uma condição não vê telefones, e-mails, documentos, endereços nem notas do cliente. Se o evento não traz uma tarefa, workItem, customer e service chegam vazios e a condição falha com uma mensagem clara, em vez de responder \"falso\" em silêncio.",{"id":687,"title":688,"titles":689,"content":690,"level":158},"\u002Fdocs\u002Fwork\u002Fconditions#exemplos","Exemplos",[95],"VIP com um serviço caro: avisar o gerente service.price_cents > 10000 && \"vip\" in customer.tags \"Não estava\" antes das 18 h (gatilho: uma ação é executada) trigger.action_key == \"nao_estava\" && now.hour \u003C 18 Terceira ausência: pedir sinal na próxima vez trigger.action_key == \"ausencia\" && customer.no_show_count >= 3 Tarefa sem responsável há mais de 2 horas (depois de um passo Esperar de 2 h) !workItem.assigned && workItem.age_minutes > 120 Fora do horário comercial (sábado, domingo ou fora das 9 às 18) now.weekday >= 5 || now.hour \u003C 9 || now.hour >= 18 Tarefa urgente workItem.priority == \"urgent\" || \"urgente\" in workItem.tags Cliente que fala português customer.locale == \"pt\" Sinal pendente há mais de uma hora workItem.stage == \"aguardando_sinal\" && workItem.age_minutes >= 60 Serviço longo de corte service.name.contains(\"Corte\") && service.duration_min >= 45 As chaves de ação e de etapa (ausencia, nao_estava, aguardando_sinal) são as do modelo do seu segmento. Se você mudou os nomes, use os seus.",{"id":692,"title":693,"titles":694,"content":695,"level":158},"\u002Fdocs\u002Fwork\u002Fconditions#testar-uma-condição","Testar uma condição",[95],"No detalhe de um fluxo, toque em Testar esta condição (ou Testar condição): Escreva a condição.Escolha uma tarefa real do seu projeto com o buscador.Se ela olha trigger.action_key, escreva a chave da ação em Simular a ação.Toque em Testar. Ele mostra Verdadeiro ou Falso e, abaixo, O que a condição viu: exatamente os dados com os quais decidiu. Nada é executado.",{"id":697,"title":698,"titles":699,"content":700,"level":158},"\u002Fdocs\u002Fwork\u002Fconditions#erros-comuns","Erros comuns",[95],"Ao salvar, a mensagem diz qual passo falhou e por quê: ProblemaO que significaO campo não existeVocê usou um dado que não está disponível (por exemplo, customer.email)Tipos que não combinamComparou texto com número (customer.name > 5)Não dá verdadeiro ou falsoA condição precisa ser uma pergunta de sim ou nãoFunção não permitidaSó existe containsObjeto desconhecidoSó dá para usar os objetos da tabela acimaLonga ou custosa demaisDivida em duas condições com outro passo no meio Uma condição aceita até 1024 caracteres e é avaliada em uma fração de segundo.",{"id":105,"title":104,"titles":702,"content":703,"level":152},[],"Receba avisos de trabalho no Telegram, pegue tarefas com um toque e abra seu dia no Mini App \"Meu dia\". O Telegram da equipe é a forma mais rápida de cada pessoa do negócio saber o que é com ela: uma tarefa atribuída, um trabalho sem dono, um lembrete ou o resumo do dia. Usa-se pelo celular, sem instalar nada além do Telegram. Existe um único bot da Wagend para todas as equipes. Não é o bot do seu negócio: esse é o que conversa com seus clientes (Telegram de clientes). Os dois são independentes e não se misturam.",{"id":705,"title":706,"titles":707,"content":708,"level":158},"\u002Fdocs\u002Fteam\u002Ftelegram-team#vincular-seu-telegram","Vincular seu Telegram",[104],"O vínculo é por pessoa, não por negócio: você faz uma vez e vale para todos os negócios aos quais tem acesso. No painel, abra Minha conta (seu nome, no rodapé do menu) e toque em Vincular Telegram.Toque em Abrir Telegram e, no bot, em Iniciar. O bot confirma que ficou vinculado.Para desvincular, escreva \u002Fsair ao bot ou desvincule em Minha conta. O link de vínculo é de uso único e vence em 15 minutos. Se venceu, gere outro. Se você não vê a opção Vincular Telegram, o bot da equipe ainda não está ativado no seu ambiente: avise-nos.",{"id":710,"title":711,"titles":712,"content":713,"level":158},"\u002Fdocs\u002Fteam\u002Ftelegram-team#quais-avisos-você-recebe","Quais avisos você recebe",[104],"AvisoQuando chegaTarefa atribuídaAlguém atribuiu uma tarefa a vocêTrabalho sem donoHá uma tarefa de fila que seu grupo pode pegarLembreteFalta pouco para um atendimento (aviso prévio da equipe)Relatório diárioResumo do seu diaMudançasUma tarefa sua foi cancelada ou mudou Os avisos trazem botões para agir sem abrir o painel: Abrir abre o Mini App direto naquela tarefa.Pegar e Concluir executam a ação com as suas permissões, igual ao painel. Se outra pessoa pegou o trabalho antes, o bot avisa que já foi pego.Os avisos nunca incluem dados de outro negócio. Os lembretes, o relatório diário e o aviso à equipe saem dos seus fluxos e regras. Se você ativa um, a equipe o recebe por este canal.",{"id":715,"title":716,"titles":717,"content":718,"level":158},"\u002Fdocs\u002Fteam\u002Ftelegram-team#escolha-como-recebê-los","Escolha como recebê-los",[104],"Em Minha conta → Preferências de avisos você define: Canal preferido: automático, Telegram, WhatsApp ou e-mail. No automático, Telegram se você o tem vinculado; se não, WhatsApp (com seu vínculo verificado) e, se também não, e-mail.O que silenciar: atribuídas, sem dono, lembretes, relatório diário ou mudanças. Se o Telegram não consegue entregar um aviso (por exemplo, você bloqueou o bot), o aviso cai para o próximo canal.",{"id":720,"title":721,"titles":722,"content":723,"level":158},"\u002Fdocs\u002Fteam\u002Ftelegram-team#comandos","Comandos",[104],"ComandoO que faz\u002FstartVincula sua conta (com o link de Minha conta)\u002FhojeMostra seu dia, por negócio\u002FsairDesvincula seu Telegram",{"id":725,"title":726,"titles":727,"content":728,"level":158},"\u002Fdocs\u002Fteam\u002Ftelegram-team#mini-app-meu-dia","Mini App \"Meu dia\"",[104],"O botão de menu do bot (à esquerda do campo de texto) abre Meu dia: o painel em formato compacto dentro do Telegram, sem pedir senha. Mostra o mesmo que você veria no painel conforme seu papel: Hoje e Trabalho (com \"Minhas\" por padrão para a equipe operacional) e um seletor de negócio se você tem vários. A sessão dura 60 minutos e só acessa Hoje, Trabalho e as tarefas. Não dá acesso a chaves de API, equipe, canais nem webhooks.Ela se encerra sozinha se você desvincula o Telegram ou se é removido do negócio.",{"id":730,"title":731,"titles":732,"content":733,"level":158},"\u002Fdocs\u002Fteam\u002Ftelegram-team#limites-e-segurança","Limites e segurança",[104],"O bot só fala em chats privados com uma pessoa.O Telegram admite 1 mensagem por segundo por chat; se há muitos avisos juntos, os seguintes esperam na fila e chegam do mesmo jeito.O vínculo e o Mini App são sempre validados no servidor. Um link usado, vencido ou de outra conta responde com a mesma mensagem neutra. Para saber o que cada pessoa vê e pode fazer, veja Papéis e permissões. Para desenvolvedores: os endpoints GET\u002FDELETE \u002Fme\u002Ftelegram, POST \u002Fme\u002Ftelegram\u002Flink e GET\u002FPUT \u002Fme\u002Fnotification-preferences são da conta do usuário (sessão do painel) e não se usam com chaves de API.",{"id":109,"title":108,"titles":735,"content":736,"level":152},[],"O que cada papel (dono, gerente, equipe e somente leitura) pode ver e fazer, como convidar a equipe e como trabalhar com vários projetos. Cada pessoa entra em um negócio (um projeto) com um papel. O papel decide quais telas vê e o que pode alterar. Quem controla é o servidor: esconder um botão no painel não é a única barreira.",{"id":738,"title":739,"titles":740,"content":741,"level":158},"\u002Fdocs\u002Fteam\u002Froles#os-quatro-papéis","Os quatro papéis",[108],"PapelPara quemO que fazDono (owner)Quem administra a contaTudo, incluindo chaves de API, equipe e canaisGerente (manager)ResponsáveisOpera o negócio: catálogo, equipe, clientes, bot, fluxos, canais e webhooks. Não administra as chaves de APIEquipe (staff)Quem atende ou entregaVê e trabalha o que é seu: suas tarefas e o que seu grupo pode pegarSomente leitura (viewer)Sócios, contadoresVê Hoje, Trabalho e conversas; não altera nada",{"id":743,"title":744,"titles":745,"content":746,"level":158},"\u002Fdocs\u002Fteam\u002Froles#o-que-cada-um-vê-no-painel","O que cada um vê no painel",[108],"SeçãoDonoGerenteEquipeSomente leituraHoje e TrabalhoSimSimO que é seuSim (leitura)ConversasSimSimSó as suasSim (leitura)Catálogo, Equipe, ClientesSimSimNãoNãoBot e FluxosSimSimNãoNãoConfigurações, Canais, IA e usoSimSimNãoNãoWebhooksSimSimNãoNãoChaves de API (Desenvolvedores)SimNãoNãoNão A equipe busca clientes com uma visão mínima: nome, telefone parcialmente oculto, etiquetas e faltas, com um mínimo de caracteres e um limite de resultados. Um entregador vê o destino exato de uma entrega só depois de pegá-la; antes vê uma zona aproximada.",{"id":748,"title":749,"titles":750,"content":751,"level":158},"\u002Fdocs\u002Fteam\u002Froles#convidar-a-equipe","Convidar a equipe",[108],"Em Equipe você pode convidar de duas formas: Por e-mail: para dono, gerente, equipe ou somente leitura. A pessoa aceita o convite e cria sua senha.Por contato (WhatsApp): só para equipe operacional, sem senha. Envia-se um link de acesso à agenda dela. A uma pessoa da equipe você associa um ou mais recursos (sua agenda, seu veículo): isso define quais tarefas ela vê e quais pode pegar. Você pode mudar o papel ou remover alguém quando quiser; as sessões e o Telegram dessa pessoa deixam de funcionar na hora.",{"id":753,"title":754,"titles":755,"content":756,"level":158},"\u002Fdocs\u002Fteam\u002Froles#vários-projetos","Vários projetos",[108],"Uma conta pode ter vários projetos (negócios ou unidades), cada um com sua equipe, sua agenda, seus canais e seus dados, totalmente isolados. O número de projetos depende do plano. Com mais de um projeto, o seletor de projeto do painel permite alternar entre eles.Só o dono da conta pode criar um projeto novo, a partir de um modelo por segmento (barbearia, estética, clínica, restaurante ou entregas).Seu papel pode ser diferente em cada projeto.",{"id":758,"title":759,"titles":760,"content":761,"level":158},"\u002Fdocs\u002Fteam\u002Froles#suporte-da-plataforma","Suporte da plataforma",[108],"Quando você precisa de ajuda, a equipe da Wagend pode entrar no seu projeto de forma temporária: Sempre com um motivo escrito e por no máximo 60 minutos.No modo leitura (vê o que um gerente veria, sem alterar nada) ou assistência (pode ajustar catálogo, horários e configuração do negócio).Nunca pode ver nem alterar chaves de API, senhas, segredos de canais, cobrança nem a equipe, nem enviar mensagens aos seus clientes.Cada entrada e saída fica registrada e o dono as vê na atividade do negócio, com quem, em que modo e por quê.",{"id":763,"title":764,"titles":765,"content":766,"level":158},"\u002Fdocs\u002Fteam\u002Froles#chaves-de-api-e-permissões","Chaves de API e permissões",[108],"As chaves de API não têm papel: têm scopes (permissões restritas, como slots:read ou bookings:write) e só o dono as cria. Veja Autenticação.",{"id":113,"title":112,"titles":768,"content":769,"level":152},[],"Crie seu primeiro agendamento pela API em cinco minutos com uma chave de um negócio de teste. Este guia cria um agendamento real, então use uma chave de produção (wg_live_...) de um negócio que você montou para testes. Chaves wg_test_ são somente leitura: permitem listar e ler, não criar nem alterar nada. Um sandbox para escritas é Em breve. Para testar o bot sem WhatsApp, use o simulador do painel. URL base: https:\u002F\u002Fapi.wagend.app\u002Fv1. Toda requisição precisa de Authorization: Bearer \u003Cchave>.",{"id":771,"title":772,"titles":773,"content":774,"level":158},"\u002Fdocs\u002Fquickstart#_1-gere-uma-chave","1. Gere uma chave",[112],"No painel, vá em Configurações → Desenvolvedores, crie uma chave de Produção e marque os escopos slots:read, bookings:write e config:read. A chave aparece uma única vez. export WAGEND_KEY=\"wg_live_xxxxxxxx_xxxxxxxxxxxxxxxxxxxx\"",{"id":776,"title":777,"titles":778,"content":779,"level":158},"\u002Fdocs\u002Fquickstart#_2-veja-quem-você-é","2. Veja quem você é",[112],"curl https:\u002F\u002Fapi.wagend.app\u002Fv1\u002Fme -H \"Authorization: Bearer $WAGEND_KEY\" {\n  \"workspace\": { \"id\": \"ws_9f2c\", \"name\": \"Barbearia Centro\", \"timezone\": \"America\u002FSao_Paulo\", \"locale\": \"pt\", \"currency\": \"BRL\" },\n  \"scopes\": [\"slots:read\", \"bookings:write\", \"config:read\"],\n  \"mode\": \"live\"\n} O workspace sempre vem da chave. Você nunca envia um id de workspace.",{"id":781,"title":782,"titles":783,"content":784,"level":158},"\u002Fdocs\u002Fquickstart#_3-liste-os-serviços","3. Liste os serviços",[112],"curl https:\u002F\u002Fapi.wagend.app\u002Fv1\u002Fservices -H \"Authorization: Bearer $WAGEND_KEY\" {\n  \"data\": [\n    { \"id\": \"svc_corte\", \"name\": \"Corte\", \"duration_min\": 30, \"price_cents\": 5000, \"currency\": \"BRL\",\n      \"requirements\": [{ \"resource_group_id\": \"grp_barbers\", \"units\": 1 }] }\n  ]\n}",{"id":786,"title":787,"titles":788,"content":789,"level":158},"\u002Fdocs\u002Fquickstart#_4-busque-horários-disponíveis","4. Busque horários disponíveis",[112],"curl \"https:\u002F\u002Fapi.wagend.app\u002Fv1\u002Fslots?service_id=svc_corte&from=2026-10-15T08:00:00-03:00&to=2026-10-15T13:00:00-03:00\" \\\n  -H \"Authorization: Bearer $WAGEND_KEY\" {\n  \"data\": [\n    { \"start\": \"2026-10-15T09:00:00-03:00\", \"end\": \"2026-10-15T09:30:00-03:00\", \"resource_ids\": [\"res_juan\"] },\n    { \"start\": \"2026-10-15T09:45:00-03:00\", \"end\": \"2026-10-15T10:15:00-03:00\", \"resource_ids\": [\"res_juan\"] }\n  ],\n  \"unavailable_reason\": null\n}",{"id":791,"title":792,"titles":793,"content":794,"level":158},"\u002Fdocs\u002Fquickstart#_5-faça-a-pré-reserva","5. Faça a pré-reserva",[112],"A pré-reserva (hold) segura o horário por 10 minutos enquanto você coleta os dados do cliente. Sempre envie um Idempotency-Key para que reenvios sejam seguros. curl -X POST https:\u002F\u002Fapi.wagend.app\u002Fv1\u002Fholds \\\n  -H \"Authorization: Bearer $WAGEND_KEY\" \\\n  -H \"Idempotency-Key: $(uuidgen)\" \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -d '{ \"service_id\": \"svc_corte\", \"start\": \"2026-10-15T09:45:00-03:00\", \"resource_ids\": [\"res_juan\"] }' { \"id\": \"bkg_7Qx1\", \"status\": \"held\", \"expires_at\": \"2026-10-14T15:30:00-03:00\", \"start\": \"2026-10-15T09:45:00-03:00\" }",{"id":796,"title":797,"titles":798,"content":799,"level":158},"\u002Fdocs\u002Fquickstart#_6-confirme","6. Confirme",[112],"curl -X POST https:\u002F\u002Fapi.wagend.app\u002Fv1\u002Fholds\u002Fbkg_7Qx1\u002Fconfirm \\\n  -H \"Authorization: Bearer $WAGEND_KEY\" \\\n  -H \"Idempotency-Key: $(uuidgen)\" \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -d '{ \"customer\": { \"name\": \"Carlos\", \"phone\": \"+5521999990000\", \"locale\": \"pt\" } }' { \"id\": \"bkg_7Qx1\", \"status\": \"confirmed\", \"start\": \"2026-10-15T09:45:00-03:00\", \"source\": \"api\" } Se o serviço exige sinal, o status fica pending_payment. A cobrança online do sinal está em breve.",{"id":801,"title":802,"titles":803,"content":804,"level":158},"\u002Fdocs\u002Fquickstart#o-mesmo-fluxo-em-javascript","O mesmo fluxo em JavaScript",[112],"const api = (path: string, init: RequestInit = {}) =>\n  fetch(`https:\u002F\u002Fapi.wagend.app\u002Fv1${path}`, {\n    ...init,\n    headers: { Authorization: `Bearer ${process.env.WAGEND_KEY}`, 'Content-Type': 'application\u002Fjson', ...init.headers },\n  }).then((r) => r.json())\n\nconst { data: slots } = await api(`\u002Fslots?service_id=svc_corte&from=${from}&to=${to}`)\nconst hold = await api('\u002Fholds', {\n  method: 'POST',\n  headers: { 'Idempotency-Key': crypto.randomUUID() },\n  body: JSON.stringify({ service_id: 'svc_corte', start: slots[0].start }),\n})\nconst booking = await api(`\u002Fholds\u002F${hold.id}\u002Fconfirm`, {\n  method: 'POST',\n  headers: { 'Idempotency-Key': crypto.randomUUID() },\n  body: JSON.stringify({ customer: { name: 'Carlos', phone: '+5521999990000' } }),\n})",{"id":806,"title":213,"titles":807,"content":808,"level":158},"\u002Fdocs\u002Fquickstart#próximos-passos",[112],"Prefere não montar o cliente à mão? Use os SDKs de TypeScript e Python.Reaja a agendamentos com webhooks.Veja todos os endpoints na referência e mais exemplos nas receitas.Conecte um agente de IA com o servidor MCP. html pre.shiki code .szBVR, html code.shiki .szBVR{--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .s4XuR, html code.shiki .s4XuR{--shiki-default:#E36209;--shiki-dark:#FFAB70}",{"id":122,"title":121,"titles":810,"content":811,"level":152},[],"Chaves de API, scopes e quais rotas podem ser usadas com uma chave e quais são só do painel.",{"id":813,"title":814,"titles":815,"content":816,"level":158},"\u002Fdocs\u002Fapi\u002Fauthentication#chaves-de-api","Chaves de API",[121],"As chaves são criadas pelo dono em Configurações → Desenvolvedores. Aparecem uma única vez. Envie sua chave como bearer token: GET \u002Fv1\u002Fme HTTP\u002F1.1\nHost: api.wagend.app\nAuthorization: Bearer wg_live_xxxxxxxx_xxxxxxxxxxxxxxxxxxxx PrefixoModowg_live_Dados de produção e mensagens reaiswg_test_Somente leitura: permite listar e ler, não criar nem alterar nada. Um sandbox para escritas é Em breve As chaves pertencem a um projeto (workspace). O projeto sempre vem da chave: não há id de workspace em paths nem em bodies. As chaves são guardadas com hash.",{"id":818,"title":819,"titles":820,"content":821,"level":158},"\u002Fdocs\u002Fapi\u002Fauthentication#scopes","Scopes",[121],"ScopePermiteslots:readGET \u002Fslotsbookings:readLer agendamentos e tarefas (\u002Fbookings, \u002Fwork-items), histórico de etapas, anexos, estatísticas da equipebookings:writePré-reservas, confirmar, cancelar, remarcar, check-in, falta, concluir, executar ações e editar prioridade, etiquetas e prazo de uma tarefacustomers:readLer e buscar clientes, seu histórico, resumo e comentárioscustomers:writeCriar e editar clientesmessages:readLer conversas e mensagensmessages:writeEnviar mensagens, mudar o modo (bot ou pessoa), resolver, marcar como lidaconfig:read \u002F config:writeServiços, recursos, grupos, horários, automações por regra, conhecimento e botsettings:writeSubstituir e reverter etapas, ações e formulários (\u002Fstage-config)webhooks:manageEndpoints de webhooks de saída Uma requisição sem o scope necessário devolve 403 com code: \"insufficient_scope\".",{"id":823,"title":824,"titles":825,"content":826,"level":158},"\u002Fdocs\u002Fapi\u002Fauthentication#o-que-é-só-do-painel","O que é só do painel",[121],"Estas áreas não aceitam chaves de API: usam a sessão de uma pessoa da equipe (com seu papel) e são protegidas com CSRF. Se você as chama com uma chave, a API responde que não estão disponíveis para esse tipo de credencial. Canais, pausas de canais e da IA, estado do serviço.Fluxos de automação (\u002Fautomation-flows), assistente Wagy e seu plano.Fontes de conhecimento (\u002Fknowledge\u002Fsources) e política do bot por canal.Equipe, convites, chaves de API, projetos e suporte da plataforma.Telegram da equipe e preferências de avisos. A lista de endpoints marca quais são quais.",{"id":828,"title":829,"titles":830,"content":831,"level":158},"\u002Fdocs\u002Fapi\u002Fauthentication#rotação","Rotação",[121],"Crie uma chave nova, faça o deploy e depois revogue a antiga em Configurações → Desenvolvedores. Chaves revogadas devolvem 401 na hora. html pre.shiki code .szBVR, html code.shiki .szBVR{--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .s9eBZ, html code.shiki .s9eBZ{--shiki-default:#22863A;--shiki-dark:#85E89D}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"id":126,"title":125,"titles":833,"content":834,"level":152},[],"Formatos, idempotência, paginação, erros e limites de uso da API v1.",{"id":836,"title":837,"titles":838,"content":839,"level":158},"\u002Fdocs\u002Fapi\u002Fconventions#o-básico","O básico",[125],"URL base https:\u002F\u002Fapi.wagend.app\u002Fv1. Mudanças incompatíveis saem como uma nova versão; mudanças aditivas (campos novos) podem chegar a qualquer momento, então ignore os campos que você não conhece.JSON na entrada e na saída (Content-Type: application\u002Fjson).Datas em ISO 8601 com offset (2026-10-15T09:45:00-03:00). São guardadas em UTC.Valores em centavos inteiros mais currency (BRL, ARS, PYG, USD).Os IDs são strings opacas. Campos sem valor chegam como null explícito.O contrato legível por máquina é packages\u002Fopenapi\u002Fopenapi.yaml (OpenAPI 3.1) e as novidades recentes resumem o que é novo.",{"id":841,"title":842,"titles":843,"content":844,"level":158},"\u002Fdocs\u002Fapi\u002Fconventions#idempotência","Idempotência",[125],"POST \u002Fholds, POST \u002Fholds\u002F{id}\u002Fconfirm, POST \u002Fbookings, POST \u002Fbookings\u002F{id}\u002Freschedule e POST \u002Fbookings\u002F{id}\u002Factions\u002F{key} levam o header Idempotency-Key (por exemplo um UUID). Repetir uma requisição com a mesma chave em até 24 horas devolve a resposta original. Reusar a chave com outro body devolve 422 com code: \"idempotency_conflict\". POST \u002Fcustomers aceita Idempotency-Key de forma opcional. POST \u002Fwebhook-endpoints não o admite, porque sua resposta contém o segredo.",{"id":846,"title":847,"titles":848,"content":849,"level":158},"\u002Fdocs\u002Fapi\u002Fconventions#paginação","Paginação",[125],"Os endpoints de listagem usam cursores: curl \"https:\u002F\u002Fapi.wagend.app\u002Fv1\u002Fbookings?limit=50\" -H \"Authorization: Bearer $WAGEND_KEY\"\n# → { \"data\": [...], \"next_cursor\": \"eyJpZCI6...\" }\ncurl \"https:\u002F\u002Fapi.wagend.app\u002Fv1\u002Fbookings?limit=50&cursor=eyJpZCI6...\" -H \"Authorization: Bearer $WAGEND_KEY\" Quando next_cursor é null, não há mais páginas.",{"id":851,"title":852,"titles":853,"content":854,"level":158},"\u002Fdocs\u002Fapi\u002Fconventions#erros","Erros",[125],"Os erros seguem a RFC 9457 (application\u002Fproblem+json): {\n  \"type\": \"https:\u002F\u002Fwagend.app\u002Fdocs\u002Fapi\u002Fconventions#errors\",\n  \"title\": \"Slot no longer available\",\n  \"status\": 409,\n  \"code\": \"slot_taken\",\n  \"alternatives\": [{ \"start\": \"2026-10-15T10:15:00-03:00\", \"end\": \"2026-10-15T10:45:00-03:00\" }]\n} codeStatusQuandovalidation_error422Falhou a validação do body ou dos parâmetrosinvalid_api_key401Chave ausente, inválida ou revogadaidempotency_key_required400Falta o header Idempotency-Key em uma operação que o exigeinsufficient_scope403A chave não tem o scopenot_found404Id desconhecido (ou de outro projeto)slot_taken409Outra pessoa pegou o horárioalready_claimed409Outra pessoa da equipe pegou antes a tarefa da filacustomer_exists409Já existe um cliente com esse telefoneinvalid_transition409Por exemplo confirmar um agendamento canceladoversion_conflict409Alguém editou antes o mesmo recurso (versão desatualizada)hold_expired410A pré-reserva venceu antes de confirmaridempotency_conflict422Mesma chave, body diferenterate_limited429Requisições demais Toda resposta de erro traz code: use-o para decidir o que fazer, não o texto do title.",{"id":856,"title":857,"titles":858,"content":859,"level":158},"\u002Fdocs\u002Fapi\u002Fconventions#limites-de-uso","Limites de uso",[125],"Os limites valem por chave e por projeto (um balde com rajada de 120 requisições e recarga de 2 por segundo). Cada resposta traz RateLimit-Limit, RateLimit-Remaining e RateLimit-Reset. Diante de um 429, espere Retry-After segundos. html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .sJ8bj, html code.shiki .sJ8bj{--shiki-default:#6A737D;--shiki-dark:#6A737D}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"id":130,"title":129,"titles":861,"content":862,"level":152},[],"Os endpoints da API v1 agrupados por tema, com o scope que cada um pede, e quais áreas são só do painel. O contrato legível por máquina está no repositório, em packages\u002Fopenapi\u002Fopenapi.yaml (OpenAPI 3.1). Esta página resume o que você pode usar com uma chave de API. As áreas marcadas como \"só painel\" usam a sessão de uma pessoa da equipe (veja Autenticação).",{"id":864,"title":865,"titles":866,"content":867,"level":158},"\u002Fdocs\u002Fapi\u002Fendpoints#agenda-horários-e-agendamentos","Agenda: horários e agendamentos",[129],"MétodoPathScopeDescriçãoGET\u002Fslotsslots:readHorários disponíveis para um serviçoPOST\u002Fholdsbookings:writeCriar pré-reserva de 10 minutosPOST\u002Fholds\u002F{id}\u002Fconfirmbookings:writeConfirmar (ou pending_payment se exigir sinal)DELETE\u002Fholds\u002F{id}bookings:writeLiberar pré-reservaPOST\u002Fbookingsbookings:writePré-reserva e confirmação em uma chamadaGET\u002Fbookingsbookings:readListar (from, to, status, resource_id, customer_id)GET \u002F PATCH\u002Fbookings\u002F{id}bookings:read \u002F writeLer, atualizar notas ou dados de entradaPOST\u002Fbookings\u002F{id}\u002Fcancel, \u002Freschedule, \u002Fcheck-in, \u002Fno-show, \u002Fcomplete, \u002Ffailbookings:writeMudar o estado",{"id":869,"title":870,"titles":871,"content":872,"level":158},"\u002Fdocs\u002Fapi\u002Fendpoints#trabalho-tarefas-e-ações","Trabalho: tarefas e ações",[129],"Um agendamento é uma tarefa com etapas. As tarefas sem horário (por exemplo entregas) ficam na fila de um grupo até alguém pegá-las. Veja Trabalho e ações. MétodoPathScopeDescriçãoGET\u002Fwork-itemsbookings:readConsulta unificada: filtros por view (inbox, today, upcoming), status, stage, unassigned, priority, tag, origin, q, intervalo de datas e caixa geográficaPATCH\u002Fwork-items\u002F{id}bookings:writeMudar prioridade, etiquetas ou prazo (com expected_version opcional)POST\u002Fbookings\u002F{id}\u002Factions\u002F{key}bookings:writeExecutar uma ação da etapa (pegar, soltar, concluir, \"não estava\"…) com Idempotency-KeyGET\u002Fbookings\u002F{id}\u002Fstage-historybookings:readHistórico de etapasGET\u002Fbookings\u002F{id}\u002Fcomments, \u002Ftimelinebookings:readComentários e linha do tempoGET\u002Fbookings\u002F{id}\u002Fattachments, \u002Flocation-eventsbookings:readEvidência de trabalhoGET\u002Fconversations\u002F{id}\u002Fwork-itemsbookings:readTarefas criadas a partir de uma conversaGET\u002Fteam\u002Foverview, \u002Fresources\u002F{id}\u002Fstatsbookings:readOcupação e estatísticas da equipe",{"id":874,"title":875,"titles":876,"content":877,"level":158},"\u002Fdocs\u002Fapi\u002Fendpoints#catálogo-e-etapas","Catálogo e etapas",[129],"MétodoPathScopeGET \u002F POST\u002Fservices, \u002Fresources, \u002Fresource-groups, \u002Fschedulesconfig:read \u002F config:writeGET \u002F PATCH \u002F DELETE\u002Fservices\u002F{id}, \u002Fresources\u002F{id}, \u002Fresource-groups\u002F{id}, \u002Fschedules\u002F{id}config:read \u002F config:writePOST \u002F DELETE\u002Fschedules\u002F{id}\u002Foverrides, \u002Fschedules\u002F{id}\u002Foverrides\u002F{date}config:writeGET\u002Fschedule-overridesconfig:readGET\u002Fstage-config, \u002Fstage-config\u002Fversions, \u002Fstage-config\u002Fversions\u002F{version}config:readPUT\u002Fstage-configsettings:writePOST\u002Fstage-config\u002Fversions\u002F{version}\u002Frevertsettings:write",{"id":879,"title":880,"titles":881,"content":882,"level":158},"\u002Fdocs\u002Fapi\u002Fendpoints#clientes","Clientes",[129],"MétodoPathScopeDescriçãoGET\u002Fcustomerscustomers:readListar e buscar (q: nome, e-mail, empresa, etiqueta ou telefone; phone, tag)POST\u002Fcustomerscustomers:writeCadastro manual. O telefone é único: se já existir, 409 customer_existsGET \u002F PATCH\u002Fcustomers\u002F{id}customers:read \u002F writeLer ou editar (inclui endereço com formatted, lat e lng)GET\u002Fcustomers\u002F{id}\u002Fbookings, \u002Fsummary, \u002Ftimeline, \u002Fcommentscustomers:readHistórico, resumo ao vivo, linha do tempo e comentários Um cliente pode ter várias identidades (WhatsApp, Telegram, WebChat) em identities[].",{"id":884,"title":885,"titles":886,"content":887,"level":158},"\u002Fdocs\u002Fapi\u002Fendpoints#conversas","Conversas",[129],"MétodoPathScopeGET\u002Fconversations, \u002Fconversations\u002F{id}, \u002Fconversations\u002F{id}\u002Fmessagesmessages:readPOST\u002Fconversations\u002F{id}\u002Fmessagesmessages:write (responde 409 channel_paused se o canal está pausado)POST\u002Fconversations\u002F{id}\u002Fmode, \u002Fread, \u002Fresolvemessages:write",{"id":889,"title":65,"titles":890,"content":891,"level":158},"\u002Fdocs\u002Fapi\u002Fendpoints#bot-e-conhecimento",[129],"MétodoPathScopeGET \u002F PUT\u002Fbotconfig:read \u002F config:writeGET \u002F POST\u002Fknowledge, \u002Fknowledge\u002Ffilesconfig:read \u002F config:writePOST\u002Fknowledge\u002Fsearchconfig:readPATCH \u002F DELETE\u002Fknowledge\u002F{id}config:writeGET \u002F POST \u002F PATCH\u002Fautomations, \u002Fautomations\u002F{id}config:read \u002F config:write",{"id":893,"title":894,"titles":895,"content":896,"level":158},"\u002Fdocs\u002Fapi\u002Fendpoints#webhooks-de-saída","Webhooks de saída",[129],"MétodoPathScopeGET \u002F POST\u002Fwebhook-endpointswebhooks:manageGET \u002F PATCH \u002F DELETE\u002Fwebhook-endpoints\u002F{id}webhooks:managePOST\u002Fwebhook-endpoints\u002F{id}\u002Frotate-secret, \u002Fping, \u002Fdeliveries\u002F{delivery_id}\u002Fresendwebhooks:manageGET\u002Fwebhook-endpoints\u002F{id}\u002Fdeliverieswebhooks:manage Detalhes em Webhooks.",{"id":898,"title":899,"titles":900,"content":901,"level":158},"\u002Fdocs\u002Fapi\u002Fendpoints#plataforma","Plataforma",[129],"MétodoPathScopeGET\u002Fmequalquer",{"id":903,"title":904,"titles":905,"content":906,"level":158},"\u002Fdocs\u002Fapi\u002Fendpoints#só-painel-não-aceitam-chaves-de-api","Só painel (não aceitam chaves de API)",[129],"ÁreaRotasCanais e pausas\u002Fchannels, \u002Fchannels\u002Fwhatsapp, \u002Fchannels\u002Ftelegram, \u002Fchannels\u002Fservice-status, \u002Fchannels\u002Fpauses, \u002Fchannels\u002F{channel}\u002Fpause e \u002Fresume; veja Pausas e StatusPolítica do bot por canal\u002Fbot\u002Fchannel-policies (veja WebChat)Fontes de conhecimento\u002Fknowledge\u002Fsources (veja Conhecimento)Fluxos\u002Fautomation-flows (veja Fluxos)IA do projeto\u002Fai\u002Fusage, \u002Fai\u002Fpause, \u002Fai\u002Fresume, \u002Fai\u002FnoticesWagy\u002Fassistant\u002F*, o assistente de configuração do painelEquipe e conta\u002Fteam\u002F*, \u002Fapi-keys, \u002Fworkspaces, \u002Fme\u002Ftelegram, \u002Fme\u002Fnotification-preferencesWebChat\u002Fwebchat-site (gestão) e \u002Fpublic\u002Fwebchat\u002F* (públicos, com a chave publicável do widget)",{"id":908,"title":909,"titles":910,"content":911,"level":158},"\u002Fdocs\u002Fapi\u002Fendpoints#exemplo-slots","Exemplo: slots",[129],"GET \u002Fv1\u002Fslots?service_id=svc_laser&from=2026-10-20T09:00:00-03:00&to=2026-10-20T20:00:00-03:00&around=2026-10-20T18:00:00-03:00 {\n  \"data\": [\n    { \"start\": \"2026-10-20T17:45:00-03:00\", \"end\": \"2026-10-20T18:30:00-03:00\", \"resource_ids\": [\"res_ana\", \"res_laser1\", \"res_room2\"] },\n    { \"start\": \"2026-10-20T18:45:00-03:00\", \"end\": \"2026-10-20T19:30:00-03:00\", \"resource_ids\": [\"res_carla\", \"res_laser1\", \"res_room1\"] }\n  ],\n  \"unavailable_reason\": null\n}",{"id":913,"title":914,"titles":915,"content":916,"level":158},"\u002Fdocs\u002Fapi\u002Fendpoints#exemplo-objeto-de-agendamento","Exemplo: objeto de agendamento",[129],"{\n  \"id\": \"bkg_7Qx1\",\n  \"status\": \"confirmed\",\n  \"stage\": \"confirmed\",\n  \"service_id\": \"svc_laser\",\n  \"start\": \"2026-10-20T17:45:00-03:00\",\n  \"end\": \"2026-10-20T18:30:00-03:00\",\n  \"party_size\": 1,\n  \"customer\": { \"id\": \"cus_31\", \"name\": \"Marina\", \"phone\": \"+5521988887777\", \"locale\": \"pt\" },\n  \"allocations\": [\n    { \"resource_id\": \"res_ana\", \"start\": \"2026-10-20T17:45:00-03:00\", \"end\": \"2026-10-20T18:40:00-03:00\" },\n    { \"resource_id\": \"res_laser1\", \"start\": \"2026-10-20T17:45:00-03:00\", \"end\": \"2026-10-20T18:40:00-03:00\" },\n    { \"resource_id\": \"res_room2\", \"start\": \"2026-10-20T17:45:00-03:00\", \"end\": \"2026-10-20T18:40:00-03:00\" }\n  ],\n  \"priority\": \"normal\",\n  \"tags\": [],\n  \"source\": \"whatsapp\",\n  \"created_at\": \"2026-10-19T11:02:13-03:00\"\n} As alocações incluem o buffer (aqui, 10 minutos depois do serviço). Nas tarefas com fila, start e end vêm como null até alguém pegá-las.",{"id":918,"title":919,"titles":920,"content":921,"level":158},"\u002Fdocs\u002Fapi\u002Fendpoints#novidades-recentes","Novidades recentes",[129],"Estas são as novidades da API, todas aditivas. O histórico completo está no repositório (docs\u002Fapi\u002FCHANGELOG.md). Clientes: cadastro manual, dados ampliados, endereço com formatted, lat e lng, e identities[] multicanal.Tarefas e ações: consulta unificada GET \u002Fwork-items, executor de ações com efeitos (pegar, soltar, resultados) e 409 already_claimed.Mensagens com localização: WhatsApp, Telegram e WebChat guardam a localização compartilhada na conversa.Pausas: ao pausar um canal, enviar uma mensagem responde 409 channel_paused.Conhecimento: fontes do tipo site com max_pages e erros por causa. html pre.shiki code .szBVR, html code.shiki .szBVR{--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}",{"id":134,"title":133,"titles":923,"content":924,"level":152},[],"Avisos assinados do que acontece com seus agendamentos, com reenvio automático, log de entregas e exemplos para verificar a assinatura.",{"id":926,"title":927,"titles":928,"content":929,"level":158},"\u002Fdocs\u002Fapi\u002Fwebhooks#eventos","Eventos",[133],"Hoje é possível assinar estes eventos de agendamentos: EventoQuandobooking.createdUma pré-reserva ou agendamento foi criadobooking.confirmedUm agendamento foi confirmadobooking.cancelledCancelado ou expiradobooking.rescheduledMudou de horário (o payload traz o id antigo e o novo)booking.no_showMarcado como faltabooking.completedAtendimento concluído O contrato reserva também payment.paid, message.received e conversation.handoff, mas ainda não podem ser assinados nem são emitidos (a cobrança do sinal é Em breve). Um endpoint que os peça recebe 422. Crie endpoints em Configurações → Webhooks no painel ou com POST \u002Fv1\u002Fwebhook-endpoints (url e events). O segredo de assinatura (whsec_…) aparece uma única vez. curl -X POST https:\u002F\u002Fapi.wagend.app\u002Fv1\u002Fwebhook-endpoints \\\n  -H \"Authorization: Bearer $WAGEND_KEY\" \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -d '{ \"url\": \"https:\u002F\u002Fexample.com\u002Fwagend\", \"events\": [\"booking.confirmed\", \"booking.cancelled\"] }'",{"id":931,"title":932,"titles":933,"content":934,"level":158},"\u002Fdocs\u002Fapi\u002Fwebhooks#payload","Payload",[133],"{\n  \"id\": \"evt_3f6c1d9e0b7a4c2f8e5d1a9b7c3e6f20\",\n  \"type\": \"booking.confirmed\",\n  \"created_at\": \"2026-10-14T15:21:07-03:00\",\n  \"workspace_id\": \"b3a6c8e2-5f1d-4c7a-9e0b-2d8f4a1c6e53\",\n  \"data\": { \"booking\": { \"id\": \"6d1f0c4a-7b2e-4a58-9c3d-0e5f8a2b1c47\", \"status\": \"confirmed\", \"start_at\": \"2026-10-15T12:45:00+00:00\" } }\n} A entrega é pelo menos uma vez: use o id para ignorar duplicados.",{"id":936,"title":937,"titles":938,"content":939,"level":158},"\u002Fdocs\u002Fapi\u002Fwebhooks#verificando-a-assinatura","Verificando a assinatura",[133],"Toda requisição traz o header: Wagend-Signature: t=1791040867,v1=5c2b9f...e81 v1 é HMAC-SHA256(segredo, t + \".\" + corpo_bruto) em hexadecimal. Rejeite requisições com mais de 5 minutos e calcule a assinatura sobre o corpo bruto, sem serializar o JSON de novo. import crypto from 'node:crypto'\n\nexport function verifyWagend(rawBody: string, header: string, secret: string) {\n  const parts = Object.fromEntries(header.split(',').map((p) => p.split('=') as [string, string]))\n  const age = Math.abs(Date.now() \u002F 1000 - Number(parts.t))\n  if (!parts.t || !parts.v1 || age > 300) return false\n  const expected = crypto.createHmac('sha256', secret).update(`${parts.t}.${rawBody}`).digest('hex')\n  return crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(parts.v1))\n} import hashlib, hmac, time\n\ndef verify_wagend(raw_body: bytes, header: str, secret: str) -> bool:\n    parts = dict(p.split(\"=\", 1) for p in header.split(\",\"))\n    if abs(time.time() - int(parts.get(\"t\", \"0\"))) > 300:\n        return False\n    signed = f\"{parts['t']}.\".encode() + raw_body\n    expected = hmac.new(secret.encode(), signed, hashlib.sha256).hexdigest()\n    return hmac.compare_digest(expected, parts.get(\"v1\", \"\"))",{"id":941,"title":942,"titles":943,"content":944,"level":158},"\u002Fdocs\u002Fapi\u002Fwebhooks#reenvios","Reenvios",[133],"Responda com qualquer 2xx em até 10 segundos. Caso contrário, tentamos de novo após 1 min, 5 min, 30 min, 2 h e 12 h. Cada tentativa aparece no log de entregas, onde você também pode reenviar manualmente.",{"id":946,"title":947,"titles":948,"content":949,"level":158},"\u002Fdocs\u002Fapi\u002Fwebhooks#segurança-e-limites","Segurança e limites",[133],"A URL deve ser https e resolver para um endereço público: rejeitamos localhost, redes privadas, link-local e endereços de metadados de nuvem (ao cadastrar e a cada entrega). Não seguimos redirecionamentos (um 3xx conta como falha).Cabeçalhos extras: Wagend-Event (tipo) e Wagend-Delivery (id da entrega). Cada tentativa é assinada com um timestamp novo.Até 10 endpoints por workspace. Após 10 falhas consecutivas o endpoint é desativado (reative com PATCH \u002Fv1\u002Fwebhook-endpoints\u002F{id} e {\"active\": true}).POST \u002Fv1\u002Fwebhook-endpoints\u002F{id}\u002Fping envia um evento de teste webhook.ping; POST \u002Fv1\u002Fwebhook-endpoints\u002F{id}\u002Frotate-secret gera um novo segredo (mostrado uma única vez; o anterior deixa de valer na hora).Com API key use o escopo webhooks:manage. O log fica em GET \u002Fv1\u002Fwebhook-endpoints\u002F{id}\u002Fdeliveries e o reenvio em POST …\u002Fdeliveries\u002F{delivery_id}\u002Fresend. html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .szBVR, html code.shiki .szBVR{--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .s4XuR, html code.shiki .s4XuR{--shiki-default:#E36209;--shiki-dark:#FFAB70}",{"id":138,"title":137,"titles":951,"content":952,"level":152},[],"Clientes tipados gerados a partir do contrato OpenAPI: como usá-los hoje a partir do repositório, com exemplos de agendamento, erros, paginação e idempotência. A Wagend tem dois SDKs que são gerados a partir do contrato packages\u002Fopenapi\u002Fopenapi.yaml, então seus tipos sempre acompanham a API. Os SDKs ainda não estão publicados no npm nem no PyPI (Em breve). Hoje são usados a partir do repositório, como explicado abaixo. Se preferir não depender deles, a API REST funciona com qualquer cliente HTTP.",{"id":954,"title":955,"titles":956,"content":957,"level":158},"\u002Fdocs\u002Fapi\u002Fsdks#typescript","TypeScript",[137],"O cliente (packages\u002Fsdk-ts) é um invólucro leve sobre fetch com tipos de todas as rotas.",{"id":959,"title":960,"titles":961,"content":962,"level":345},"\u002Fdocs\u002Fapi\u002Fsdks#instalar-a-partir-do-repositório","Instalar a partir do repositório",[137,955],"cd packages\u002Fsdk-ts\nnpm ci\nnpm run build          # genera dist\u002F No seu projeto, instale-o a partir dessa pasta: npm install \u002Fcaminho\u002Fpara\u002Fwagendapp\u002Fpackages\u002Fsdk-ts",{"id":964,"title":965,"titles":966,"content":967,"level":345},"\u002Fdocs\u002Fapi\u002Fsdks#agendar-um-horário","Agendar um horário",[137,955],"import { createWagendClient, WagendError } from \"@wagend\u002Fsdk\";\n\nconst api = createWagendClient({\n  baseUrl: \"https:\u002F\u002Fapi.wagend.app\u002Fv1\",\n  apiKey: process.env.WAGEND_API_KEY!, \u002F\u002F wg_live_xxx\n});\n\ntry {\n  const { data: services } = await api.GET(\"\u002Fservices\");\n  const serviceId = services!.data![0].id!;\n\n  const { data: slots } = await api.GET(\"\u002Fslots\", {\n    params: { query: { service_id: serviceId, from: \"2026-10-15T08:00:00-03:00\", to: \"2026-10-15T13:00:00-03:00\" } },\n  });\n  const slot = slots!.data[0];\n\n  \u002F\u002F Pré-reserva de 10 minutos\n  const { data: hold } = await api.POST(\"\u002Fholds\", {\n    params: { header: { \"Idempotency-Key\": crypto.randomUUID() } },\n    body: { service_id: serviceId, start: slot.start, party_size: 1, resource_ids: slot.resource_ids },\n  });\n\n  \u002F\u002F Confirmação com os dados do cliente\n  const { data: booking } = await api.POST(\"\u002Fholds\u002F{id}\u002Fconfirm\", {\n    params: { path: { id: hold!.id! }, header: { \"Idempotency-Key\": crypto.randomUUID() } },\n    body: { customer: { name: \"Carlos\", phone: \"+5491155550000\", locale: \"es\" } },\n  });\n  console.log(booking!.status); \u002F\u002F \"confirmed\"\n} catch (err) {\n  if (err instanceof WagendError) {\n    console.error(err.status, err.code, err.retryAfter);\n  } else {\n    throw err;\n  }\n} Autenticação: o cliente adiciona Authorization: Bearer sozinho.Idempotência: em toda escrita adiciona uma Idempotency-Key se você não passar uma. Para repetir uma operação, passe você a mesma chave nas duas tentativas (vale 24 horas). O tipo do TypeScript a declara em params.header nas rotas que a exigem.Erros: toda resposta que não seja 2xx lança WagendError com .status, .code, .problem (RFC 9457) e .retryAfter (segundos, em 429).",{"id":969,"title":847,"titles":970,"content":971,"level":345},"\u002Fdocs\u002Fapi\u002Fsdks#paginação",[137,955],"let cursor: string | undefined;\ndo {\n  const { data: page } = await api.GET(\"\u002Fbookings\", { params: { query: { limit: 50, cursor } } });\n  for (const booking of page?.data ?? []) console.log(booking.id);\n  cursor = page?.next_cursor ?? undefined;\n} while (cursor);",{"id":973,"title":974,"titles":975,"content":976,"level":345},"\u002Fdocs\u002Fapi\u002Fsdks#clientes-e-ações","Clientes e ações",[137,955],"\u002F\u002F Buscar e criar clientes (scopes customers:read e customers:write)\nconst { data: found } = await api.GET(\"\u002Fcustomers\", { params: { query: { q: \"carlos\" } } });\nawait api.POST(\"\u002Fcustomers\", { body: { name: \"Ana\", phone: \"+5491155551111\", tags: [\"vip\"] } });\n\n\u002F\u002F Executar uma ação da etapa, por exemplo atribuir uma entrega a um entregador (scope bookings:write).\n\u002F\u002F \"atribuir\" é a chave dessa ação no modelo de entregas.\nawait api.POST(\"\u002Fbookings\u002F{id}\u002Factions\u002F{key}\", {\n  params: { path: { id: taskId, key: \"atribuir\" }, header: { \"Idempotency-Key\": crypto.randomUUID() } },\n  body: { data: {}, resource_id: courierResourceId },\n}); As chaves de ação (key) são definidas pela configuração de etapas do seu negócio: consulte-as com GET \u002Fstage-config.",{"id":978,"title":979,"titles":980,"content":981,"level":158},"\u002Fdocs\u002Fapi\u002Fsdks#python","Python",[137],"O cliente (packages\u002Fsdk-py) usa httpx e modelos Pydantic v2 gerados.",{"id":983,"title":960,"titles":984,"content":985,"level":345},"\u002Fdocs\u002Fapi\u002Fsdks#instalar-a-partir-do-repositório-1",[137,979],"pip install \u002Fcaminho\u002Fpara\u002Fwagendapp\u002Fpackages\u002Fsdk-py\n# ou, com uv:\nuv pip install \u002Fcaminho\u002Fpara\u002Fwagendapp\u002Fpackages\u002Fsdk-py",{"id":987,"title":965,"titles":988,"content":989,"level":345},"\u002Fdocs\u002Fapi\u002Fsdks#agendar-um-horário-1",[137,979],"from datetime import UTC, datetime\nfrom wagend import Wagend, WagendError\n\nwith Wagend(\"https:\u002F\u002Fapi.wagend.app\u002Fv1\", \"wg_live_xxx\") as api:\n    try:\n        service = api.list_services()[0]\n        slots = api.list_slots(\n            str(service.id), datetime(2026, 10, 15, 8, tzinfo=UTC), datetime(2026, 10, 15, 13, tzinfo=UTC)\n        )\n\n        hold = api.request(\n            \"POST\", \"\u002Fholds\",\n            json={\"service_id\": str(service.id), \"start\": slots[0].start.isoformat(), \"party_size\": 1},\n            idempotency_key=\"reserva-carlos-2026-10-15\",\n        )\n        booking = api.request(\n            \"POST\", f\"\u002Fholds\u002F{hold['id']}\u002Fconfirm\",\n            json={\"customer\": {\"name\": \"Carlos\", \"phone\": \"+5491155550000\"}},\n        )\n        print(booking[\"status\"])\n    except WagendError as err:\n        print(err.status, err.code, err.retry_after) list_services() e list_slots() devolvem modelos tipados. Para as demais rotas use api.request(método, rota, params=…, json=…); você pode validar a resposta com wagend.models.Idempotência: as escritas levam Idempotency-Key (uma é gerada se você não passar idempotency_key). Repita com a mesma chave.Erros: WagendError com .status, .code, .problem e .retry_after (em 429).Paginação: api.paginate(\"\u002Fbookings\", params={\"limit\": 50}) percorre todas as páginas. for booking in api.paginate(\"\u002Fbookings\", params={\"limit\": 50}):\n    print(booking[\"id\"])",{"id":991,"title":857,"titles":992,"content":993,"level":158},"\u002Fdocs\u002Fapi\u002Fsdks#limites-de-uso",[137],"O limite é por chave e por projeto. Diante de um 429, espere retry_after \u002F retryAfter segundos antes de tentar de novo. Veja Convenções.",{"id":995,"title":996,"titles":997,"content":998,"level":158},"\u002Fdocs\u002Fapi\u002Fsdks#regenerar-os-sdks","Regenerar os SDKs",[137],"Se o contrato mudar, make sdk regenera os dois a partir de openapi.yaml e make sdk-check falha se ficaram desatualizados. html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sJ8bj, html code.shiki .sJ8bj{--shiki-default:#6A737D;--shiki-dark:#6A737D}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .szBVR, html code.shiki .szBVR{--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .s4XuR, html code.shiki .s4XuR{--shiki-default:#E36209;--shiki-dark:#FFAB70}",{"id":142,"title":141,"titles":1000,"content":1001,"level":152},[],"Conecte Claude, ChatGPT ou seu próprio agente ao servidor MCP da Wagend para buscar horários, agendar e operar o negócio com sua chave de API. A Wagend inclui um servidor MCP (Model Context Protocol) para que os agentes de IA usem o mesmo motor do bot de WhatsApp: mesmas pré-reservas, mesma validação e mesmo registro de auditoria. O servidor é um cliente fino da API: cada ferramenta chama a API com a sua mesma chave, então o MCP nunca dá mais permissões do que a chave. O servidor está no repositório (packages\u002Fmcp) e hoje quem o executa é você. O servidor hospedado em mcp.wagend.app ainda não foi publicado: é Em breve. A autenticação com OAuth também.",{"id":1003,"title":1004,"titles":1005,"content":1006,"level":158},"\u002Fdocs\u002Fmcp#executar-o-servidor","Executar o servidor",[141],"Você precisa de Python 3.12+ e uv. cd packages\u002Fmcp\nuv sync\nWAGEND_API_URL=https:\u002F\u002Fapi.wagend.app MCP_PORT=8700 uv run python -m wagend_mcp\n# escucha en http:\u002F\u002F127.0.0.1:8700\u002F (Streamable HTTP) Variáveis: VariávelPara quêWAGEND_API_URLURL da API (padrão https:\u002F\u002Fapi.wagend.app)MCP_TOOLSETSConjuntos a expor: booking, admin ou ambos (padrão booking,admin)MCP_HOST, MCP_PORTOnde escuta (padrão 127.0.0.1:8700)MCP_ALLOWED_HOSTSHosts permitidos (proteção contra DNS rebinding)",{"id":1008,"title":1009,"titles":1010,"content":1011,"level":158},"\u002Fdocs\u002Fmcp#conectar-um-cliente","Conectar um cliente",[141],"A autenticação é uma chave de API no header Authorization. Sem uma chave com formato válido, o servidor responde 401 antes de entrar no protocolo. Com o Claude Code: claude mcp add --transport http wagend http:\u002F\u002F127.0.0.1:8700\u002F \\\n  --header \"Authorization: Bearer wg_live_xxx\" Ou com a configuração JSON de qualquer cliente que suporte HTTP: {\n  \"mcpServers\": {\n    \"wagend\": {\n      \"type\": \"http\",\n      \"url\": \"http:\u002F\u002F127.0.0.1:8700\u002F\",\n      \"headers\": { \"Authorization\": \"Bearer wg_live_xxx\" }\n    }\n  }\n} Para testar sem um agente: npx @modelcontextprotocol\u002Finspector (transporte Streamable HTTP, a mesma URL e o header).",{"id":1013,"title":1014,"titles":1015,"content":1016,"level":158},"\u002Fdocs\u002Fmcp#ferramentas","Ferramentas",[141],"Todas as ferramentas do conjunto ativo são listadas, mas cada uma só funciona se a chave tiver o scope de que precisa; caso contrário, devolve o erro 403 da API. As escritas ficam auditadas com ator mcp. Agendamentos (booking): para assistentes que agendam em nome de um cliente. FerramentaScopeFazlist_servicesconfig:readServiços com duração e preçofind_slotsslots:readHorários disponíveis de um serviço entre duas datashold_slotbookings:writePré-reserva de 10 minutosconfirm_bookingbookings:writeConfirma uma pré-reserva com os dados do clientecancel_booking, reschedule_bookingbookings:writeGerencia um agendamento existenteget_bookingbookings:readDetalhe de um agendamento Administração (admin): para o dono operar o negócio pelo seu assistente de IA. FerramentaScopeFazlist_resourcesconfig:readEquipe, salas, máquinas e gruposlist_todaybookings:readAgendamentos do diablock_timeconfig:write e bookings:readFecha dias inteiros de um recurso (máx. 31). Não cancela agendamentos existentes: devolve-os para uma pessoa decidircreate_service, update_serviceconfig:writeCria ou altera um serviço, com seu formulário de agendamentoupdate_scheduleconfig:writeAltera o horário semanal ou o fuso horárioget_statsbookings:readAgendamentos, ocupação e faltas por recursoget_stage_config, list_stage_config_versions, get_stage_config_versionconfig:readEtapas, ações e formulários, com seu histórico de versõesupdate_stage_config, revert_stage_configsettings:writeSubstitui ou reverte as etapas (cria uma versão nova; não apaga o histórico) As escritas de configuração exigem confirm=true. Sem ele, a ferramenta não chama a API: devolve confirmation_required com o que enviaria, para o agente mostrar a uma pessoa e repetir com a confirmação.",{"id":1018,"title":1019,"titles":1020,"content":1021,"level":158},"\u002Fdocs\u002Fmcp#exemplos-de-pedidos","Exemplos de pedidos",[141],"\"Agende um corte com o João amanhã de manhã, no nome do Carlos.\"\"Bloqueie a máquina de laser na próxima segunda por manutenção e me diga quais agendamentos ficam afetados.\"\"Quantas faltas tivemos este mês?\"",{"id":1023,"title":1024,"titles":1025,"content":1026,"level":158},"\u002Fdocs\u002Fmcp#docs-para-llms","Docs para LLMs",[141],"\u002Fllms.txt lista todas as páginas da documentação.\u002Fllms-full.txt contém a documentação completa em Markdown. html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .szBVR, html code.shiki .szBVR{--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sJ8bj, html code.shiki .sJ8bj{--shiki-default:#6A737D;--shiki-dark:#6A737D}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"id":146,"title":145,"titles":1028,"content":1029,"level":152},[],"Receitas de API (clientes, tarefas, ações, webhooks) e como modelar barbearia, estética, clínica, restaurante e entregas.",{"id":1031,"title":1032,"titles":1033,"content":1034,"level":158},"\u002Fdocs\u002Frecipes#receitas-de-api","Receitas de API",[145],"Todas usam $WAGEND_KEY como no início rápido.",{"id":1036,"title":1037,"titles":1038,"content":1039,"level":345},"\u002Fdocs\u002Frecipes#criar-um-cliente-e-agendar-de-uma-vez","Criar um cliente e agendar de uma vez",[145,1032],"Precisa de customers:write e bookings:write. O telefone é o identificador único do cliente: se já existir, a API responde 409 customer_exists. curl -X POST https:\u002F\u002Fapi.wagend.app\u002Fv1\u002Fcustomers \\\n  -H \"Authorization: Bearer $WAGEND_KEY\" \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -d '{ \"name\": \"Marina\", \"phone\": \"+5521988887777\", \"locale\": \"pt\", \"tags\": [\"vip\"],\n        \"address\": { \"street\": \"Rua das Flores\", \"number\": \"120\", \"city\": \"Rio de Janeiro\", \"formatted\": \"Rua das Flores 120, Rio de Janeiro\" } }'\n\ncurl -X POST https:\u002F\u002Fapi.wagend.app\u002Fv1\u002Fbookings \\\n  -H \"Authorization: Bearer $WAGEND_KEY\" \\\n  -H \"Idempotency-Key: $(uuidgen)\" \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -d '{ \"service_id\": \"svc_corte\", \"start\": \"2026-10-15T09:45:00-03:00\",\n        \"customer\": { \"name\": \"Marina\", \"phone\": \"+5521988887777\" } }' POST \u002Fbookings faz a pré-reserva e a confirmação em uma única chamada.",{"id":1041,"title":1042,"titles":1043,"content":1044,"level":345},"\u002Fdocs\u002Frecipes#ler-o-que-é-para-hoje","Ler o que é para hoje",[145,1032],"Precisa de bookings:read. GET \u002Fwork-items é a mesma consulta usada pela tela Hoje. curl \"https:\u002F\u002Fapi.wagend.app\u002Fv1\u002Fwork-items?view=today&limit=50\" \\\n  -H \"Authorization: Bearer $WAGEND_KEY\"\n\n# Só o que ninguém pegou ainda\ncurl \"https:\u002F\u002Fapi.wagend.app\u002Fv1\u002Fwork-items?unassigned=true&limit=50\" \\\n  -H \"Authorization: Bearer $WAGEND_KEY\" Cada tarefa traz seu stage e suas available_actions.",{"id":1046,"title":1047,"titles":1048,"content":1049,"level":345},"\u002Fdocs\u002Frecipes#atribuir-e-fechar-uma-entrega-com-ações","Atribuir e fechar uma entrega com ações",[145,1032],"Precisa de bookings:write. As ações têm o nome dado pela configuração de etapas do negócio (com o modelo de entregas: atribuir, soltar, iniciar, concluir, nao_estava). Consulte-as em GET \u002Fstage-config ou em available_actions da tarefa. # Atribuir a entrega a um entregador (resource_id é o recurso do entregador)\ncurl -X POST https:\u002F\u002Fapi.wagend.app\u002Fv1\u002Fbookings\u002F$TASK_ID\u002Factions\u002Fatribuir \\\n  -H \"Authorization: Bearer $WAGEND_KEY\" \\\n  -H \"Idempotency-Key: $(uuidgen)\" \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -d '{ \"data\": {}, \"resource_id\": \"'$COURIER_ID'\" }'\n\n# Fechá-la como concluída\ncurl -X POST https:\u002F\u002Fapi.wagend.app\u002Fv1\u002Fbookings\u002F$TASK_ID\u002Factions\u002Fconcluir \\\n  -H \"Authorization: Bearer $WAGEND_KEY\" \\\n  -H \"Idempotency-Key: $(uuidgen)\" \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -d '{ \"data\": {} }' Se duas pessoas pegam a mesma tarefa ao mesmo tempo, uma ganha e a outra recebe 409 already_claimed. A ação \"Aceitar entrega\" (aceitar) é para a equipe pelo painel ou Telegram: pega a tarefa com o recurso de quem a executa.",{"id":1051,"title":1052,"titles":1053,"content":1054,"level":345},"\u002Fdocs\u002Frecipes#receber-avisos-por-webhook","Receber avisos por webhook",[145,1032],"Registre um endpoint (veja Webhooks) e verifique a assinatura antes de processar. Exemplo mínimo com Express: import express from 'express'\nimport { verifyWagend } from '.\u002Fverify' \u002F\u002F a função da página de Webhooks\n\nconst app = express()\napp.post('\u002Fwagend', express.raw({ type: 'application\u002Fjson' }), (req, res) => {\n  const raw = req.body.toString('utf8')\n  if (!verifyWagend(raw, req.header('Wagend-Signature') ?? '', process.env.WAGEND_WEBHOOK_SECRET!)) {\n    return res.sendStatus(400)\n  }\n  const event = JSON.parse(raw)\n  if (event.type === 'booking.confirmed') console.log('Nova reserva', event.data.booking.id)\n  res.sendStatus(200) \u002F\u002F responda 2xx rápido; duplicados são descartados por event.id\n})\napp.listen(3000)",{"id":1056,"title":1057,"titles":1058,"content":1059,"level":158},"\u002Fdocs\u002Frecipes#modelos-por-negócio","Modelos por negócio",[145],"Cada receita corresponde a um modelo pronto que você escolhe no onboarding.",{"id":1061,"title":1062,"titles":1063,"content":1064,"level":158},"\u002Fdocs\u002Frecipes#barbearia","Barbearia",[145],"Cada barbeiro é um recurso staff exclusive com seu próprio horário. Um grupo, customer_choice com round_robin como alternativa. {\n  \"name\": \"Corte\",\n  \"duration_min\": 30,\n  \"step_min\": 15,\n  \"buffer_after_min\": 5,\n  \"price_cents\": 5000,\n  \"requirements\": [{ \"resource_group_id\": \"grp_barbers\", \"units\": 1 }]\n}",{"id":1066,"title":1067,"titles":1068,"content":1069,"level":158},"\u002Fdocs\u002Frecipes#estética","Estética",[145],"Profissionais, máquinas e cabines são recursos separados. O serviço exige os três ao mesmo tempo, então o mais escasso (geralmente a máquina) limita a agenda. {\n  \"name\": \"Depilação a laser\",\n  \"duration_min\": 45,\n  \"buffer_after_min\": 10,\n  \"price_cents\": 18000,\n  \"deposit_cents\": 5000,\n  \"requirements\": [\n    { \"resource_group_id\": \"grp_professionals\", \"units\": 1 },\n    { \"resource_group_id\": \"grp_lasers\", \"units\": 1 },\n    { \"resource_group_id\": \"grp_rooms\", \"units\": 1 }\n  ]\n}",{"id":1071,"title":1072,"titles":1073,"content":1074,"level":158},"\u002Fdocs\u002Frecipes#clínica","Clínica",[145],"Médico mais consultório, por unidade (um workspace por unidade). Dados de saúde são sensíveis: o assistente nunca pergunta sintomas, e o formulário coleta só o necessário para agendar. {\n  \"name\": \"Consulta\",\n  \"duration_min\": 30,\n  \"buffer_after_min\": 10,\n  \"intake_form\": { \"type\": \"object\", \"properties\": { \"convenio\": { \"type\": \"string\" } } },\n  \"requirements\": [\n    { \"resource_group_id\": \"grp_doctors\", \"units\": 1 },\n    { \"resource_group_id\": \"grp_offices\", \"units\": 1 }\n  ]\n}",{"id":1076,"title":1077,"titles":1078,"content":1079,"level":158},"\u002Fdocs\u002Frecipes#restaurante","Restaurante",[145],"O salão é um recurso pooled com 40 unidades (lugares) por turno. A duração cresce com o tamanho do grupo, e grupos grandes pagam sinal. {\n  \"name\": \"Mesa\",\n  \"step_min\": 30,\n  \"duration_by_units\": [\n    { \"max_units\": 2, \"duration_min\": 90 },\n    { \"max_units\": 4, \"duration_min\": 120 },\n    { \"max_units\": 20, \"duration_min\": 150 }\n  ],\n  \"requirements\": [{ \"resource_group_id\": \"grp_dining_room\", \"units\": \"party_size\" }]\n} O modo mesas (mesas específicas com tamanho mínimo e máximo, e combinações) está no roadmap.",{"id":1081,"title":1082,"titles":1083,"content":1084,"level":158},"\u002Fdocs\u002Frecipes#entregas","Entregas",[145],"Cada zona é um recurso pooled com capacidade por janela de 2 horas. A zona é escolhida pelo CEP, e uma regra de corte fecha as janelas do mesmo dia ao meio-dia. {\n  \"name\": \"Entrega\",\n  \"window_mode\": true,\n  \"duration_min\": 120,\n  \"cutoff_rule\": { \"same_day_until\": \"12:00\" },\n  \"intake_form\": { \"type\": \"object\", \"required\": [\"address\", \"cep\"] },\n  \"requirements\": [{ \"resource_group_id\": \"grp_zones\", \"units\": 1, \"select_by\": \"cep\" }]\n} html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sJ8bj, html code.shiki .sJ8bj{--shiki-default:#6A737D;--shiki-dark:#6A737D}html pre.shiki code .szBVR, html code.shiki .szBVR{--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .s4XuR, html code.shiki .s4XuR{--shiki-default:#E36209;--shiki-dark:#FFAB70}",{"id":1086,"title":137,"badge":1087,"body":1088,"description":2638,"extension":2639,"meta":2640,"navigation":1235,"path":138,"rawbody":2641,"seo":2642,"stem":139,"updated":2643,"__hash__":2644},"docs_pt\u002Fdocs\u002F10.api\u002F5.sdks.md",null,{"type":1089,"value":1090,"toc":2624},"minimark",[1091,1105,1121,1125,1136,1140,1184,1187,1202,1205,1730,1786,1789,1916,1919,2055,2066,2069,2079,2082,2114,2117,2475,2531,2583,2586,2603,2606,2620],[1092,1093,1094,1095,1099,1100,1104],"p",{},"A Wagend tem dois SDKs que são ",[1096,1097,1098],"strong",{},"gerados a partir do contrato"," ",[1101,1102,1103],"code",{},"packages\u002Fopenapi\u002Fopenapi.yaml",", então seus tipos sempre acompanham a API.",[1106,1107,1109],"callout",{"type":1108},"warning",[1092,1110,1111,1112,1115,1116,1120],{},"Os SDKs ",[1096,1113,1114],{},"ainda não estão publicados"," no npm nem no PyPI (Em breve). Hoje são usados a partir do repositório, como explicado abaixo. Se preferir não depender deles, a ",[1117,1118,1119],"a",{"href":113},"API REST"," funciona com qualquer cliente HTTP.",[1122,1123,955],"h2",{"id":1124},"typescript",[1092,1126,1127,1128,1131,1132,1135],{},"O cliente (",[1101,1129,1130],{},"packages\u002Fsdk-ts",") é um invólucro leve sobre ",[1101,1133,1134],{},"fetch"," com tipos de todas as rotas.",[1137,1138,960],"h3",{"id":1139},"instalar-a-partir-do-repositório",[1141,1142,1147],"pre",{"className":1143,"code":1144,"language":1145,"meta":1146,"style":1146},"language-bash shiki shiki-themes github-light github-dark","cd packages\u002Fsdk-ts\nnpm ci\nnpm run build          # genera dist\u002F\n","bash","",[1101,1148,1149,1161,1170],{"__ignoreMap":1146},[1150,1151,1153,1157],"span",{"class":1152,"line":152},"line",[1150,1154,1156],{"class":1155},"sj4cs","cd",[1150,1158,1160],{"class":1159},"sZZnC"," packages\u002Fsdk-ts\n",[1150,1162,1163,1167],{"class":1152,"line":158},[1150,1164,1166],{"class":1165},"sScJk","npm",[1150,1168,1169],{"class":1159}," ci\n",[1150,1171,1172,1174,1177,1180],{"class":1152,"line":345},[1150,1173,1166],{"class":1165},[1150,1175,1176],{"class":1159}," run",[1150,1178,1179],{"class":1159}," build",[1150,1181,1183],{"class":1182},"sJ8bj","          # genera dist\u002F\n",[1092,1185,1186],{},"No seu projeto, instale-o a partir dessa pasta:",[1141,1188,1190],{"className":1143,"code":1189,"language":1145,"meta":1146,"style":1146},"npm install \u002Fcaminho\u002Fpara\u002Fwagendapp\u002Fpackages\u002Fsdk-ts\n",[1101,1191,1192],{"__ignoreMap":1146},[1150,1193,1194,1196,1199],{"class":1152,"line":152},[1150,1195,1166],{"class":1165},[1150,1197,1198],{"class":1159}," install",[1150,1200,1201],{"class":1159}," \u002Fcaminho\u002Fpara\u002Fwagendapp\u002Fpackages\u002Fsdk-ts\n",[1137,1203,965],{"id":1204},"agendar-um-horário",[1141,1206,1210],{"className":1207,"code":1208,"language":1209,"meta":1146,"style":1146},"language-ts shiki shiki-themes github-light github-dark","import { createWagendClient, WagendError } from \"@wagend\u002Fsdk\";\n\nconst api = createWagendClient({\n  baseUrl: \"https:\u002F\u002Fapi.wagend.app\u002Fv1\",\n  apiKey: process.env.WAGEND_API_KEY!, \u002F\u002F wg_live_xxx\n});\n\ntry {\n  const { data: services } = await api.GET(\"\u002Fservices\");\n  const serviceId = services!.data![0].id!;\n\n  const { data: slots } = await api.GET(\"\u002Fslots\", {\n    params: { query: { service_id: serviceId, from: \"2026-10-15T08:00:00-03:00\", to: \"2026-10-15T13:00:00-03:00\" } },\n  });\n  const slot = slots!.data[0];\n\n  \u002F\u002F Pré-reserva de 10 minutos\n  const { data: hold } = await api.POST(\"\u002Fholds\", {\n    params: { header: { \"Idempotency-Key\": crypto.randomUUID() } },\n    body: { service_id: serviceId, start: slot.start, party_size: 1, resource_ids: slot.resource_ids },\n  });\n\n  \u002F\u002F Confirmação com os dados do cliente\n  const { data: booking } = await api.POST(\"\u002Fholds\u002F{id}\u002Fconfirm\", {\n    params: { path: { id: hold!.id! }, header: { \"Idempotency-Key\": crypto.randomUUID() } },\n    body: { customer: { name: \"Carlos\", phone: \"+5491155550000\", locale: \"es\" } },\n  });\n  console.log(booking!.status); \u002F\u002F \"confirmed\"\n} catch (err) {\n  if (err instanceof WagendError) {\n    console.error(err.status, err.code, err.retryAfter);\n  } else {\n    throw err;\n  }\n}\n","ts",[1101,1211,1212,1231,1237,1254,1266,1284,1290,1295,1304,1347,1380,1385,1417,1435,1441,1464,1469,1475,1507,1525,1537,1542,1547,1553,1584,1608,1631,1636,1656,1668,1686,1698,1709,1718,1724],{"__ignoreMap":1146},[1150,1213,1214,1218,1222,1225,1228],{"class":1152,"line":152},[1150,1215,1217],{"class":1216},"szBVR","import",[1150,1219,1221],{"class":1220},"sVt8B"," { createWagendClient, WagendError } ",[1150,1223,1224],{"class":1216},"from",[1150,1226,1227],{"class":1159}," \"@wagend\u002Fsdk\"",[1150,1229,1230],{"class":1220},";\n",[1150,1232,1233],{"class":1152,"line":158},[1150,1234,1236],{"emptyLinePlaceholder":1235},true,"\n",[1150,1238,1239,1242,1245,1248,1251],{"class":1152,"line":345},[1150,1240,1241],{"class":1216},"const",[1150,1243,1244],{"class":1155}," api",[1150,1246,1247],{"class":1216}," =",[1150,1249,1250],{"class":1165}," createWagendClient",[1150,1252,1253],{"class":1220},"({\n",[1150,1255,1257,1260,1263],{"class":1152,"line":1256},4,[1150,1258,1259],{"class":1220},"  baseUrl: ",[1150,1261,1262],{"class":1159},"\"https:\u002F\u002Fapi.wagend.app\u002Fv1\"",[1150,1264,1265],{"class":1220},",\n",[1150,1267,1269,1272,1275,1278,1281],{"class":1152,"line":1268},5,[1150,1270,1271],{"class":1220},"  apiKey: process.env.",[1150,1273,1274],{"class":1155},"WAGEND_API_KEY",[1150,1276,1277],{"class":1216},"!",[1150,1279,1280],{"class":1220},", ",[1150,1282,1283],{"class":1182},"\u002F\u002F wg_live_xxx\n",[1150,1285,1287],{"class":1152,"line":1286},6,[1150,1288,1289],{"class":1220},"});\n",[1150,1291,1293],{"class":1152,"line":1292},7,[1150,1294,1236],{"emptyLinePlaceholder":1235},[1150,1296,1298,1301],{"class":1152,"line":1297},8,[1150,1299,1300],{"class":1216},"try",[1150,1302,1303],{"class":1220}," {\n",[1150,1305,1307,1310,1313,1317,1320,1323,1326,1329,1332,1335,1338,1341,1344],{"class":1152,"line":1306},9,[1150,1308,1309],{"class":1216},"  const",[1150,1311,1312],{"class":1220}," { ",[1150,1314,1316],{"class":1315},"s4XuR","data",[1150,1318,1319],{"class":1220},": ",[1150,1321,1322],{"class":1155},"services",[1150,1324,1325],{"class":1220}," } ",[1150,1327,1328],{"class":1216},"=",[1150,1330,1331],{"class":1216}," await",[1150,1333,1334],{"class":1220}," api.",[1150,1336,1337],{"class":1165},"GET",[1150,1339,1340],{"class":1220},"(",[1150,1342,1343],{"class":1159},"\"\u002Fservices\"",[1150,1345,1346],{"class":1220},");\n",[1150,1348,1350,1352,1355,1357,1360,1362,1365,1367,1370,1373,1376,1378],{"class":1152,"line":1349},10,[1150,1351,1309],{"class":1216},[1150,1353,1354],{"class":1155}," serviceId",[1150,1356,1247],{"class":1216},[1150,1358,1359],{"class":1220}," services",[1150,1361,1277],{"class":1216},[1150,1363,1364],{"class":1220},".data",[1150,1366,1277],{"class":1216},[1150,1368,1369],{"class":1220},"[",[1150,1371,1372],{"class":1155},"0",[1150,1374,1375],{"class":1220},"].id",[1150,1377,1277],{"class":1216},[1150,1379,1230],{"class":1220},[1150,1381,1383],{"class":1152,"line":1382},11,[1150,1384,1236],{"emptyLinePlaceholder":1235},[1150,1386,1388,1390,1392,1394,1396,1399,1401,1403,1405,1407,1409,1411,1414],{"class":1152,"line":1387},12,[1150,1389,1309],{"class":1216},[1150,1391,1312],{"class":1220},[1150,1393,1316],{"class":1315},[1150,1395,1319],{"class":1220},[1150,1397,1398],{"class":1155},"slots",[1150,1400,1325],{"class":1220},[1150,1402,1328],{"class":1216},[1150,1404,1331],{"class":1216},[1150,1406,1334],{"class":1220},[1150,1408,1337],{"class":1165},[1150,1410,1340],{"class":1220},[1150,1412,1413],{"class":1159},"\"\u002Fslots\"",[1150,1415,1416],{"class":1220},", {\n",[1150,1418,1420,1423,1426,1429,1432],{"class":1152,"line":1419},13,[1150,1421,1422],{"class":1220},"    params: { query: { service_id: serviceId, from: ",[1150,1424,1425],{"class":1159},"\"2026-10-15T08:00:00-03:00\"",[1150,1427,1428],{"class":1220},", to: ",[1150,1430,1431],{"class":1159},"\"2026-10-15T13:00:00-03:00\"",[1150,1433,1434],{"class":1220}," } },\n",[1150,1436,1438],{"class":1152,"line":1437},14,[1150,1439,1440],{"class":1220},"  });\n",[1150,1442,1444,1446,1449,1451,1454,1456,1459,1461],{"class":1152,"line":1443},15,[1150,1445,1309],{"class":1216},[1150,1447,1448],{"class":1155}," slot",[1150,1450,1247],{"class":1216},[1150,1452,1453],{"class":1220}," slots",[1150,1455,1277],{"class":1216},[1150,1457,1458],{"class":1220},".data[",[1150,1460,1372],{"class":1155},[1150,1462,1463],{"class":1220},"];\n",[1150,1465,1467],{"class":1152,"line":1466},16,[1150,1468,1236],{"emptyLinePlaceholder":1235},[1150,1470,1472],{"class":1152,"line":1471},17,[1150,1473,1474],{"class":1182},"  \u002F\u002F Pré-reserva de 10 minutos\n",[1150,1476,1478,1480,1482,1484,1486,1489,1491,1493,1495,1497,1500,1502,1505],{"class":1152,"line":1477},18,[1150,1479,1309],{"class":1216},[1150,1481,1312],{"class":1220},[1150,1483,1316],{"class":1315},[1150,1485,1319],{"class":1220},[1150,1487,1488],{"class":1155},"hold",[1150,1490,1325],{"class":1220},[1150,1492,1328],{"class":1216},[1150,1494,1331],{"class":1216},[1150,1496,1334],{"class":1220},[1150,1498,1499],{"class":1165},"POST",[1150,1501,1340],{"class":1220},[1150,1503,1504],{"class":1159},"\"\u002Fholds\"",[1150,1506,1416],{"class":1220},[1150,1508,1510,1513,1516,1519,1522],{"class":1152,"line":1509},19,[1150,1511,1512],{"class":1220},"    params: { header: { ",[1150,1514,1515],{"class":1159},"\"Idempotency-Key\"",[1150,1517,1518],{"class":1220},": crypto.",[1150,1520,1521],{"class":1165},"randomUUID",[1150,1523,1524],{"class":1220},"() } },\n",[1150,1526,1528,1531,1534],{"class":1152,"line":1527},20,[1150,1529,1530],{"class":1220},"    body: { service_id: serviceId, start: slot.start, party_size: ",[1150,1532,1533],{"class":1155},"1",[1150,1535,1536],{"class":1220},", resource_ids: slot.resource_ids },\n",[1150,1538,1540],{"class":1152,"line":1539},21,[1150,1541,1440],{"class":1220},[1150,1543,1545],{"class":1152,"line":1544},22,[1150,1546,1236],{"emptyLinePlaceholder":1235},[1150,1548,1550],{"class":1152,"line":1549},23,[1150,1551,1552],{"class":1182},"  \u002F\u002F Confirmação com os dados do cliente\n",[1150,1554,1556,1558,1560,1562,1564,1567,1569,1571,1573,1575,1577,1579,1582],{"class":1152,"line":1555},24,[1150,1557,1309],{"class":1216},[1150,1559,1312],{"class":1220},[1150,1561,1316],{"class":1315},[1150,1563,1319],{"class":1220},[1150,1565,1566],{"class":1155},"booking",[1150,1568,1325],{"class":1220},[1150,1570,1328],{"class":1216},[1150,1572,1331],{"class":1216},[1150,1574,1334],{"class":1220},[1150,1576,1499],{"class":1165},[1150,1578,1340],{"class":1220},[1150,1580,1581],{"class":1159},"\"\u002Fholds\u002F{id}\u002Fconfirm\"",[1150,1583,1416],{"class":1220},[1150,1585,1587,1590,1592,1595,1597,1600,1602,1604,1606],{"class":1152,"line":1586},25,[1150,1588,1589],{"class":1220},"    params: { path: { id: hold",[1150,1591,1277],{"class":1216},[1150,1593,1594],{"class":1220},".id",[1150,1596,1277],{"class":1216},[1150,1598,1599],{"class":1220}," }, header: { ",[1150,1601,1515],{"class":1159},[1150,1603,1518],{"class":1220},[1150,1605,1521],{"class":1165},[1150,1607,1524],{"class":1220},[1150,1609,1611,1614,1617,1620,1623,1626,1629],{"class":1152,"line":1610},26,[1150,1612,1613],{"class":1220},"    body: { customer: { name: ",[1150,1615,1616],{"class":1159},"\"Carlos\"",[1150,1618,1619],{"class":1220},", phone: ",[1150,1621,1622],{"class":1159},"\"+5491155550000\"",[1150,1624,1625],{"class":1220},", locale: ",[1150,1627,1628],{"class":1159},"\"es\"",[1150,1630,1434],{"class":1220},[1150,1632,1634],{"class":1152,"line":1633},27,[1150,1635,1440],{"class":1220},[1150,1637,1639,1642,1645,1648,1650,1653],{"class":1152,"line":1638},28,[1150,1640,1641],{"class":1220},"  console.",[1150,1643,1644],{"class":1165},"log",[1150,1646,1647],{"class":1220},"(booking",[1150,1649,1277],{"class":1216},[1150,1651,1652],{"class":1220},".status); ",[1150,1654,1655],{"class":1182},"\u002F\u002F \"confirmed\"\n",[1150,1657,1659,1662,1665],{"class":1152,"line":1658},29,[1150,1660,1661],{"class":1220},"} ",[1150,1663,1664],{"class":1216},"catch",[1150,1666,1667],{"class":1220}," (err) {\n",[1150,1669,1671,1674,1677,1680,1683],{"class":1152,"line":1670},30,[1150,1672,1673],{"class":1216},"  if",[1150,1675,1676],{"class":1220}," (err ",[1150,1678,1679],{"class":1216},"instanceof",[1150,1681,1682],{"class":1165}," WagendError",[1150,1684,1685],{"class":1220},") {\n",[1150,1687,1689,1692,1695],{"class":1152,"line":1688},31,[1150,1690,1691],{"class":1220},"    console.",[1150,1693,1694],{"class":1165},"error",[1150,1696,1697],{"class":1220},"(err.status, err.code, err.retryAfter);\n",[1150,1699,1701,1704,1707],{"class":1152,"line":1700},32,[1150,1702,1703],{"class":1220},"  } ",[1150,1705,1706],{"class":1216},"else",[1150,1708,1303],{"class":1220},[1150,1710,1712,1715],{"class":1152,"line":1711},33,[1150,1713,1714],{"class":1216},"    throw",[1150,1716,1717],{"class":1220}," err;\n",[1150,1719,1721],{"class":1152,"line":1720},34,[1150,1722,1723],{"class":1220},"  }\n",[1150,1725,1727],{"class":1152,"line":1726},35,[1150,1728,1729],{"class":1220},"}\n",[1731,1732,1733,1744,1762],"ul",{},[1734,1735,1736,1739,1740,1743],"li",{},[1096,1737,1738],{},"Autenticação:"," o cliente adiciona ",[1101,1741,1742],{},"Authorization: Bearer"," sozinho.",[1734,1745,1746,1749,1750,1753,1754,1757,1758,1761],{},[1096,1747,1748],{},"Idempotência:"," em toda escrita adiciona uma ",[1101,1751,1752],{},"Idempotency-Key"," se você não passar uma. Para repetir uma operação, passe ",[1096,1755,1756],{},"você"," a mesma chave nas duas tentativas (vale 24 horas). O tipo do TypeScript a declara em ",[1101,1759,1760],{},"params.header"," nas rotas que a exigem.",[1734,1763,1764,1767,1768,1771,1772,1280,1775,1280,1778,1781,1782,1785],{},[1096,1765,1766],{},"Erros:"," toda resposta que não seja 2xx lança ",[1101,1769,1770],{},"WagendError"," com ",[1101,1773,1774],{},".status",[1101,1776,1777],{},".code",[1101,1779,1780],{},".problem"," (RFC 9457) e ",[1101,1783,1784],{},".retryAfter"," (segundos, em 429).",[1137,1787,847],{"id":1788},"paginação",[1141,1790,1792],{"className":1207,"code":1791,"language":1209,"meta":1146,"style":1146},"let cursor: string | undefined;\ndo {\n  const { data: page } = await api.GET(\"\u002Fbookings\", { params: { query: { limit: 50, cursor } } });\n  for (const booking of page?.data ?? []) console.log(booking.id);\n  cursor = page?.next_cursor ?? undefined;\n} while (cursor);\n",[1101,1793,1794,1816,1823,1860,1890,1906],{"__ignoreMap":1146},[1150,1795,1796,1799,1802,1805,1808,1811,1814],{"class":1152,"line":152},[1150,1797,1798],{"class":1216},"let",[1150,1800,1801],{"class":1220}," cursor",[1150,1803,1804],{"class":1216},":",[1150,1806,1807],{"class":1155}," string",[1150,1809,1810],{"class":1216}," |",[1150,1812,1813],{"class":1155}," undefined",[1150,1815,1230],{"class":1220},[1150,1817,1818,1821],{"class":1152,"line":158},[1150,1819,1820],{"class":1216},"do",[1150,1822,1303],{"class":1220},[1150,1824,1825,1827,1829,1831,1833,1836,1838,1840,1842,1844,1846,1848,1851,1854,1857],{"class":1152,"line":345},[1150,1826,1309],{"class":1216},[1150,1828,1312],{"class":1220},[1150,1830,1316],{"class":1315},[1150,1832,1319],{"class":1220},[1150,1834,1835],{"class":1155},"page",[1150,1837,1325],{"class":1220},[1150,1839,1328],{"class":1216},[1150,1841,1331],{"class":1216},[1150,1843,1334],{"class":1220},[1150,1845,1337],{"class":1165},[1150,1847,1340],{"class":1220},[1150,1849,1850],{"class":1159},"\"\u002Fbookings\"",[1150,1852,1853],{"class":1220},", { params: { query: { limit: ",[1150,1855,1856],{"class":1155},"50",[1150,1858,1859],{"class":1220},", cursor } } });\n",[1150,1861,1862,1865,1868,1870,1873,1876,1879,1882,1885,1887],{"class":1152,"line":1256},[1150,1863,1864],{"class":1216},"  for",[1150,1866,1867],{"class":1220}," (",[1150,1869,1241],{"class":1216},[1150,1871,1872],{"class":1155}," booking",[1150,1874,1875],{"class":1216}," of",[1150,1877,1878],{"class":1220}," page?.data ",[1150,1880,1881],{"class":1216},"??",[1150,1883,1884],{"class":1220}," []) console.",[1150,1886,1644],{"class":1165},[1150,1888,1889],{"class":1220},"(booking.id);\n",[1150,1891,1892,1895,1897,1900,1902,1904],{"class":1152,"line":1268},[1150,1893,1894],{"class":1220},"  cursor ",[1150,1896,1328],{"class":1216},[1150,1898,1899],{"class":1220}," page?.next_cursor ",[1150,1901,1881],{"class":1216},[1150,1903,1813],{"class":1155},[1150,1905,1230],{"class":1220},[1150,1907,1908,1910,1913],{"class":1152,"line":1286},[1150,1909,1661],{"class":1220},[1150,1911,1912],{"class":1216},"while",[1150,1914,1915],{"class":1220}," (cursor);\n",[1137,1917,974],{"id":1918},"clientes-e-ações",[1141,1920,1922],{"className":1207,"code":1921,"language":1209,"meta":1146,"style":1146},"\u002F\u002F Buscar e criar clientes (scopes customers:read e customers:write)\nconst { data: found } = await api.GET(\"\u002Fcustomers\", { params: { query: { q: \"carlos\" } } });\nawait api.POST(\"\u002Fcustomers\", { body: { name: \"Ana\", phone: \"+5491155551111\", tags: [\"vip\"] } });\n\n\u002F\u002F Executar uma ação da etapa, por exemplo atribuir uma entrega a um entregador (scope bookings:write).\n\u002F\u002F \"atribuir\" é a chave dessa ação no modelo de entregas.\nawait api.POST(\"\u002Fbookings\u002F{id}\u002Factions\u002F{key}\", {\n  params: { path: { id: taskId, key: \"atribuir\" }, header: { \"Idempotency-Key\": crypto.randomUUID() } },\n  body: { data: {}, resource_id: courierResourceId },\n});\n",[1101,1923,1924,1929,1966,1999,2003,2008,2013,2028,2046,2051],{"__ignoreMap":1146},[1150,1925,1926],{"class":1152,"line":152},[1150,1927,1928],{"class":1182},"\u002F\u002F Buscar e criar clientes (scopes customers:read e customers:write)\n",[1150,1930,1931,1933,1935,1937,1939,1942,1944,1946,1948,1950,1952,1954,1957,1960,1963],{"class":1152,"line":158},[1150,1932,1241],{"class":1216},[1150,1934,1312],{"class":1220},[1150,1936,1316],{"class":1315},[1150,1938,1319],{"class":1220},[1150,1940,1941],{"class":1155},"found",[1150,1943,1325],{"class":1220},[1150,1945,1328],{"class":1216},[1150,1947,1331],{"class":1216},[1150,1949,1334],{"class":1220},[1150,1951,1337],{"class":1165},[1150,1953,1340],{"class":1220},[1150,1955,1956],{"class":1159},"\"\u002Fcustomers\"",[1150,1958,1959],{"class":1220},", { params: { query: { q: ",[1150,1961,1962],{"class":1159},"\"carlos\"",[1150,1964,1965],{"class":1220}," } } });\n",[1150,1967,1968,1971,1973,1975,1977,1979,1982,1985,1987,1990,1993,1996],{"class":1152,"line":345},[1150,1969,1970],{"class":1216},"await",[1150,1972,1334],{"class":1220},[1150,1974,1499],{"class":1165},[1150,1976,1340],{"class":1220},[1150,1978,1956],{"class":1159},[1150,1980,1981],{"class":1220},", { body: { name: ",[1150,1983,1984],{"class":1159},"\"Ana\"",[1150,1986,1619],{"class":1220},[1150,1988,1989],{"class":1159},"\"+5491155551111\"",[1150,1991,1992],{"class":1220},", tags: [",[1150,1994,1995],{"class":1159},"\"vip\"",[1150,1997,1998],{"class":1220},"] } });\n",[1150,2000,2001],{"class":1152,"line":1256},[1150,2002,1236],{"emptyLinePlaceholder":1235},[1150,2004,2005],{"class":1152,"line":1268},[1150,2006,2007],{"class":1182},"\u002F\u002F Executar uma ação da etapa, por exemplo atribuir uma entrega a um entregador (scope bookings:write).\n",[1150,2009,2010],{"class":1152,"line":1286},[1150,2011,2012],{"class":1182},"\u002F\u002F \"atribuir\" é a chave dessa ação no modelo de entregas.\n",[1150,2014,2015,2017,2019,2021,2023,2026],{"class":1152,"line":1292},[1150,2016,1970],{"class":1216},[1150,2018,1334],{"class":1220},[1150,2020,1499],{"class":1165},[1150,2022,1340],{"class":1220},[1150,2024,2025],{"class":1159},"\"\u002Fbookings\u002F{id}\u002Factions\u002F{key}\"",[1150,2027,1416],{"class":1220},[1150,2029,2030,2033,2036,2038,2040,2042,2044],{"class":1152,"line":1297},[1150,2031,2032],{"class":1220},"  params: { path: { id: taskId, key: ",[1150,2034,2035],{"class":1159},"\"atribuir\"",[1150,2037,1599],{"class":1220},[1150,2039,1515],{"class":1159},[1150,2041,1518],{"class":1220},[1150,2043,1521],{"class":1165},[1150,2045,1524],{"class":1220},[1150,2047,2048],{"class":1152,"line":1306},[1150,2049,2050],{"class":1220},"  body: { data: {}, resource_id: courierResourceId },\n",[1150,2052,2053],{"class":1152,"line":1349},[1150,2054,1289],{"class":1220},[1092,2056,2057,2058,2061,2062,2065],{},"As chaves de ação (",[1101,2059,2060],{},"key",") são definidas pela configuração de etapas do seu negócio: consulte-as com ",[1101,2063,2064],{},"GET \u002Fstage-config",".",[1122,2067,979],{"id":2068},"python",[1092,2070,1127,2071,2074,2075,2078],{},[1101,2072,2073],{},"packages\u002Fsdk-py",") usa ",[1101,2076,2077],{},"httpx"," e modelos Pydantic v2 gerados.",[1137,2080,960],{"id":2081},"instalar-a-partir-do-repositório-1",[1141,2083,2085],{"className":1143,"code":2084,"language":1145,"meta":1146,"style":1146},"pip install \u002Fcaminho\u002Fpara\u002Fwagendapp\u002Fpackages\u002Fsdk-py\n# ou, com uv:\nuv pip install \u002Fcaminho\u002Fpara\u002Fwagendapp\u002Fpackages\u002Fsdk-py\n",[1101,2086,2087,2097,2102],{"__ignoreMap":1146},[1150,2088,2089,2092,2094],{"class":1152,"line":152},[1150,2090,2091],{"class":1165},"pip",[1150,2093,1198],{"class":1159},[1150,2095,2096],{"class":1159}," \u002Fcaminho\u002Fpara\u002Fwagendapp\u002Fpackages\u002Fsdk-py\n",[1150,2098,2099],{"class":1152,"line":158},[1150,2100,2101],{"class":1182},"# ou, com uv:\n",[1150,2103,2104,2107,2110,2112],{"class":1152,"line":345},[1150,2105,2106],{"class":1165},"uv",[1150,2108,2109],{"class":1159}," pip",[1150,2111,1198],{"class":1159},[1150,2113,2096],{"class":1159},[1137,2115,965],{"id":2116},"agendar-um-horário-1",[1141,2118,2121],{"className":2119,"code":2120,"language":2068,"meta":1146,"style":1146},"language-python shiki shiki-themes github-light github-dark","from datetime import UTC, datetime\nfrom wagend import Wagend, WagendError\n\nwith Wagend(\"https:\u002F\u002Fapi.wagend.app\u002Fv1\", \"wg_live_xxx\") as api:\n    try:\n        service = api.list_services()[0]\n        slots = api.list_slots(\n            str(service.id), datetime(2026, 10, 15, 8, tzinfo=UTC), datetime(2026, 10, 15, 13, tzinfo=UTC)\n        )\n\n        hold = api.request(\n            \"POST\", \"\u002Fholds\",\n            json={\"service_id\": str(service.id), \"start\": slots[0].start.isoformat(), \"party_size\": 1},\n            idempotency_key=\"reserva-carlos-2026-10-15\",\n        )\n        booking = api.request(\n            \"POST\", f\"\u002Fholds\u002F{hold['id']}\u002Fconfirm\",\n            json={\"customer\": {\"name\": \"Carlos\", \"phone\": \"+5491155550000\"}},\n        )\n        print(booking[\"status\"])\n    except WagendError as err:\n        print(err.status, err.code, err.retry_after)\n",[1101,2122,2123,2138,2150,2154,2178,2186,2201,2211,2276,2281,2285,2295,2306,2348,2360,2364,2373,2404,2437,2441,2455,2468],{"__ignoreMap":1146},[1150,2124,2125,2127,2130,2132,2135],{"class":1152,"line":152},[1150,2126,1224],{"class":1216},[1150,2128,2129],{"class":1220}," datetime ",[1150,2131,1217],{"class":1216},[1150,2133,2134],{"class":1155}," UTC",[1150,2136,2137],{"class":1220},", datetime\n",[1150,2139,2140,2142,2145,2147],{"class":1152,"line":158},[1150,2141,1224],{"class":1216},[1150,2143,2144],{"class":1220}," wagend ",[1150,2146,1217],{"class":1216},[1150,2148,2149],{"class":1220}," Wagend, WagendError\n",[1150,2151,2152],{"class":1152,"line":345},[1150,2153,1236],{"emptyLinePlaceholder":1235},[1150,2155,2156,2159,2162,2164,2166,2169,2172,2175],{"class":1152,"line":1256},[1150,2157,2158],{"class":1216},"with",[1150,2160,2161],{"class":1220}," Wagend(",[1150,2163,1262],{"class":1159},[1150,2165,1280],{"class":1220},[1150,2167,2168],{"class":1159},"\"wg_live_xxx\"",[1150,2170,2171],{"class":1220},") ",[1150,2173,2174],{"class":1216},"as",[1150,2176,2177],{"class":1220}," api:\n",[1150,2179,2180,2183],{"class":1152,"line":1268},[1150,2181,2182],{"class":1216},"    try",[1150,2184,2185],{"class":1220},":\n",[1150,2187,2188,2191,2193,2196,2198],{"class":1152,"line":1286},[1150,2189,2190],{"class":1220},"        service ",[1150,2192,1328],{"class":1216},[1150,2194,2195],{"class":1220}," api.list_services()[",[1150,2197,1372],{"class":1155},[1150,2199,2200],{"class":1220},"]\n",[1150,2202,2203,2206,2208],{"class":1152,"line":1292},[1150,2204,2205],{"class":1220},"        slots ",[1150,2207,1328],{"class":1216},[1150,2209,2210],{"class":1220}," api.list_slots(\n",[1150,2212,2213,2216,2219,2222,2224,2227,2229,2232,2234,2237,2239,2242,2244,2247,2250,2252,2254,2256,2258,2260,2262,2265,2267,2269,2271,2273],{"class":1152,"line":1297},[1150,2214,2215],{"class":1155},"            str",[1150,2217,2218],{"class":1220},"(service.id), datetime(",[1150,2220,2221],{"class":1155},"2026",[1150,2223,1280],{"class":1220},[1150,2225,2226],{"class":1155},"10",[1150,2228,1280],{"class":1220},[1150,2230,2231],{"class":1155},"15",[1150,2233,1280],{"class":1220},[1150,2235,2236],{"class":1155},"8",[1150,2238,1280],{"class":1220},[1150,2240,2241],{"class":1315},"tzinfo",[1150,2243,1328],{"class":1216},[1150,2245,2246],{"class":1155},"UTC",[1150,2248,2249],{"class":1220},"), datetime(",[1150,2251,2221],{"class":1155},[1150,2253,1280],{"class":1220},[1150,2255,2226],{"class":1155},[1150,2257,1280],{"class":1220},[1150,2259,2231],{"class":1155},[1150,2261,1280],{"class":1220},[1150,2263,2264],{"class":1155},"13",[1150,2266,1280],{"class":1220},[1150,2268,2241],{"class":1315},[1150,2270,1328],{"class":1216},[1150,2272,2246],{"class":1155},[1150,2274,2275],{"class":1220},")\n",[1150,2277,2278],{"class":1152,"line":1306},[1150,2279,2280],{"class":1220},"        )\n",[1150,2282,2283],{"class":1152,"line":1349},[1150,2284,1236],{"emptyLinePlaceholder":1235},[1150,2286,2287,2290,2292],{"class":1152,"line":1382},[1150,2288,2289],{"class":1220},"        hold ",[1150,2291,1328],{"class":1216},[1150,2293,2294],{"class":1220}," api.request(\n",[1150,2296,2297,2300,2302,2304],{"class":1152,"line":1387},[1150,2298,2299],{"class":1159},"            \"POST\"",[1150,2301,1280],{"class":1220},[1150,2303,1504],{"class":1159},[1150,2305,1265],{"class":1220},[1150,2307,2308,2311,2313,2316,2319,2321,2324,2327,2330,2333,2335,2338,2341,2343,2345],{"class":1152,"line":1419},[1150,2309,2310],{"class":1315},"            json",[1150,2312,1328],{"class":1216},[1150,2314,2315],{"class":1220},"{",[1150,2317,2318],{"class":1159},"\"service_id\"",[1150,2320,1319],{"class":1220},[1150,2322,2323],{"class":1155},"str",[1150,2325,2326],{"class":1220},"(service.id), ",[1150,2328,2329],{"class":1159},"\"start\"",[1150,2331,2332],{"class":1220},": slots[",[1150,2334,1372],{"class":1155},[1150,2336,2337],{"class":1220},"].start.isoformat(), ",[1150,2339,2340],{"class":1159},"\"party_size\"",[1150,2342,1319],{"class":1220},[1150,2344,1533],{"class":1155},[1150,2346,2347],{"class":1220},"},\n",[1150,2349,2350,2353,2355,2358],{"class":1152,"line":1437},[1150,2351,2352],{"class":1315},"            idempotency_key",[1150,2354,1328],{"class":1216},[1150,2356,2357],{"class":1159},"\"reserva-carlos-2026-10-15\"",[1150,2359,1265],{"class":1220},[1150,2361,2362],{"class":1152,"line":1443},[1150,2363,2280],{"class":1220},[1150,2365,2366,2369,2371],{"class":1152,"line":1466},[1150,2367,2368],{"class":1220},"        booking ",[1150,2370,1328],{"class":1216},[1150,2372,2294],{"class":1220},[1150,2374,2375,2377,2379,2382,2385,2387,2390,2393,2396,2399,2402],{"class":1152,"line":1471},[1150,2376,2299],{"class":1159},[1150,2378,1280],{"class":1220},[1150,2380,2381],{"class":1216},"f",[1150,2383,2384],{"class":1159},"\"\u002Fholds\u002F",[1150,2386,2315],{"class":1155},[1150,2388,2389],{"class":1220},"hold[",[1150,2391,2392],{"class":1159},"'id'",[1150,2394,2395],{"class":1220},"]",[1150,2397,2398],{"class":1155},"}",[1150,2400,2401],{"class":1159},"\u002Fconfirm\"",[1150,2403,1265],{"class":1220},[1150,2405,2406,2408,2410,2412,2415,2418,2421,2423,2425,2427,2430,2432,2434],{"class":1152,"line":1477},[1150,2407,2310],{"class":1315},[1150,2409,1328],{"class":1216},[1150,2411,2315],{"class":1220},[1150,2413,2414],{"class":1159},"\"customer\"",[1150,2416,2417],{"class":1220},": {",[1150,2419,2420],{"class":1159},"\"name\"",[1150,2422,1319],{"class":1220},[1150,2424,1616],{"class":1159},[1150,2426,1280],{"class":1220},[1150,2428,2429],{"class":1159},"\"phone\"",[1150,2431,1319],{"class":1220},[1150,2433,1622],{"class":1159},[1150,2435,2436],{"class":1220},"}},\n",[1150,2438,2439],{"class":1152,"line":1509},[1150,2440,2280],{"class":1220},[1150,2442,2443,2446,2449,2452],{"class":1152,"line":1527},[1150,2444,2445],{"class":1155},"        print",[1150,2447,2448],{"class":1220},"(booking[",[1150,2450,2451],{"class":1159},"\"status\"",[1150,2453,2454],{"class":1220},"])\n",[1150,2456,2457,2460,2463,2465],{"class":1152,"line":1539},[1150,2458,2459],{"class":1216},"    except",[1150,2461,2462],{"class":1220}," WagendError ",[1150,2464,2174],{"class":1216},[1150,2466,2467],{"class":1220}," err:\n",[1150,2469,2470,2472],{"class":1152,"line":1544},[1150,2471,2445],{"class":1155},[1150,2473,2474],{"class":1220},"(err.status, err.code, err.retry_after)\n",[1731,2476,2477,2494,2506,2522],{},[1734,2478,2479,2482,2483,2486,2487,2490,2491,2065],{},[1101,2480,2481],{},"list_services()"," e ",[1101,2484,2485],{},"list_slots()"," devolvem modelos tipados. Para as demais rotas use ",[1101,2488,2489],{},"api.request(método, rota, params=…, json=…)","; você pode validar a resposta com ",[1101,2492,2493],{},"wagend.models",[1734,2495,2496,2498,2499,2501,2502,2505],{},[1096,2497,1748],{}," as escritas levam ",[1101,2500,1752],{}," (uma é gerada se você não passar ",[1101,2503,2504],{},"idempotency_key","). Repita com a mesma chave.",[1734,2507,2508,1099,2510,1771,2512,1280,2514,1280,2516,2482,2518,2521],{},[1096,2509,1766],{},[1101,2511,1770],{},[1101,2513,1774],{},[1101,2515,1777],{},[1101,2517,1780],{},[1101,2519,2520],{},".retry_after"," (em 429).",[1734,2523,2524,1099,2527,2530],{},[1096,2525,2526],{},"Paginação:",[1101,2528,2529],{},"api.paginate(\"\u002Fbookings\", params={\"limit\": 50})"," percorre todas as páginas.",[1141,2532,2534],{"className":2119,"code":2533,"language":2068,"meta":1146,"style":1146},"for booking in api.paginate(\"\u002Fbookings\", params={\"limit\": 50}):\n    print(booking[\"id\"])\n",[1101,2535,2536,2571],{"__ignoreMap":1146},[1150,2537,2538,2541,2544,2547,2550,2552,2554,2557,2559,2561,2564,2566,2568],{"class":1152,"line":152},[1150,2539,2540],{"class":1216},"for",[1150,2542,2543],{"class":1220}," booking ",[1150,2545,2546],{"class":1216},"in",[1150,2548,2549],{"class":1220}," api.paginate(",[1150,2551,1850],{"class":1159},[1150,2553,1280],{"class":1220},[1150,2555,2556],{"class":1315},"params",[1150,2558,1328],{"class":1216},[1150,2560,2315],{"class":1220},[1150,2562,2563],{"class":1159},"\"limit\"",[1150,2565,1319],{"class":1220},[1150,2567,1856],{"class":1155},[1150,2569,2570],{"class":1220},"}):\n",[1150,2572,2573,2576,2578,2581],{"class":1152,"line":158},[1150,2574,2575],{"class":1155},"    print",[1150,2577,2448],{"class":1220},[1150,2579,2580],{"class":1159},"\"id\"",[1150,2582,2454],{"class":1220},[1122,2584,857],{"id":2585},"limites-de-uso",[1092,2587,2588,2589,2592,2593,2596,2597,2600,2601,2065],{},"O limite é por chave e por projeto. Diante de um ",[1101,2590,2591],{},"429",", espere ",[1101,2594,2595],{},"retry_after"," \u002F ",[1101,2598,2599],{},"retryAfter"," segundos antes de tentar de novo. Veja ",[1117,2602,125],{"href":126},[1122,2604,996],{"id":2605},"regenerar-os-sdks",[1092,2607,2608,2609,2612,2613,2482,2616,2619],{},"Se o contrato mudar, ",[1101,2610,2611],{},"make sdk"," regenera os dois a partir de ",[1101,2614,2615],{},"openapi.yaml",[1101,2617,2618],{},"make sdk-check"," falha se ficaram desatualizados.",[2621,2622,2623],"style",{},"html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sJ8bj, html code.shiki .sJ8bj{--shiki-default:#6A737D;--shiki-dark:#6A737D}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .szBVR, html code.shiki .szBVR{--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .s4XuR, html code.shiki .s4XuR{--shiki-default:#E36209;--shiki-dark:#FFAB70}",{"title":1146,"searchDepth":158,"depth":345,"links":2625},[2626,2632,2636,2637],{"id":1124,"depth":158,"text":955,"children":2627},[2628,2629,2630,2631],{"id":1139,"depth":345,"text":960},{"id":1204,"depth":345,"text":965},{"id":1788,"depth":345,"text":847},{"id":1918,"depth":345,"text":974},{"id":2068,"depth":158,"text":979,"children":2633},[2634,2635],{"id":2081,"depth":345,"text":960},{"id":2116,"depth":345,"text":965},{"id":2585,"depth":158,"text":857},{"id":2605,"depth":158,"text":996},"Clientes tipados gerados a partir do contrato OpenAPI: como usá-los hoje a partir do repositório, com exemplos de agendamento, erros, paginação e idempotência.","md",{},"---\ntitle: SDKs de TypeScript e Python\ndescription: \"Clientes tipados gerados a partir do contrato OpenAPI: como usá-los hoje a partir do repositório, com exemplos de agendamento, erros, paginação e idempotência.\"\nupdated: \"2026-10-03\"\n---\n\nA Wagend tem dois SDKs que são **gerados a partir do contrato** `packages\u002Fopenapi\u002Fopenapi.yaml`, então seus tipos sempre acompanham a API.\n\n::callout{type=\"warning\"}\nOs SDKs **ainda não estão publicados** no npm nem no PyPI (Em breve). Hoje são usados a partir do repositório, como explicado abaixo. Se preferir não depender deles, a [API REST](\u002Fdocs\u002Fquickstart) funciona com qualquer cliente HTTP.\n::\n\n## TypeScript\n\nO cliente (`packages\u002Fsdk-ts`) é um invólucro leve sobre `fetch` com tipos de todas as rotas.\n\n### Instalar a partir do repositório\n\n```bash\ncd packages\u002Fsdk-ts\nnpm ci\nnpm run build          # genera dist\u002F\n```\n\nNo seu projeto, instale-o a partir dessa pasta:\n\n```bash\nnpm install \u002Fcaminho\u002Fpara\u002Fwagendapp\u002Fpackages\u002Fsdk-ts\n```\n\n### Agendar um horário\n\n```ts\nimport { createWagendClient, WagendError } from \"@wagend\u002Fsdk\";\n\nconst api = createWagendClient({\n  baseUrl: \"https:\u002F\u002Fapi.wagend.app\u002Fv1\",\n  apiKey: process.env.WAGEND_API_KEY!, \u002F\u002F wg_live_xxx\n});\n\ntry {\n  const { data: services } = await api.GET(\"\u002Fservices\");\n  const serviceId = services!.data![0].id!;\n\n  const { data: slots } = await api.GET(\"\u002Fslots\", {\n    params: { query: { service_id: serviceId, from: \"2026-10-15T08:00:00-03:00\", to: \"2026-10-15T13:00:00-03:00\" } },\n  });\n  const slot = slots!.data[0];\n\n  \u002F\u002F Pré-reserva de 10 minutos\n  const { data: hold } = await api.POST(\"\u002Fholds\", {\n    params: { header: { \"Idempotency-Key\": crypto.randomUUID() } },\n    body: { service_id: serviceId, start: slot.start, party_size: 1, resource_ids: slot.resource_ids },\n  });\n\n  \u002F\u002F Confirmação com os dados do cliente\n  const { data: booking } = await api.POST(\"\u002Fholds\u002F{id}\u002Fconfirm\", {\n    params: { path: { id: hold!.id! }, header: { \"Idempotency-Key\": crypto.randomUUID() } },\n    body: { customer: { name: \"Carlos\", phone: \"+5491155550000\", locale: \"es\" } },\n  });\n  console.log(booking!.status); \u002F\u002F \"confirmed\"\n} catch (err) {\n  if (err instanceof WagendError) {\n    console.error(err.status, err.code, err.retryAfter);\n  } else {\n    throw err;\n  }\n}\n```\n\n- **Autenticação:** o cliente adiciona `Authorization: Bearer` sozinho.\n- **Idempotência:** em toda escrita adiciona uma `Idempotency-Key` se você não passar uma. Para repetir uma operação, passe **você** a mesma chave nas duas tentativas (vale 24 horas). O tipo do TypeScript a declara em `params.header` nas rotas que a exigem.\n- **Erros:** toda resposta que não seja 2xx lança `WagendError` com `.status`, `.code`, `.problem` (RFC 9457) e `.retryAfter` (segundos, em 429).\n\n### Paginação\n\n```ts\nlet cursor: string | undefined;\ndo {\n  const { data: page } = await api.GET(\"\u002Fbookings\", { params: { query: { limit: 50, cursor } } });\n  for (const booking of page?.data ?? []) console.log(booking.id);\n  cursor = page?.next_cursor ?? undefined;\n} while (cursor);\n```\n\n### Clientes e ações\n\n```ts\n\u002F\u002F Buscar e criar clientes (scopes customers:read e customers:write)\nconst { data: found } = await api.GET(\"\u002Fcustomers\", { params: { query: { q: \"carlos\" } } });\nawait api.POST(\"\u002Fcustomers\", { body: { name: \"Ana\", phone: \"+5491155551111\", tags: [\"vip\"] } });\n\n\u002F\u002F Executar uma ação da etapa, por exemplo atribuir uma entrega a um entregador (scope bookings:write).\n\u002F\u002F \"atribuir\" é a chave dessa ação no modelo de entregas.\nawait api.POST(\"\u002Fbookings\u002F{id}\u002Factions\u002F{key}\", {\n  params: { path: { id: taskId, key: \"atribuir\" }, header: { \"Idempotency-Key\": crypto.randomUUID() } },\n  body: { data: {}, resource_id: courierResourceId },\n});\n```\n\nAs chaves de ação (`key`) são definidas pela configuração de etapas do seu negócio: consulte-as com `GET \u002Fstage-config`.\n\n## Python\n\nO cliente (`packages\u002Fsdk-py`) usa `httpx` e modelos Pydantic v2 gerados.\n\n### Instalar a partir do repositório\n\n```bash\npip install \u002Fcaminho\u002Fpara\u002Fwagendapp\u002Fpackages\u002Fsdk-py\n# ou, com uv:\nuv pip install \u002Fcaminho\u002Fpara\u002Fwagendapp\u002Fpackages\u002Fsdk-py\n```\n\n### Agendar um horário\n\n```python\nfrom datetime import UTC, datetime\nfrom wagend import Wagend, WagendError\n\nwith Wagend(\"https:\u002F\u002Fapi.wagend.app\u002Fv1\", \"wg_live_xxx\") as api:\n    try:\n        service = api.list_services()[0]\n        slots = api.list_slots(\n            str(service.id), datetime(2026, 10, 15, 8, tzinfo=UTC), datetime(2026, 10, 15, 13, tzinfo=UTC)\n        )\n\n        hold = api.request(\n            \"POST\", \"\u002Fholds\",\n            json={\"service_id\": str(service.id), \"start\": slots[0].start.isoformat(), \"party_size\": 1},\n            idempotency_key=\"reserva-carlos-2026-10-15\",\n        )\n        booking = api.request(\n            \"POST\", f\"\u002Fholds\u002F{hold['id']}\u002Fconfirm\",\n            json={\"customer\": {\"name\": \"Carlos\", \"phone\": \"+5491155550000\"}},\n        )\n        print(booking[\"status\"])\n    except WagendError as err:\n        print(err.status, err.code, err.retry_after)\n```\n\n- `list_services()` e `list_slots()` devolvem modelos tipados. Para as demais rotas use `api.request(método, rota, params=…, json=…)`; você pode validar a resposta com `wagend.models`.\n- **Idempotência:** as escritas levam `Idempotency-Key` (uma é gerada se você não passar `idempotency_key`). Repita com a mesma chave.\n- **Erros:** `WagendError` com `.status`, `.code`, `.problem` e `.retry_after` (em 429).\n- **Paginação:** `api.paginate(\"\u002Fbookings\", params={\"limit\": 50})` percorre todas as páginas.\n\n```python\nfor booking in api.paginate(\"\u002Fbookings\", params={\"limit\": 50}):\n    print(booking[\"id\"])\n```\n\n## Limites de uso\n\nO limite é por chave e por projeto. Diante de um `429`, espere `retry_after` \u002F `retryAfter` segundos antes de tentar de novo. Veja [Convenções](\u002Fdocs\u002Fapi\u002Fconventions).\n\n## Regenerar os SDKs\n\nSe o contrato mudar, `make sdk` regenera os dois a partir de `openapi.yaml` e `make sdk-check` falha se ficaram desatualizados.\n",{"title":137,"description":2638},"2026-10-03","-1sZFR-u-MBfdfkP6ydU26xxQg_fJlYiVjocxHlNEAI",[2646,2647],{"title":133,"path":134,"stem":135,"description":924,"children":-1},{"title":141,"path":142,"stem":143,"description":2648,"children":-1},"Conecte Claude, ChatGPT ou seu próprio agente ao servidor MCP da Wagend para buscar horários, agendar e operar o negócio com sua chave de API.",1791052078152]