Venda Perfeita · Desenvolvedores

API de agendamento pelo site

Ligue o agendamento do seu site na agenda do Venda Perfeita. O cliente marca pelo site, com o visual dele, e o horário cai direto na agenda. A confirmação, o lembrete e o pedido de avaliação saem pelo WhatsApp da empresa.

Funciona com qualquer site: feito em IA (Lovable, Bolt, v0, Replit, Cursor) ou por um programador. Se o seu site foi feito em IA, o jeito mais fácil é copiar as instruções prontas em Ajustes › Agendamento online › Agendar pelo seu site e colar no chat dela.

Começar em 3 passos

  1. No Venda Perfeita, em Ajustes › Agendamento online › Agendar pelo seu site, gere a chave do site. Ela começa com vpag_ e só aparece uma vez.
  2. Guarde a chave como segredo do servidor (secret ou variável de ambiente) com o nome VP_AGENDA_KEY.
  3. Crie uma função de servidor (Edge Function no Lovable/Supabase, rota de API no Vercel/Next.js, ou no servidor que o site já usa, como uma hospedagem na Hostinger) que chama as 4 rotas abaixo. O navegador chama a sua função; a sua função chama o Venda Perfeita. Você não precisa hospedar a API: ela já está no ar.

Autenticação e segurança

  • Toda chamada leva o header Authorization: Bearer vpag_....
  • Sempre de servidor pra servidor. A API não libera chamada do navegador (sem CORS), e a chave nunca pode ir no código da página, em resposta ou em log.
  • A sua função deve aceitar só as 4 ações fixas e montar a URL sozinha. Nunca use caminho, endereço ou host vindo do navegador.
  • Em marcar e cancelar, mande o header x-visitante-ip com o IP de quem está no site (o primeiro de x-forwarded-for). É o que limita robôs por visitante.
  • Não guarde nome, telefone ou id de marcação de cliente em tabela do site. Pra o cliente cancelar depois, guarde o id só no navegador dele (localStorage).

Formato das respostas

Toda resposta é JSON neste envelope:

{ "success": true, "data": { ... } }
{ "success": false, "error": "Frase pronta pra mostrar ao cliente", "code": "slot_gone", "detalhe": "Motivo técnico (opcional)" }

error é sempre uma frase de cliente: mostre como veio. detalhe é pro dono ou pro programador: nunca mostre ao cliente.

Rotas

Base: https://vendaperfeita.com/api/site/agenda

GET/api/site/agenda· Catálogo

O nome da empresa, os serviços e, se a empresa deixa escolher, quem atende cada um. Busque de novo sempre que o cliente abrir o agendamento.

curl https://vendaperfeita.com/api/site/agenda \
  -H "Authorization: Bearer $VP_AGENDA_KEY"
{
  "success": true,
  "data": {
    "empresa": "Barbearia do JP",
    "fuso": "America/Sao_Paulo",
    "diasParaFrente": 30,
    "escolheProfissional": true,
    "servicos": [
      { "id": "corte", "nome": "Corte", "duracaoMin": 30, "preco": 45, "precoAPartirDe": false, "categoria": null, "profissionais": ["p_3f9c1a2b7d4e"] }
    ],
    "profissionais": [
      { "id": "p_3f9c1a2b7d4e", "nome": "Nathan", "diasQueAtende": [2, 3, 4, 5, 6] }
    ]
  }
}
  • preco: null = sem preço definido (mostre “a combinar”). precoAPartirDe: true = “a partir de”.
  • profissionais vazio no serviço: não peça profissional (a agenda escolhe quem estiver livre).
  • escolheProfissional: false: não mostre a escolha de profissional.
  • diasQueAtende: 0 = domingo, 6 = sábado.
GET/api/site/agenda/horarios· Horários livres do dia

Parâmetros: data (AAAA-MM-DD), servico (id) e profissional (id, opcional). Respeita funcionamento, folga, ausência, antecedência mínima e o Google Agenda de quem conectou.

curl "https://vendaperfeita.com/api/site/agenda/horarios?data=2026-10-23&servico=corte&profissional=p_3f9c1a2b7d4e" \
  -H "Authorization: Bearer $VP_AGENDA_KEY"
{ "success": true, "data": { "horarios": [ { "hora": "19:00", "inicio": "2026-10-23T22:00:00.000Z" } ] } }

Mostre hora (já no horário da empresa). inicio é só pra mandar de volta na marcação. Lista vazia = sem horário livre nesse dia.

POST/api/site/agenda/marcar· Marcar

JSON, com o header x-visitante-ip. O inicio tem que ser exatamente um dos que /horarios devolveu.

curl -X POST https://vendaperfeita.com/api/site/agenda/marcar \
  -H "Authorization: Bearer $VP_AGENDA_KEY" \
  -H "x-visitante-ip: 200.150.10.20" \
  -H "Content-Type: application/json" \
  -d '{
    "servico": "corte",
    "profissional": "p_3f9c1a2b7d4e",
    "inicio": "2026-10-23T22:00:00.000Z",
    "nome": "Lucas Prado",
    "telefone": "(41) 99999-1111",
    "observacao": "Prefiro máquina 2",
    "origem": { "utm_source": "instagram", "utm_campaign": "outubro", "referrer": "https://l.instagram.com/" }
  }'
{
  "success": true,
  "data": {
    "id": "8d1f...", "data": "2026-10-23", "hora": "19:00",
    "inicio": "2026-10-23T22:00:00.000Z", "fim": "2026-10-23T22:30:00.000Z",
    "servico": "Corte", "profissional": "Nathan", "local": null,
    "preco": 45, "precoAPartirDe": false
  }
}
  • Na confirmação, mostre data e hora. Guarde o id no navegador do cliente pra ele poder cancelar.
  • jaMarcado: true = clique duplo: é a mesma marcação, mostre a confirmação normal.
  • origem (opcional): os parâmetros utm_*, gclid e fbclid da primeira página que a pessoa abriu e o document.referrer. O Venda Perfeita mostra se o cliente veio do Google, do Instagram, de anúncio ou direto.
  • Desabilite o botão enquanto o pedido estiver em andamento.
POST/api/site/agenda/cancelar· Cancelar

Só horário marcado pelo site, com o mesmo WhatsApp. Fica no histórico como “o cliente cancelou”. Pra remarcar: marque o novo e, se der certo, cancele o antigo. Mande também o header x-visitante-ip.

curl -X POST https://vendaperfeita.com/api/site/agenda/cancelar \
  -H "Authorization: Bearer $VP_AGENDA_KEY" \
  -H "x-visitante-ip: 200.150.10.20" \
  -H "Content-Type: application/json" \
  -d '{ "id": "8d1f...", "telefone": "41 99999-1111" }'
{ "success": true, "data": { "id": "8d1f...", "cancelado": true } }

Códigos de erro

codeHTTPQuando
invalid_key401Chave ausente, errada ou trocada. Gere outra em Ajustes › Agendamento online e atualize o segredo.
agenda_off409O agendamento online está desligado, ou não há serviço/profissional disponível.
visitor_ip_required400A marcação veio sem o header x-visitante-ip.
invalid_body400Corpo fora do formato (campo a mais, tipo errado). O motivo vem em detalhe.
date_invalid400data fora do formato AAAA-MM-DD.
service_gone409O serviço não existe mais ou não marca pelo site. Recarregue o catálogo.
member_gone409O profissional saiu da equipe. Recarregue o catálogo.
member_invalid409Esse profissional não faz esse serviço.
slot_gone409O horário não está mais livre. Recarregue os horários do dia.
name_invalid400O nome tem número, link ou formato que não é de nome.
phone_invalid400WhatsApp inválido. Só números do Brasil, com DDD.
notes_link400A observação tem link.
phone_limit429Esse WhatsApp já marcou 3 vezes nas últimas 24 h.
daily_full429A empresa chegou ao teto de marcações online do dia.
month_full409O plano da empresa chegou ao limite de horários do mês.
too_many429Muitas chamadas em pouco tempo. Espere um minuto.
not_found404Cancelar: o horário não existe, não é do site ou o WhatsApp não bate.
not_open409Cancelar: o horário já foi atendido.
past409Cancelar: o horário já passou.

slot_gone: recarregue os horários. service_gone ou member_gone: recarregue o catálogo. invalid_key, agenda_off e visitor_ip_required são de configuração: registre o detalhe e avise o dono.

Testar em paralelo com o sistema atual

Dá pra testar antes de trocar: o sistema atual (Trinks ou outro) continua confirmando as reservas, e o site manda uma cópia de cada uma pro Venda Perfeita.

  1. No Venda Perfeita, cadastre os mesmos profissionais (com o mesmo nome) e o mesmo horário de funcionamento do sistema atual.
  2. Depois que o sistema atual confirmar, a sua função chama catalogo (acha serviço e profissional pelo nome), horarios (acha o inicio da mesma hora) e marcar. Cancelou lá, chame cancelar aqui.
  3. Se o Venda Perfeita recusar uma cópia, só registre o code no log: é onde as duas agendas não batem.
  4. Não ligue as mensagens de WhatsApp do Venda Perfeita durante o teste, senão o cliente recebe a confirmação em dobro.

Quando decidir trocar, tire o sistema antigo e deixe o site usar só as rotas do Venda Perfeita.

Limites

  • 300 leituras e 30 escritas por minuto, por empresa.
  • 10 marcações por hora por visitante (pelo x-visitante-ip).
  • 3 marcações por WhatsApp a cada 24 h, e 80 por empresa por dia (somando o link e o site).
  • O limite de horários do plano da empresa.