Para desenvolvedores
Conecte o Telofia 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 Line; 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://telofia.com/api/v1curl https://telofia.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 Telofia 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 Office
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://telofia.com/api/v1/me \
-H "Authorization: Bearer tf_live_…"const API = "https://telofia.com/api/v1";
const headers = { Authorization: `Bearer ${process.env.TELOFIA_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é 20.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
Telofia-SignatureAssinatura: t=<tempo unix>,v1=<HMAC-SHA256 hex>Telofia-EventTipo de evento, ex.: appointment.bookedTelofia-DeliveryID única da entregaUser-AgentTelofia-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",
"callback_id": null,
"external_id": null,
"outreach": null,
"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 Telofia-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) {
// Telofia-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("/telofia/webhook", express.raw({ type: "application/json" }), (req, res) => {
const raw = req.body.toString("utf8");
if (!verify(raw, req.get("Telofia-Signature") ?? "", process.env.TELOFIA_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.
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 Office
- Cerca de 14 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://telofia.com/widget.js" data-key="tfw_…" async></script>// optional: open the widget from your own button
document.querySelector("#talk-to-us").addEventListener("click", () => window.TelofiaWidget?.open());
window.TelofiaWidget?.close(); // close the panel
window.TelofiaWidget?.destroy(); // remove the widget from the pageTem uma Content Security Policy rígida? Permita script-src https://telofia.com https://cdn.jsdelivr.net, connect-src https://telofia.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 TelofiaWidget.identify({ token }) a qualquer momento; uma chamada posterior substitui o token e identify(null) apaga-o. Antes de o widget.js carregar, defina window.TelofiaIdentity = { token, expires_at }: é lido quando a conversa começa e um token expirado é ignorado.
- No painel, escolha o argumento do token de identidade na sua ferramenta MCP «No início da chamada». A Telofia 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/telofia-identity").then((r) => r.json());
window.TelofiaIdentity = { token, expires_at }; // read when the conversation starts, also before widget.js loads
window.TelofiaWidget?.identify({ token, expires_at }); // replaces the token at any time
// refresh before it expires (e.g. every 10 minutes); on sign-out:
window.TelofiaIdentity = null;
window.TelofiaWidget?.identify(null);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-Telofia-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://telofia.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}, Telofia (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://telofia.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.
{
"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",
"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
},
"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 Office.
Precisa de limites maiores? Fale com a gente e podemos aumentá-los para a sua conta.
Acesso antecipado: seja uma das primeiras empresas a deixar a IA atender o telefone.
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 Line.