Para desenvolvedores
Conecte o Voxiora aos sistemas que você já usa
Consulte chamadas, transcrições, agendamentos e contatos por uma API REST, receba webhooks assinados assim que algo acontece, deixe o assistente consultar dados ao vivo no seu sistema durante a chamada e coloque um assistente de voz no seu site com uma linha de código.
A API REST e os webhooks estão incluídos em todos os planos, a partir do Essential; planos superiores têm limites maiores. No teste grátis você tem acesso de teste: 1 chave de API, 20 requisições por minuto.
https://voxiora.com/api/v1curl https://voxiora.com/api/v1/me \
-H "Authorization: Bearer tf_live_…"{
"object": "account",
"id": "1f2e3d4c-5b6a-4789-8a7b-6c5d4e3f2a1b",
"name": "Smile Dental",
"timezone": "Europe/Warsaw",
"locale": "en",
"country": "PL",
"currency": "PLN",
"status": "active",
"plan": {
"id": "team",
"billing_cycle": "month",
"trial_ends_at": null,
"period_start": "2026-10-01T00:00:00Z",
"period_end": "2026-11-01T00:00:00Z",
"recording_history_days": 365
},
"minutes": {
"included": 3000,
"extra": 100,
"total": 3100,
"used": 412.5,
"remaining": 2687.5
},
"api_key_id": "2a3b4c5d-6e7f-4a8b-9c0d-1e2f3a4b5c6d",
"scopes": [
"read:calls",
"read:appointments",
"read:contacts",
"read:tasks"
],
"limits": {
"plan": "team",
"requests_per_minute": 180,
"requests_per_day": 50000,
"max_api_keys": 10,
"max_webhook_endpoints": 10
}
}O que você pode conectar
Sete formas de integrar o Voxiora ao seu negócio
Escolha o que fizer sentido: automações sem código, algumas linhas de código ou uma integração completa nos dois sentidos.
- Em todos os planos
API REST
Consulte chamadas com transcrição e gravação, agendamentos, contatos e tarefas. Crie e atualize contatos, cancele ou remarque agendamentos e feche tarefas a partir do seu próprio sistema.
- Em todos os planos
Webhooks
Eventos JSON assinados em tempo real: chamada iniciada ou concluída, agendamento marcado, cancelado ou remarcado, novo contato, pedido de retorno.
- Em todos os planos
Dados ao vivo via MCP
Conecte seu servidor MCP e o assistente consulta estoque, disponibilidade ou status de pedidos durante a chamada.
- A partir do Business
Widget de voz para o site
Uma tag script adiciona o botão “Fale conosco”. Os visitantes falam com seu assistente no navegador.
- Em todos os planos
Onboarding por telefone
Envie os novos cadastros do seu sistema e o assistente liga para ajudar essas pessoas a começar.
- Em todos os planos
Agenda e CRM
Google Agenda para agendamentos; HubSpot e Pipedrive para contatos, chamadas, reuniões e tarefas.
- Em todos os planos
Zapier, Make, n8n
Fluxos sem código baseados em webhooks e na API: Google Sheets, Slack, e-mail, qualquer CRM.
Início rápido
Sua primeira requisição em dois minutos
- 1
Crie uma chave de API
No painel, vá em Desenvolvedores → Chaves de API, dê um nome à chave e escolha as permissões. A chave (tf_live_…) aparece só uma vez, então guarde-a logo no seu gerenciador de segredos.
- 2
Teste a conexão
Chame GET /me. Funciona com qualquer chave válida e retorna sua conta, as permissões da chave e os limites do seu plano.
- 3
Leia dados ou assine eventos
Liste chamadas, agendamentos e contatos, ou adicione um endpoint em Desenvolvedores → Webhooks para receber eventos na hora.
curl https://voxiora.com/api/v1/me \
-H "Authorization: Bearer tf_live_…"const API = "https://voxiora.com/api/v1";
const headers = { Authorization: `Bearer ${process.env.VOXIORA_API_KEY}` };
// All calls booked since 1 October, page by page
let cursor = null;
while (true) {
const url = new URL(`${API}/calls`);
url.searchParams.set("outcome", "booked");
url.searchParams.set("since", "2026-10-01T00:00:00Z");
url.searchParams.set("limit", "100");
if (cursor) url.searchParams.set("cursor", cursor);
const res = await fetch(url, { headers });
if (res.status === 429) {
// rate limited: wait for the number of seconds in Retry-After, then retry the same page
await new Promise((r) => setTimeout(r, Number(res.headers.get("Retry-After") ?? 1) * 1000));
continue;
}
if (!res.ok) throw new Error((await res.json()).error.message);
const page = await res.json();
for (const call of page.data) console.log(call.started_at, call.from, call.summary);
if (!page.has_more) break;
cursor = page.next_cursor;
}API REST v1
Chamadas, agendamentos e contatos via HTTPS
JSON na entrada e na saída. Cada requisição é autenticada com uma chave de API e segue os limites do seu plano. As requisições aparecem no painel (método, caminho, status e tempo — nunca o conteúdo de requisições ou respostas).
Autenticação
Crie uma chave em Chaves de API e envie-a como token Bearer. As chaves começam com tf_live_ e pertencem a uma única conta.
Authorization: Bearer tf_live_…Paginação
Os endpoints de lista devolvem até limit itens (1–100, padrão 25) em ordem estável. Quando has_more for true, passe next_cursor sem alterações como cursor (com os mesmos filtros) para obter a próxima página. Um cursor inválido devolve 400 invalid_request.
Erros
Os erros usam códigos de status HTTP padrão e um corpo JSON com um tipo e uma mensagem legível.
{ "error": { "type": "…", "message": "…" } }Endpoints
- GET
/mePermissão: qualquer chaveObter a conta atual
Retorna a conta à qual a chave de API pertence. Útil como chamada de “teste de conexão”.
- GET
/assistantsPermissão: qualquer chaveListar assistentes
Seus assistentes com idioma, status e números de telefone atribuídos. Use o id como assistant_id para filtrar chamadas.
- GET
/assistants/{id}Permissão: qualquer chaveObter um assistente
Um assistente com idioma, status e números de telefone. Com o escopo read:assistants (ou write:assistants) retorna também o prompt: instructions, greeting, company_profile e updated_at.
- PATCH
/assistants/{id}Permissão: write:assistantsAlterar o prompt do assistente
Altera as instruções, a saudação ou o perfil da empresa. Campos omitidos não mudam. Mesmos limites do painel: instruções até 40.000 caracteres, perfil até 10.000, saudação de 5 a 600 caracteres que deve dizer que a pessoa fala com uma IA (senão 400 com code ai_disclosure). Cada alteração vai para o histórico de versões do assistente (origem API) e vale a partir da próxima chamada. As regras de honestidade da plataforma (aviso de IA e de gravação) sempre se aplicam.
- GET
/phone-numbersPermissão: qualquer chaveListar números de telefone
Os números de telefone da sua conta com país, tipo, status e o assistente que os atende.
- GET
/callsPermissão: read:callsListar chamadas
Chamadas da mais recente para a mais antiga, sem transcrições. Chamadas de demonstração nunca são incluídas.
- GET
/calls/{id}Permissão: read:callsObter uma chamada
Uma chamada com a transcrição completa e os agendamentos feitos durante ela.
- GET
/calls/{id}/recordingPermissão: read:callsObter a gravação de uma chamada
Links assinados (válidos por 1 hora) para ouvir e baixar a gravação MP3 (estéreo: quem liga à esquerda, assistente à direita). Uma gravação mais antiga que o histórico do seu plano devolve 403 plan_required com recording_history_days; uma chamada sem gravação devolve 404.
- GET
/appointmentsPermissão: read:appointmentsListar agendamentos
Próximos agendamentos em ordem de início (a partir de agora, por padrão).
- GET
/appointments/{id}Permissão: read:appointmentsObter uma marcação
Uma marcação da sua conta.
- POST
/appointments/{id}/cancelPermissão: write:appointmentsCancelar uma marcação
Cancela uma marcação futura, remove-a do calendário Google ligado e envia o webhook appointment.canceled. calendar_sync indica se o calendário foi atualizado.
- POST
/appointments/{id}/reschedulePermissão: write:appointmentsReagendar uma marcação
Move uma marcação futura para um novo horário. Responde 409 se o horário coincidir com outra marcação ou com um período ocupado no calendário ligado. Sem ends_at a duração mantém-se. Envia o webhook appointment.rescheduled.
- GET
/contactsPermissão: read:contactsListar contatos
Quem ligou para você, do mais recente para o mais antigo. O assistente se lembra deles entre as chamadas.
- GET
/contacts/{id}Permissão: read:contactsObter um contato
Um contato com nome, email, tags, notas e a origem do nome e do email (call, system ou manual).
- POST
/contactsPermissão: write:contactsCriar um contato
Adiciona um contato, por exemplo a partir do seu CRM, para que o assistente saiba o nome de quem liga. Nome e email salvos pela API ficam marcados como manual e o assistente nunca os substitui. Devolve 409 com contact_id se o número já existir. Envia o webhook contact.created.
- PATCH
/contacts/{id}Permissão: write:contactsAtualizar um contato
Altera nome, email, notas ou bloqueio. Campos omitidos não mudam e null limpa um campo. Um nome ou email alterado fica marcado como manual, então o assistente não o substituirá. O número de telefone não pode ser alterado.
- GET
/tasksPermissão: read:tasksListar tarefas
Pedidos de retorno, mensagens e outras tarefas das chamadas, das mais recentes para as mais antigas.
- GET
/tasks/{id}Permissão: read:tasksObter uma tarefa
Uma tarefa da sua conta.
- PATCH
/tasks/{id}Permissão: write:tasksAtualizar uma tarefa
Define o status da tarefa como open, done ou dismissed, por exemplo depois que sua equipe retornou a ligação ao cliente.
- POST
/calls/outboundPermissão: write:callsCriar uma chamada de saída
Seu assistente liga para uma pessoa a partir do número da sua empresa, com o objetivo que você definir, como uma etapa de uma sequência de onboarding. A chamada é feita agora ou em call_at, sempre dentro do horário de chamadas (seg–sáb, 9h–20h no fuso horário da sua conta; fora dele, é movida para o próximo horário permitido e call_at mostra quando). Se ninguém atender, tenta até 3 vezes, com 2 horas de intervalo. Retorna 202 com a chamada no status scheduled. Erros: 400 consent_missing, invalid_phone, number_not_callable, international ou invalid_call_at; 409 opted_out (a pessoa pediu para não receber ligações), already_scheduled (com existing_id), assistant_not_live, over_quota ou no_outbound_number; 429 daily_outbound_limit com limit (200 chamadas a cada 24 horas por padrão). O resultado chega nos webhooks call.completed e outbound_call.finished com o seu external_id.
- GET
/calls/outbound/{id}Permissão: write:callsObter uma chamada de saída
Status de uma chamada de saída agendada: scheduled, dialing, done (com call_id da conversa), failed (last_error, ex.: no_answer após todas as tentativas) ou canceled. Também funciona com o callback_id dos webhooks para chamadas de onboarding e de retorno.
- DELETE
/calls/outbound/{id}Permissão: write:callsCancelar uma chamada de saída
Cancela uma chamada de saída criada pela API que ainda está agendada. Pode ser repetido com segurança (uma chamada já cancelada retorna 200). Retorna 409 not_cancelable quando a chamada está em discagem ou finalizada, ou para chamadas de onboarding (nesse caso, remova a pessoa com POST /api/outreach/unenroll).
- GET
/messagesPermissão: read:messagesListar SMS
SMS enviados pela sua conta e respostas de clientes, dos mais recentes. phone é o número do cliente (destinatário ou remetente de uma resposta). generated_by: template, ai ou manual; charged_from: plan ou credits.
- POST
/messagesPermissão: write:messagesEnviar um SMS
Envia um SMS para um dos seus contatos ou pessoas que ligaram: seu próprio texto ou um modelo da sua conta com vars (date, time, name, service, link, amount). Conta no limite de SMS do plano e nos SMS adicionais. Erros: 400 invalid_request (consent_missing, invalid_phone, too_long, missing_vars); 409 conflict (opted_out — o cliente respondeu STOP, over_quota, recipient_not_allowed — crie o contato primeiro, blocked_destination); 429 rate_limited.
Permissões
Cada chave tem as permissões escolhidas ao ser criada. As permissões não podem ser alteradas depois — se precisar de mais, crie uma nova chave. Quando falta à chave a permissão necessária, os endpoints respondem 403 insufficient_scope. GET /me, /assistants e /phone-numbers funcionam com qualquer chave válida.
read:callsLer chamadas, resumos e transcriçõesread:appointmentsLer marcaçõeswrite:appointmentsCancelar e reagendar marcaçõesread:contactsLer contactoswrite:contactsCriar e editar contatosread:tasksLer tarefas e pedidos de retornowrite:tasksAlterar o status das tarefaswrite:callsIniciar chamadas de saída, consultá-las e cancelá-lasread:messagesLer SMS e respostas de clienteswrite:messagesEnviar SMS para seus contatosread:assistantsLer o prompt do assistente (instruções, saudação, perfil da empresa)write:assistantsAlterar o prompt do assistente
Erros
400invalid_request — um parâmetro está ausente ou é inválido401unauthorized — chave de API ausente, inválida ou revogada403insufficient_scope — a chave não tem a permissão do endpoint; plan_required — a conta não tem um plano ativo ou a gravação é mais antiga que o histórico de gravações do plano404not_found — o objeto não existe na sua conta409conflict — o horário já está ocupado, a marcação não pode ser alterada, já existe um contato com este número ou uma chamada de saída não pode ser feita (code: opted_out, already_scheduled, assistant_not_live, over_quota, no_outbound_number, not_cancelable)429rate_limited — demasiados pedidos; tente novamente após o tempo do cabeçalho Retry-After500server_error — algo deu errado do nosso lado503service_unavailable — problema temporário; tente novamente após o tempo do cabeçalho Retry-After
A referência completa da API, com parâmetros e exemplos de resposta, está no painel em Desenvolvedores → Referência da API.
Webhooks
Eventos enviados ao seu servidor em tempo real
Adicione um endpoint https no painel, escolha os eventos e enviaremos um envelope JSON assinado (POST) assim que algo acontecer. “Enviar teste” entrega um exemplo do seu primeiro evento, útil para mapear campos no Zapier ou no Make.
Eventos
call.completedChamada concluídaResumo, resultado, sentimento, transcrição, contato e agendamentos; em chamadas de saída, também a sequência ou a requisição da API (callback_id, external_id, outreach).
call.startedChamada iniciadaUma chamada foi atendida (de entrada, de saída ou pela web).
appointment.bookedAgendamento realizadoO assistente fez um agendamento.
appointment.canceledMarcação canceladaUma marcação foi cancelada por telefone ou através da API.
appointment.rescheduledMarcação reagendadaUma marcação foi movida para um novo horário (inclui o horário anterior).
task.createdRetorno / tarefa criadaAlguém pediu um retorno ou deixou uma tarefa.
contact.createdNovo contatoQuem ligou pela primeira vez foi salvo como contato.
outbound_call.finishedChamada de saída finalizadaUma chamada de saída agendada (API, sequência de onboarding ou retorno) foi concluída ou falhou — também quando ninguém atendeu após todas as tentativas.
Cabeçalhos de cada entrega
Voxiora-SignatureAssinatura: t=<tempo unix>,v1=<HMAC-SHA256 hex>Voxiora-EventTipo de evento, ex.: appointment.bookedVoxiora-DeliveryID única da entregaUser-AgentVoxiora-Webhooks/1.0 · Identifica nosso remetente de webhooks
Entrega e novas tentativas
- Responda com qualquer status 2xx em até 10 segundos. Redirecionamentos não são seguidos.
- Entregas com falha são repetidas após 1 min, 5 min, 30 min, 2 h, 6 h e 12 h (7 tentativas, cerca de 21 horas).
- O mesmo evento pode chegar mais de uma vez. Use o id do evento para ignorar duplicados.
- Só aceitamos endereços https públicos. Após 50 falhas seguidas, o endpoint é pausado e o painel mostra o motivo.
- O painel mantém um registro de entregas com códigos de status e respostas e permite repetir uma entrega manualmente.
{
"id": "evt_3f9a1c7e5b2d4f6a8c0e1b3d5f7a9c1e",
"type": "call.completed",
"created_at": "2026-10-01T09:17:45Z",
"account_id": "1f2e3d4c-5b6a-4789-8a7b-6c5d4e3f2a1b",
"data": {
"id": "5b1f0c6e-2a8d-4f3e-9d51-7c0a4e2b9f10",
"object": "call",
"assistant_id": "0e6f4c8a-3b2d-4a1e-8f7c-5d9b2a1c3e4f",
"phone_number_id": "4d3c2b1a-0f9e-4d8c-b7a6-958473625140",
"contact_id": "9a8b7c6d-5e4f-4a3b-2c1d-0e9f8a7b6c5d",
"direction": "inbound",
"status": "completed",
"from": "+48601234567",
"to": "+48221234567",
"started_at": "2026-10-01T09:14:03Z",
"ended_at": "2026-10-01T09:17:41Z",
"duration_sec": 218,
"summary": "Anna Kowalska booked a first consultation for Friday 10:00.",
"outcome": "booked",
"sentiment": "positive",
"tags": [
"new-customer"
],
"has_recording": true,
"end_reason": "caller_hangup",
"page_url": null,
"page_title": null,
"continued_from": null,
"callback_id": null,
"external_id": null,
"outreach": null,
"callback_return": false,
"caller_spoke": true,
"caller_words": 6,
"transcript": [
{
"role": "caller",
"text": "I'd like to book a consultation this week.",
"at": 4.1
}
],
"contact": {
"id": "9a8b7c6d-5e4f-4a3b-2c1d-0e9f8a7b6c5d",
"object": "contact",
"phone": "+48601234567",
"name": "Anna Kowalska",
"name_source": "call",
"email": "anna.kowalska@example.com",
"email_source": "call",
"notes": null,
"tags": [
"customer"
],
"blocked": false,
"calls_count": 3,
"last_call_at": "2026-10-01T09:14:03Z",
"created_at": "2026-08-12T15:02:11Z"
},
"appointments": [
{
"id": "c3d2e1f0-a9b8-4c7d-8e6f-5a4b3c2d1e0f",
"object": "appointment",
"call_id": "5b1f0c6e-2a8d-4f3e-9d51-7c0a4e2b9f10",
"contact_id": "9a8b7c6d-5e4f-4a3b-2c1d-0e9f8a7b6c5d",
"customer_name": "Anna Kowalska",
"customer_phone": "+48601234567",
"customer_email": "anna.kowalska@example.com",
"service": "First consultation",
"starts_at": "2026-10-03T08:00:00Z",
"ends_at": "2026-10-03T08:30:00Z",
"status": "booked",
"external_id": "google:7h3k9s2l1m0n",
"created_at": "2026-10-01T09:16:20Z"
}
]
}
}Verificação de assinaturas. Cada entrega tem um cabeçalho Voxiora-Signature no formato t=timestamp,v1=signature. Calcule o HMAC-SHA256 de “timestamp.raw_body” com seu segredo de assinatura e compare com v1. Rejeite timestamps com mais de 5 minutos.
import crypto from "node:crypto";
// Express: app.post("/webhook", express.raw({ type: "application/json" }), handler)
export function verify(rawBody, signatureHeader, secret) {
// Voxiora-Signature: t=1727774265,v1=5f2c…
const parts = Object.fromEntries(signatureHeader.split(",").map((p) => p.split("=")));
const expected = crypto.createHmac("sha256", secret).update(`${parts.t}.${rawBody}`).digest("hex");
const fresh = Math.abs(Date.now() / 1000 - Number(parts.t)) < 300;
const given = Buffer.from(parts.v1 ?? "");
// timingSafeEqual needs buffers of the same length
return fresh && given.length === expected.length && crypto.timingSafeEqual(Buffer.from(expected), given);
}import hmac, hashlib, time
def verify(raw_body: bytes, signature_header: str, secret: str) -> bool:
parts = dict(p.split("=", 1) for p in signature_header.split(","))
expected = hmac.new(secret.encode(), f"{parts['t']}.".encode() + raw_body, hashlib.sha256).hexdigest()
fresh = abs(time.time() - int(parts["t"])) < 300
return fresh and hmac.compare_digest(expected, parts.get("v1", ""))import express from "express";
import { verify } from "./verify.js";
const app = express();
const seen = new Set(); // use your database in production
app.post("/voxiora/webhook", express.raw({ type: "application/json" }), (req, res) => {
const raw = req.body.toString("utf8");
if (!verify(raw, req.get("Voxiora-Signature") ?? "", process.env.VOXIORA_WEBHOOK_SECRET)) return res.sendStatus(401);
const event = JSON.parse(raw);
if (seen.has(event.id)) return res.sendStatus(200); // retried delivery, already handled
seen.add(event.id);
if (event.type === "appointment.booked") {
const a = event.data;
console.log("New booking:", a.customer_name, a.service, a.starts_at);
}
res.sendStatus(200); // answer with 2xx within 10 seconds
});
app.listen(3000);Valores estáveis
Estes valores em chamadas (API e webhooks call.*) e em chamadas de saída (outbound_call.finished, /calls/outbound) são um contrato estável: podemos adicionar novos valores, mas não vamos alterar nem remover estes. Tentativas de saída sem resposta, ocupadas ou rejeitadas nunca criam uma chamada, então não há call.completed para elas: você recebe outbound_call.finished com last_error no_answer após a última tentativa. Uma chamada atendida pela caixa postal conta como atendida (normalmente uma chamada curta com outcome other).
Status da chamada
in_progress- A chamada está em andamento.
completed- A pessoa falou com o assistente.
missed- Ninguém falou, ou o assistente não pôde atender a chamada (veja end_reason).
failed- A chamada não pôde ser tratada por causa de um erro.
Resultado da chamada
booked- Foi feito um agendamento.
transferred- A chamada foi transferida para uma pessoa.
message- Foi registrada uma mensagem, pedido de retorno, encomenda ou acompanhamento.
info- A pessoa recebeu informações; nada mais foi necessário.
spam- Spam, telemarketing ou um número bloqueado.
other- Qualquer outra coisa, ex.: uma chamada muito curta ou caixa postal.
Motivo de encerramento da chamada (end_reason)
caller_hangup- A outra pessoa desligou.
caller_hangup_greeting- Chamada de saída: a pessoa desligou durante a saudação ou logo a seguir, sem dizer nada (chamada até 45 s). Nesse caso caller_spoke é false.
agent_hangup- O assistente encerrou a chamada após se despedir.
transferred- A chamada foi transferida para uma pessoa.
silence- Encerrada após um longo silêncio.
max_duration- A duração máxima da chamada foi atingida.
spam- Encerrada como spam.
blocked- O número está bloqueado nos contatos.
busy- Todas as linhas da conta estavam ocupadas.
over_quota- Sem minutos de chamada restantes.
trial_expired- O teste gratuito terminou.
inactive- Sem plano ativo.
assistant_not_live- O assistente está pausado.
no_assistant- Nenhum assistente atende este número.
ai_budget- Tratada sem IA por causa de um limite temporário; a equipe foi avisada para retornar a ligação.
error- Um erro técnico encerrou a chamada.
Status da chamada de saída
scheduled- Aguardando o seu horário (ou a próxima tentativa).
dialing- Ligando agora.
done- Atendida; call_id é a conversa.
failed- Não atendida após todas as tentativas, ou não pôde ser feita (veja last_error).
canceled- Cancelada (API, pessoa removida da sequência ou sequência desativada).
last_error da chamada de saída
no_answer- Ninguém atendeu (também ocupado ou rejeitada).
failed- O assistente não estava disponível no horário da chamada (plano, minutos ou pausa).
no_result- Nenhum resultado da chamada em 15 minutos.
expired- A chamada estava mais de 2 horas atrasada, então não foi feita.
outside_window- Movida para o próximo horário de chamadas (o status continua scheduled).
dial_error- A rede telefônica recusou a chamada (enviado como dial_<reason>).
over_quota- Sem minutos de chamada restantes.
inactive- Sem plano ativo.
assistant_not_live- O assistente está pausado.
no_outbound_number- Nenhum número da empresa para fazer a ligação.
canceled_by_api- Cancelada com DELETE /calls/outbound/{id}.
unenrolled- A pessoa foi removida da sequência (POST /api/outreach/unenroll).
opt_out- A pessoa pediu para não receber ligações.
replaced- Substituída por um retorno mais recente para o mesmo número.
Dados ao vivo via MCP
O assistente consulta o seu sistema durante a chamada
Conecte um servidor MCP remoto (Model Context Protocol), como o catálogo da sua loja, o estoque ou o sistema de agendamentos ou pedidos. Você escolhe exatamente quais ferramentas e recursos (somente leitura) o assistente pode usar.
Aprender com antecedência
Para conteúdos que mudam pouco, como tabelas de preços, descrições de produtos ou políticas. Os recursos e ferramentas de leitura escolhidos são importados para o conhecimento do assistente a cada 1 a 168 horas ou quando você quiser. Sem atraso na chamada.
Consultar ao vivo na chamada
Para o que muda: estoque, disponibilidade, status do pedido. O assistente usa a ferramenta durante a conversa com um rápido “um momento, vou verificar”. Se o seu servidor não responder em cerca de 2,5 segundos, ele diz que não consegue confirmar agora e oferece um retorno da sua equipe.
O que você precisa
- Um servidor MCP acessível por https (Streamable HTTP, ex.: https://mcp.example.com/mcp; servidores HTTP+SSE antigos são detectados automaticamente).
- Autenticação: nenhuma, um token Bearer ou um cabeçalho próprio como X-API-Key. Os segredos são criptografados (AES-256-GCM) e nunca vão para o navegador.
- Ferramentas somente leitura. As marcadas como destrutivas são bloqueadas; para as que não estão marcadas como somente leitura, você confirma que elas apenas leem dados.
- Até 5 fontes e 50 ferramentas ao vivo por assistente. As consultas ao vivo devem responder em cerca de 2 segundos.
- Opcional para o widget do site: numa ferramenta «No início da chamada», escolha o argumento que recebe o token de identidade do visitante com sessão iniciada (ver Widget de voz para o site).
Os argumentos são validados pelo esquema da ferramenta, os resultados são encurtados e tratados estritamente como dados (nunca como instruções), e cada consulta é registrada sem dados de quem liga. Endereços privados e internos são recusados.
Servidor MCP para agentes de IA
Dê ao seu agente de IA acesso ao Voxiora
O Voxiora oferece um servidor MCP remoto (Model Context Protocol). Conecte Claude, ChatGPT, Cursor ou seu próprio agente: ele lê chamadas, transcrições, agendamentos, contatos e tarefas e, com sua permissão, cria contatos, inicia chamadas de saída e envia SMS.
- Endpoint: https://voxiora.com/api/mcp (Streamable HTTP, JSON-RPC 2.0, sem estado).
- Autenticação: a mesma chave de API da API REST (Authorization: Bearer tf_live_…) ou um token de acesso OAuth de 1 hora obtido com client credentials. Sem ela, o servidor responde 401 com um link para os metadados OAuth.
- O agente só vê as ferramentas permitidas pelos scopes da chave, e cada chamada passa pelas mesmas verificações, limites e registro de requisições da API REST.
- Chamadas de saída e SMS exigem consent: true, como na API. Os resultados das ferramentas são dados dos seus clientes, nunca instruções.
OAuth para agentes
Troque uma chave de API por um token de acesso de curta duração em https://voxiora.com/api/oauth/token: client_id é o id da chave (api_key_id de GET /me) ou o prefixo dela, client_secret é a chave. O token recebe os scopes solicitados que a chave tem. Revogar a chave no painel invalida todos os tokens emitidos com ela.
Os agentes também podem pedir acesso sozinhos: POST https://voxiora.com/api/agent-auth/register devolve um código, o proprietário da conta aprova no painel (Aprovar um agente de IA) e o agente recebe uma única vez a própria chave de API. Nada é concedido antes da aprovação; detalhes no auth.md.
Ferramentas
get_accountqualquer chavelist_assistantsqualquer chavelist_phone_numbersqualquer chavelist_callsread:callsget_callread:callslist_contactsread:contactsget_contactread:contactscreate_contactwrite:contactslist_appointmentsread:appointmentsget_appointmentread:appointmentslist_tasksread:taskslist_messagesread:messagesstart_outbound_callwrite:callsget_outbound_callwrite:callssend_messagewrite:messages
Documentos de descoberta
curl https://voxiora.com/api/mcp \
-H "Authorization: Bearer tf_live_…" \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-11-25","capabilities":{},"clientInfo":{"name":"my-agent","version":"1.0"}}}'curl https://voxiora.com/api/oauth/token \
-u "<api_key_id>:tf_live_…" \
-d grant_type=client_credentials \
-d scope="read:calls read:contacts"Widget de voz para o site
Seu assistente no seu site, com uma linha de código
Os visitantes clicam em um botão e falam, no navegador, com o mesmo assistente que atende o seu telefone. As chamadas web usam os minutos do seu plano, sem custos de telefonia.
A partir do Business
- Cerca de 21 KB, sem dependências, isolado em Shadow DOM para que os estilos do seu site não o quebrem.
- Fala o idioma da sua página (<html lang>) ou o definido com data-lang="de".
- Legendas ao vivo; se o microfone estiver bloqueado, o visitante pode digitar e o assistente responde por voz.
- Limite o widget aos seus domínios e ele só vai iniciar nesses sites.
<script src="https://voxiora.com/widget.js" data-key="tfw_…" async></script>// optional: open the widget from your own button
document.querySelector("#talk-to-us").addEventListener("click", () => window.VoxioraWidget?.open());
// open and start right away: { mode: "voice" } or { mode: "chat" } (text only, no microphone)
window.VoxioraWidget?.open({ mode: "chat" });
window.VoxioraWidget?.close(); // close the panel
window.VoxioraWidget?.destroy(); // remove the widget from the pageTem uma Content Security Policy rígida? Permita script-src https://voxiora.com https://cdn.jsdelivr.net, connect-src https://voxiora.com wss://*.livekit.cloud https://*.livekit.cloud e media-src blob:.
Utilizadores com sessão iniciada (token de identidade)
Quando os visitantes têm sessão iniciada no seu site, o assistente pode saber quem está a falar sem pedir o e-mail.
- O seu servidor emite um token assinado e de curta duração para o utilizador com sessão iniciada (p. ex. HMAC, válido 15 minutos). Nunca coloque um e-mail nem um ID de utilizador no navegador: qualquer pessoa poderia escrever o de outra na consola.
- Chame VoxioraWidget.identify({ token }) a qualquer momento; uma chamada posterior substitui o token e identify(null) apaga-o. Antes de o widget.js carregar, defina window.VoxioraIdentity = { token, expires_at }: é lido quando a conversa começa e um token expirado é ignorado.
- No painel, escolha o argumento do token de identidade em qualquer ferramenta MCP em tempo real: de consulta, de ação ou a sua ferramenta «No início da chamada». A Voxiora passa o token sem alterações apenas para esse argumento, nunca o guarda nem o mostra e mantém-no fora de transcrições, resumos, webhooks e registos; o assistente nunca o vê.
- De 8 a 400 caracteres: letras, dígitos e . _ ~ + / = - (p. ex. base64url). Renove-o antes de expirar, por exemplo a cada 10 minutos. O seu servidor MCP verifica-o; um token inválido ou expirado deve dar o mesmo resultado que não ter token. As chamadas telefónicas e as conversas sem token funcionam como até agora.
// signed-in user: a short-lived, signed token issued by YOUR server (never an e-mail or user ID)
const { token, expires_at } = await fetch("/api/voxiora-identity").then((r) => r.json());
window.VoxioraIdentity = { token, expires_at }; // read when the conversation starts, also before widget.js loads
window.VoxioraWidget?.identify({ token, expires_at }); // replaces the token at any time
// refresh before it expires (e.g. every 10 minutes); on sign-out:
window.VoxioraIdentity = null;
window.VoxioraWidget?.identify(null);Modo chat e botão próprio
Abra o assistente pela sua própria interface — um botão, um menu ou uma recepção numa cena 3D — por voz ou como chat de texto.
- data-launcher="none" oculta o botão flutuante: o painel só abre pelo seu código com VoxioraWidget.open() e fecha com close(). O foco volta para onde estava (por exemplo, o canvas do seu jogo). close() apenas esconde o painel e a conversa continua; VoxioraWidget.endCall() ou close({ end: true }) termina-a (o widget fica).
- open({ mode: "voice" }) ou open({ mode: "chat" }) abre o painel e inicia a conversa na hora. data-mode="chat" torna o chat o modo padrão do botão de início.
- O modo chat nunca pede o microfone: o visitante digita e o assistente responde por texto. É o mesmo assistente, com o mesmo conhecimento e as mesmas ferramentas.
- Todos os métodos funcionam antes de o widget carregar: as chamadas entram numa fila e rodam assim que ele estiver pronto. Antes mesmo de carregar o widget.js, você pode colocá-las em window.VoxioraWidget = { q: [["open", { mode: "chat" }]] }.
<!-- no floating button: the panel opens only from your code -->
<script src="https://voxiora.com/widget.js" data-key="tfw_…" data-launcher="none" data-mode="chat" async></script>
<script>
// calls made before widget.js has loaded are queued and run when it starts
window.VoxioraWidget = window.VoxioraWidget || { q: [] };
const voxiora = (method, ...args) =>
window.VoxioraWidget.q ? window.VoxioraWidget.q.push([method, ...args]) : window.VoxioraWidget[method](...args);
// e.g. the reception desk in your 3D gallery
document.querySelector("#talk").addEventListener("click", () => voxiora("open", { mode: "voice" })); // asks for the microphone
document.querySelector("#chat").addEventListener("click", () => voxiora("open", { mode: "chat" })); // text only, no microphone
// later:
// VoxioraWidget.close(); hide the panel (the conversation continues)
// VoxioraWidget.isOpen(); true | false
// VoxioraWidget.state(); { ready, open, mode, call: "idle" | "connecting" | "active", agent_state }
// VoxioraWidget.init({ launcher: false, mode: "chat", lang: "de" }); // the same options in code
</script>Eventos
Reaja à conversa na sua página: anime um avatar enquanto o assistente fala, mostre seus próprios balões de chat ou registre as chamadas.
- Cada evento é um CustomEvent de window chamado voxiora:<nome> e também pode ser ouvido com VoxioraWidget.on(nome, fn) / off(nome, fn).
- ready { key, assistant, available } · open · close · call_started { mode, roomName } · call_ended { reason } · agent_state { state: listening | thinking | speaking } · error { code }
- speaking { speaking, level }: nível da voz do assistente de 0 a 1, até 20 vezes por segundo enquanto ele fala e a cada mudança, também quando o visitante prefere movimento reduzido.
- message { role: agent | user, text, final, id }: o texto conforme chega (final: false) e completo (final: true), para a sua própria interface de chat. tool: veja as ferramentas na página abaixo. Uma intervenção = um id: chegam vários eventos com o mesmo id e o texto final tem final: true — junte-os por id.
const avatar = document.querySelector("#receptionist");
// { speaking: boolean, level: 0..1 } — up to 20 times per second while the assistant speaks
window.addEventListener("voxiora:speaking", (e) => {
avatar.classList.toggle("talking", e.detail.speaking);
avatar.style.setProperty("--mouth", e.detail.level); // e.g. scale the mouth or a glow
// Unity WebGL: unityInstance.SendMessage("Receptionist", "SetVoiceLevel", e.detail.level);
});
// the same events through the widget API (name with or without the "voxiora:" prefix)
VoxioraWidget.on("call_started", ({ mode, roomName }) => console.log("started", mode, roomName));
VoxioraWidget.on("call_ended", ({ reason }) => console.log("ended", reason)); // user | disconnected | …
VoxioraWidget.on("agent_state", ({ state }) => console.log(state)); // listening | thinking | speaking
VoxioraWidget.on("message", ({ role, text, final }) => final && console.log(role, text)); // your own chat UI
VoxioraWidget.on("error", ({ code }) => console.warn("Voxiora:", code)); // rate_limited, assistant_offline, …Contexto da página
Diga ao assistente onde o visitante está — em qual galeria, loja ou produto — para que ele responda sem perguntar.
- VoxioraWidget.setContext({ … }) ou data-context='{"gallery":"POL"}' na tag script; setContext(null) limpa. Durante uma conversa, o novo contexto chega de imediato ao assistente, junto com o endereço e o título atuais da página (também após navegar sem recarregar); caso contrário, vale para a próxima conversa.
- Até 20 chaves (letras minúsculas, dígitos e _, começando por letra); valores: texto de até 200 caracteres, números ou true/false, no máximo 2000 bytes no total. Um contexto inválido é ignorado com um aviso no console e o anterior é mantido.
- Nas instruções do assistente use {{context.gallery}}, {{context.store}} etc.; o assistente também vê o contexto como informação sobre a página.
- Seu servidor MCP o recebe no cabeçalho Voxiora-Context (JSON compacto, caracteres não ASCII como \uXXXX, até 1000 bytes; acima disso ficam as chaves que cabem, primeiro as secret_) junto com Voxiora-Call-Id. Trate-o como dado não confiável: quem o define é o navegador do visitante. As chaves que começam por secret_ (p. ex., secret_session) vão apenas para o seu servidor MCP: o assistente nunca as vê, nunca são guardadas, registadas nem mostradas e, se o seu servidor repetir uma, ela é substituída por [secret].
// what the visitor is looking at; used by the next conversation
VoxioraWidget.setContext({ gallery: "POL", store: "Lumi Shoes", floor: 2, logged_in: true });
VoxioraWidget.setContext(null); // clear
// or on the script tag: data-context='{"gallery":"POL"}'
// assistant instructions:
// The visitor is in gallery {{context.gallery}}, at the store {{context.store}}.
// every live lookup on your MCP server during that conversation carries:
// Voxiora-Call-Id: 5b1f0c6e-…
// Voxiora-Context: {"gallery":"POL","store":"Lumi Shoes","floor":2,"logged_in":true}
// (non-ASCII as \uXXXX — JSON.parse restores it; set by the visitor's browser, so treat it as untrusted)Ferramentas na página
Deixe o assistente agir no navegador do visitante — mostrar uma loja, abrir um produto, ler o carrinho — com funções que você registra na página.
- VoxioraWidget.registerTools([...]): até 10 ferramentas com name (minúsculas, dígitos, _), description (o que faz e quando usar, até 500 caracteres) e parameters como JSON Schema do tipo object (até 4000 bytes). A lista vale para a próxima conversa.
- Quando o assistente chama uma ferramenta, seu handler(args, { waitForUser }) roda (pode retornar um valor ou uma Promise) e o evento voxiora:tool é emitido com name, args, respond(resultado), reject(erro) e waitForUser(). Vale a primeira resposta.
- Responda em até 9 segundos; caso contrário, o assistente saberá que a ferramenta não respondeu. Se a ação precisar do visitante (p. ex., confirmar um pagamento), chame primeiro waitForUser(): o assistente diz que está à espera e você tem até 29 segundos. Os resultados são limitados a 15.000 bytes de JSON; ferramentas desconhecidas são recusadas.
- Os argumentos vêm do modelo de IA: valide-os como qualquer entrada do usuário e nunca execute sem perguntar ações que precisam da confirmação do visitante.
VoxioraWidget.registerTools([
{
name: "show_store",
description: "Moves the visitor's view to a store in the gallery. Use it when they ask where a store is.",
parameters: { type: "object", properties: { store_id: { type: "string" } }, required: ["store_id"] },
// runs in the visitor's browser; the returned value (or Promise) goes back to the assistant
handler: async ({ store_id }) => {
await gallery.flyTo(String(store_id)); // your code — validate arguments like any user input
return { shown: true };
},
},
{ name: "cart_count", description: "Number of items in the visitor's cart.", parameters: { type: "object", properties: {} } },
]);
// or answer from an event listener — the first answer wins; no answer within 9 s = "timeout"
window.addEventListener("voxiora:tool", (e) => {
const { name, args, respond, reject } = e.detail;
if (name === "cart_count") respond({ items: cart.length });
});Vários assistentes numa página
Cada assistente tem a própria chave de widget. Alterne entre eles sem recarregar a página — por exemplo, entre a recepção e o assistente de uma loja.
- VoxioraWidget.switchTo({ key }) encerra a conversa atual, remove o widget e o inicia de novo com a outra chave; um open() chamado logo depois espera o novo assistente ficar pronto. O contexto (setContext), as ferramentas (registerTools) e os ouvintes (on) mantêm-se: não é preciso registá-los de novo; mude apenas o contexto se o outro assistente precisar de outro (por exemplo place).
- Seus ouvintes de eventos, o contexto da página e as ferramentas continuam; cada chave guarda o próprio estado para retomar conversas. Adicione seu domínio aos domínios permitidos de cada chave.
- VoxioraWidget.destroy() remove o widget por completo: interface, ouvintes, conversa e estado de retomada salvo.
const RECEPTION = "tfw_…"; // widget key of the gallery reception
const STORE = "tfw_…"; // widget key of a store's own assistant
document.querySelector("#store-desk").addEventListener("click", () => {
VoxioraWidget.switchTo({ key: STORE }); // ends the conversation, reloads the widget with the other assistant
VoxioraWidget.open({ mode: "voice" }); // queued until the new assistant is ready
});
VoxioraWidget.on("ready", ({ key, assistant }) => console.log("now:", assistant, key === RECEPTION ? "reception" : "store"));
VoxioraWidget.destroy(); // remove the widget completely (interface, listeners, conversation, resume state)Onboarding por telefone
Seus novos clientes recebem uma ligação de boas-vindas automaticamente
Quando alguém se cadastra no seu sistema, envie essa pessoa para uma sequência de ligações. O assistente liga do número da sua empresa, ajuda a começar e volta a ligar alguns dias depois. As ligações acontecem dentro do horário de ligações da sequência: por padrão de segunda a sábado, das 9h às 20h no seu fuso horário, ou nos dias e horários que você definir.
POST/api/outreach/enroll
Autentique-se com a chave da sequência (tlo_…) do painel, como token Bearer ou no cabeçalho X-Voxiora-Key. Cada sequência tem sua própria chave.
Corpo da requisição
- Número de telefone, de preferência no formato E.164. Números nacionais são lidos com o código do país da sua conta.
phonestringobrigatório - Deve ser true: a pessoa concordou em ser contatada por telefone, ex.: no seu formulário de cadastro.
consenttrueobrigatório - Nome, até 120 caracteres.
namestringopcional - Endereço de e-mail.
emailstringopcional - O que o assistente deve saber sobre essa pessoa, até 1.000 caracteres (ex.: o plano escolhido).
contextstringopcional - A ID da pessoa no seu sistema (texto ou número). A mesma ID é inscrita só uma vez.
external_idstring | numberopcional
curl -X POST "https://voxiora.com/api/outreach/enroll" \
-H "Authorization: Bearer tlo_…" \
-H "Content-Type: application/json" \
-d '{"phone":"+48601234567","name":"Anna Kowalska","email":"anna@example.com","context":"Signed up today, Start plan","external_id":"user_123","consent":true}'{
"ok": true,
"enrollment_id": "8f7e6d5c-4b3a-4c2d-9e1f-0a9b8c7d6e5f",
"external_id": "user_123",
"status": "active",
"next_call_at": "2026-10-09T10:20:00Z",
"limits": {
"per_day": 500,
"remaining_today": 499
}
}Respostas
- 201: inscrita. enrollment_id, external_id, status, next_call_at (horário da primeira ligação), intro_sms_at (quando sai o SMS antes da primeira chamada, ou null) e limits { per_day, remaining_today }
- 200: já inscrita (mesmo external_id, ou este número já está em andamento na sequência), com duplicate: true
- 400: invalid_request, invalid_phone ou consent_required
- 401: invalid_key
- 409: sequence_disabled, consent_missing ou opted_out (a pessoa não quer ligações)
- 429: limit, o limite diário de inscrições da sequência foi atingido (500 novas pessoas a cada 24 horas; o corpo contém limit). rate_limited: mais de 120 requisições por minuto com esta chave (cabeçalho Retry-After)
Horário de ligações: defina no painel os dias e um intervalo entre 7h e 21h para cada sequência. Se ninguém atender, o assistente tenta até 3 vezes, com 2 horas de intervalo, dentro desse horário.
SMS antes da chamada: quando está ativo na sequência (painel), a pessoa recebe uma mensagem curta do número de onde o assistente vai ligar, por predefinição 20 minutos antes da primeira chamada (5–120 min). Se a primeira chamada fosse mais cedo, é adiada para que o SMS saia sempre primeiro, dentro do horário de chamadas. Um SMS que falhe (a pessoa respondeu STOP, os SMS do plano esgotaram-se) nunca impede a chamada. Cada SMS conta para os SMS do seu plano e aparece no painel, em SMS.
Saudação: no painel define a primeira frase da chamada para cada passo (ou por omissão para toda a sequência) — um texto fixo com as variáveis {first_name}, {first_name_vocative} (vocativo polaco, p. ex. Krystianie), {assistant_name}, {brand} (nome da empresa nas chamadas, das definições do assistente) e {name}, com uma variante própria para inscrições sem nome — ou um modo em que o assistente escreve a primeira frase a partir de name, context, do objetivo do passo e do resultado das ferramentas «No início da chamada». Que liga um assistente de IA e que a chamada é gravada é sempre acrescentado à primeira frase se o texto não o disser.
Remover uma pessoa da sequência
POST/api/outreach/unenroll
Quando alguém não precisa mais das ligações (por exemplo, após a primeira venda ou se cancelou), interrompa a sequência dessa pessoa com a mesma chave. As ligações agendadas são canceladas imediatamente. Uma ligação já em andamento não é interrompida, mas nenhuma outra ligação será feita depois dela.
- Exatamente um destes: external_id (como enviado na inscrição), enrollment_id (da resposta da inscrição) ou phone.
external_id | enrollment_id | phoneobrigatório - Motivo opcional, até 200 caracteres, guardado no registro de auditoria da sua conta.
reasonopcional
- 200: interrompida (changed: true) ou já encerrada: status stopped, completed ou failed (changed: false). Pode ser repetido com segurança.
- 400: invalid_request (nenhum identificador ou mais de um) ou invalid_phone
- 401: invalid_key
- 404: not_found, não existe essa inscrição nesta sequência
- 429: rate_limited
curl -X POST "https://voxiora.com/api/outreach/unenroll" \
-H "Authorization: Bearer tlo_…" \
-H "Content-Type: application/json" \
-d '{"external_id":"user_123","reason":"first_sale"}'{
"ok": true,
"enrollment_id": "8f7e6d5c-4b3a-4c2d-9e1f-0a9b8c7d6e5f",
"external_id": "user_123",
"status": "stopped",
"changed": true
}Resultados das ligações nos webhooks
call.started e call.completed de ligações de uma sequência trazem callback_id, external_id e outreach { sequence_id, enrollment_id, external_id, step } (todos null em ligações recebidas). Tentativas sem resposta não criam uma ligação, então não há call.completed para elas: após a última tentativa você recebe outbound_call.finished com status failed e last_error no_answer. As novas tentativas de uma etapa contam como um único resultado. call.completed inclui também caller_spoke e caller_words (quantas palavras a pessoa disse). Se alguém atendeu e desligou durante a saudação ou logo a seguir sem dizer nada, end_reason é caller_hangup_greeting. Se a pessoa ligar de volta para o número da empresa até 3 dias após a nossa tentativa, a chamada recebida tem callback_return: true e os mesmos callback_id, external_id e outreach da chamada a que está a responder. As chamadas do widget do site têm direction widget, page_url e page_title (página da chamada) e continued_from (parte anterior após recarregar a página); um teste no navegador a partir do painel é direction web. Cada pedido ao seu servidor MCP durante uma chamada leva o cabeçalho Voxiora-Call-Id (igual ao id da chamada), Voxiora-Caller em chamadas telefónicas e Voxiora-Outreach-External-Id em chamadas de sequência ou da API.
{
"id": "5b1f0c6e-2a8d-4f3e-9d51-7c0a4e2b9f10",
"object": "call",
"assistant_id": "0e6f4c8a-3b2d-4a1e-8f7c-5d9b2a1c3e4f",
"phone_number_id": "4d3c2b1a-0f9e-4d8c-b7a6-958473625140",
"contact_id": "9a8b7c6d-5e4f-4a3b-2c1d-0e9f8a7b6c5d",
"direction": "outbound",
"status": "completed",
"from": "+48732127980",
"to": "+48601234567",
"started_at": "2026-10-01T09:14:03Z",
"ended_at": "2026-10-01T09:17:41Z",
"duration_sec": 218,
"summary": "Jan added the company name and tax ID; asked for a call tomorrow at 10:00 about payments.",
"outcome": "message",
"sentiment": "positive",
"tags": [],
"has_recording": true,
"end_reason": "agent_hangup",
"page_url": null,
"page_title": null,
"continued_from": null,
"callback_id": "0f1e2d3c-4b5a-4968-8776-655443322110",
"external_id": "gapli-evt-1842",
"outreach": {
"sequence_id": "11111111-1111-4111-8111-111111111111",
"enrollment_id": "8f7e6d5c-4b3a-4c2d-9e1f-0a9b8c7d6e5f",
"external_id": "gapli-evt-1842",
"step": 1
},
"callback_return": false,
"caller_spoke": true,
"caller_words": 112
}Agenda, CRM e automação
Integrações prontas, sem código
Google Agenda
O assistente verifica a disponibilidade real e marca, remarca e cancela agendamentos na sua agenda. Lê apenas os horários ocupados, nunca os títulos dos eventos.
HubSpot
Cada chamada é registrada no contato, agendamentos viram reuniões e pedidos de retorno viram tarefas. Opcionalmente cria contatos e negócios.
Pipedrive
Chamadas como atividades ou notas, agendamentos como reuniões, retornos como atividades. Opcionalmente cria pessoas, negócios ou leads.
Zapier, Make e n8n
Guias passo a passo no painel. Funcionam com webhooks e a API, incluídos em todos os planos.
Planos e limites
De qual plano você precisa
Limites por conta: requisições por minuto (também por chave, janela deslizante) e por dia (UTC). Acima do limite você recebe 429 rate_limited com o cabeçalho Retry-After.
Widget de voz para o site: a partir do plano Business.
Precisa de limites maiores? Fale com a gente e podemos aumentá-los para a sua conta.
Comece hoje
Pronto para conectar?
Comece o teste grátis, crie uma chave de API de teste e envie sua primeira requisição em minutos. A API está incluída em todos os planos, a partir do Essential.