

Documentação da API do Agente
Como um agente de IA (ex.: no n8n) usa a API do Agenda Vet como ferramentas para consultar a agenda, marcar consultas e responder o cliente no WhatsApp.
Visão geral
- Base URL
https://agendamento.btwdata.tech - Autenticação
Authorization: Bearer <API_KEY>em toda chamada. - FormatoJSON no request e na resposta. Datas em ISO 8601 com fuso (ex.:
2026-07-20T14:30:00-03:00). - IsolamentoA clínica é resolvida a partir da API key no servidor. Um agente nunca enxerga outra clínica.
1. Gerar a API key
No app, como Gestor: Configurações → Agente de IA → Nova chave.
- A chave aparece uma única vez (guarde na hora); o sistema guarda só o hash.
- Marque "Pode marcar consultas" para permitir escrita; sem isso, a chave é somente leitura (rotas de escrita respondem 403).
- Para revogar, apague a chave na mesma tela. Formato:
vet_live_XXalgo.
2. Autenticação no n8n
Guarde a chave numa credencial, nunca em texto no nó:
- n8n → Credentials → New → Header Auth.
- Name: Agenda Vet
- Header Name:
Authorization - Header Value:
Bearer vet_live_XXalgo - Use essa credencial em todo nó HTTP Request que chamar a API.
3. Usar como ferramenta do AI Agent
No nó AI Agent, cada rota vira uma tool. Use o nó HTTP Request Tool (um por rota) e deixe o modelo preencher os parâmetros com $fromAI(...):
{{ $fromAI('doctorId', 'ID do doutor escolhido', 'string') }}Em cada tool: Authentication = Header Auth (credencial Agenda Vet); URL = base + caminho da rota; e cole a "Descrição para o modelo" de cada rota abaixo no campo de descrição da tool.
4. Rotas (as ferramentas)
/api/agent/doctorsListar doutores e escala
Quem existe, do que entende e quando atende. Leia isto antes de sugerir horário. Retorna também o fuso e a duração da consulta da clínica.
{
"clinica": { "fuso": "America/Sao_Paulo", "duracaoConsultaMin": 30 },
"doutores": [
{
"id": "ckdoc123",
"nome": "Dra. Ana Paula",
"especialidade": "Clínica Geral",
"especialidadeId": "ckspec1",
"crmv": "SP-12345",
"cor": "#C9A961",
"escala": [
{ "weekday": 1, "dia": "segunda", "inicio": "09:00", "fim": "12:00" }
]
}
]
}Lista os doutores da clínica, especialidades e a escala semanal. Use no início para saber quem pode atender.
/api/agent/availabilityHorários livres
Slots já descontados de escala, bloqueios (férias/feriado), consultas existentes e passado.
from(ISO 8601, opcional)Início da busca. Padrão: agora.to(ISO 8601, opcional)Fim da busca. Padrão: +7 dias. Máx. 60 dias.doctorId(string, opcional)Restringe a um doutor.specialtyId(string, opcional)Restringe a uma especialidade.
{
"de": "2026-07-20T00:00:00.000Z",
"ate": "2026-07-27T00:00:00.000Z",
"fuso": "America/Sao_Paulo",
"duracaoConsultaMin": 30,
"doutores": [
{
"doctorId": "ckdoc123",
"nome": "Dra. Ana Paula",
"especialidade": "Clínica Geral",
"horariosLivres": [
{ "inicio": "2026-07-20T12:00:00.000Z", "fim": "2026-07-20T12:30:00.000Z" }
]
}
]
}Retorna os horários livres para marcar. Filtre por doutor ou especialidade. Use antes de agendar.
/api/agent/patientsAchar paciente
Localiza pet/tutor por nome ou telefone, para pegar o petId antes de marcar.
q(string)Nome do pet, nome do tutor ou telefone.
{
"pacientes": [
{
"petId": "ckpet1",
"nome": "Rex",
"especie": "Cão",
"raca": "SRD",
"tutor": { "id": "cktut1", "nome": "Ana Paula", "telefone": "5511999998888" }
}
]
}Busca pacientes (pet + tutor) por nome ou telefone. Use para achar o petId antes de marcar, se o cliente já existe.
/api/agent/appointmentsConsultas agendadas
Lista as consultas do período. Use para conferir a agenda ou achar o id de uma consulta a remarcar/cancelar.
from(ISO 8601, opcional)Padrão: agora.to(ISO 8601, opcional)Padrão: +30 dias. Máx. 90 dias.doctorId(string, opcional)Restringe a um doutor.
{
"agendamentos": [
{
"id": "ckappt1",
"inicio": "2026-07-20T12:00:00.000Z",
"fim": "2026-07-20T12:30:00.000Z",
"status": "AGENDADO",
"motivo": "Vacina",
"criadoPor": "AGENTE",
"doutor": { "id": "ckdoc123", "nome": "Dra. Ana Paula" },
"pet": { "id": "ckpet1", "nome": "Rex", "especie": "Cão" },
"tutor": { "id": "cktut1", "nome": "Ana Paula", "telefone": "5511999998888" }
}
]
}Lista as consultas já marcadas no período. Use para conferir agenda ou achar o id de uma consulta a remarcar/cancelar.
/api/agent/appointmentsrequer escritaMarcar consulta
Passe petId se já conhece o paciente; senão passe tutor + pet, que o sistema acha pelo telefone/nome ou cria na hora. Os campos extras (CPF, endereço, sexo, nascimento, peso, microchip, cor) são opcionais e enriquecem a ficha para o prontuário/termo.
{
"doctorId": "ckdoc123",
"inicio": "2026-07-20T12:00:00-03:00",
"motivo": "Vacina (opcional)",
"petId": "ckpet1"
}
// ou, sem petId (cria o paciente na hora):
{
"doctorId": "ckdoc123",
"inicio": "2026-07-20T12:00:00-03:00",
"tutor": {
"nome": "Ana Paula", "telefone": "5511999998888",
"cpf": "000.000.000-00", "endereco": "Rua X, 123 - São Paulo/SP"
},
"pet": {
"nome": "Rex", "especie": "Cão", "raca": "SRD",
"sexo": "M", "nascimento": "2021-05-10", "pesoKg": 12.5,
"microchip": "981000000000000", "corPelagem": "Caramelo"
}
}{
"ok": true,
"agendamento": {
"id": "ckappt2", "inicio": "...", "fim": "...",
"doctorId": "ckdoc123", "petId": "ckpet1"
}
}Marca a consulta. Passe petId se conhece o paciente; senão passe tutor + pet (campos extras opcionais: cpf, endereco, sexo, nascimento AAAA-MM-DD, pesoKg, microchip, corPelagem). inicio deve ser um horário livre retornado por availability.
/api/agent/appointments/{id}requer escritaRemarcar / mudar status
Mande só o que muda. Status válidos: AGENDADO, CONFIRMADO, ATENDIDO, FALTOU, CANCELADO.
{
"inicio": "2026-07-21T15:00:00-03:00",
"doctorId": "ckdoc999",
"status": "CONFIRMADO",
"motivo": "texto (opcional)"
}{
"ok": true,
"agendamento": { "id": "ckappt2", "inicio": "...", "fim": "...", "status": "CONFIRMADO", "doctorId": "ckdoc999" }
}Edita uma consulta existente: remarcar horário, trocar doutor ou mudar status. Use o id de appointments.
/api/agent/appointments/{id}requer escritaCancelar consulta
Cancelamento soft (status CANCELADO): preserva o histórico e libera o horário para reagendar. Sem body.
{ "ok": true, "cancelado": "ckappt2" }Cancela a consulta e libera o horário.
/api/agent/inbox/statusEstado da IA na conversa
Antes de responder, confira se a IA ainda está ligada para aquele contato (a equipe pode ter assumido).
telefone(string)Com DDI, ex.: 5511999998888.
{
"conversaId": "ckconv1",
"telefone": "5511999998888",
"iaAtiva": true,
"motivo": null,
"alteradaEm": null,
"alteradaVia": null
}Consulta se a IA está ativa para o telefone. Se iaAtiva for false, NÃO responda: um humano assumiu.
/api/agent/inbox/messagesrequer escritaResponder no WhatsApp
Único caminho para a IA responder. Se a IA estiver desligada na conversa, o envio é recusado (409 IA_DESLIGADA).
{ "telefone": "5511999998888", "text": "Olá! Podemos marcar o banho do Rex." }{
"ok": true,
"conversaId": "ckconv1",
"mensagem": { "id": "ckmsg1", "externalId": "wa123", "texto": "Olá!", "enviadaEm": "..." }
}Envia uma mensagem de texto ao cliente pelo WhatsApp da clínica. Só funciona se a IA estiver ligada na conversa.
/api/agent/inbox/handoffrequer escritaTransferir para humano
Desliga a IA e entrega a conversa para a equipe. O agente não consegue se reativar depois.
{ "telefone": "5511999998888", "motivo": "cliente pediu humano (opcional)" }{ "ok": true, "conversaId": "ckconv1", "iaAtiva": false, "desligadaEm": "..." }Transfere a conversa para um atendente humano quando não souber resolver ou o cliente pedir. Depois disso, pare de responder.
5. Gatilho: receber a mensagem (webhook)
Para o agente reagir a mensagens que chegam no Inbox, configure em Configurações → Agente de IA → Webhook do agente a URL de um nó Webhook do n8n. A cada mensagem nova do cliente (com a IA ligada na conversa), o app faz um POST com este corpo:
{
"clinicId": "ckclinic1",
"conversation": { "id": "ckconv1" },
"contact": { "number": "5511999998888", "name": "Ana Paula" },
"message": { "text": "quero marcar banho pro Rex", "mediaType": null, "timestamp": "..." },
"replyApi": "/api/agent/inbox/messages"
}Cada requisição leva o header X-Signature (HMAC) para o n8n validar a origem, se quiser. O segredo de assinatura é gerenciado pelo administrador da plataforma. Fluxo típico: Webhook recebe → AI Agent decide (checa status → busca horários → marca) → HTTP Request Tool POST /api/agent/inbox/messages responde.
6. Códigos de erro
Erros têm o formato { "erro": "...", "codigo": "OPCIONAL" }.
| HTTP | Código | Significado |
|---|---|---|
| 400 | - | Dados inválidos (veja detalhes) ou data fora do formato ISO 8601 |
| 401 | - | API key ausente, inválida ou inativa |
| 403 | - | A key é somente leitura (marque "Pode marcar consultas") |
| 404 | - | Recurso não encontrado nesta clínica (doutor, pet, consulta ou conversa) |
| 409 | SLOT_INDISPONIVEL | Horário fora da escala, bloqueado ou no passado |
| 409 | SLOT_OCUPADO | O horário acabou de ser ocupado por outra pessoa |
| 409 | IA_DESLIGADA | A IA foi desligada nessa conversa (um humano assumiu) |
| 409 | ENVIO_EM_ANDAMENTO | Outro envio da mesma conversa está em curso; tente de novo |
| 429 | - | Limite de requisições excedido |
| 503 | - | WhatsApp não configurado ou integração pausada |
7. Limites e boas práticas
Rate limit por API key, por minuto: inbox/status 600, inbox/messages 120, inbox/handoff 120. Ao receber 429, aguarde e tente de novo.
- Comece por
GET /api/agent/doctorspara pegar o fuso e a duração da consulta. - Sempre confira horários livres (
availability) antes de marcar; nunca invente um horário. - Antes de responder, cheque
inbox/status; seiaAtiva=false, silencie. - Quando não souber resolver ou o cliente pedir, use
handoffe pare de responder. - Guarde a API key numa credencial do n8n; nunca a exponha em nós ou logs.