Seggest API de Parceiros
Documentação

API do Seggest

Referência da superfície de dados da plataforma: o que existe, em que aba é usado, e como um sistema parceiro consome isso de fora.

25
Abas
106
Tabelas e views
60
Funções (RPC)
36
Edge Functions
490.289
Registros

O catálogo cobre os módulos operacionais do Seggest — comercial, cadastro, financeiro, relacionamento e atendimento. Módulos de administração interna do Grupo VSX não constam aqui.

Só a seção “Endpoints da API” é acessível de fora, e apenas nos recursos liberados para a sua chave. O restante existe para dar contexto do que a plataforma cobre.

A API está no ar. Sem chave ela responde “não autenticado”; com chave e sem escopo, “sem acesso” — os dois são esperados até a liberação ser combinada.

Levantado direto do banco de produção e do código publicado, não de documentação anterior. Volumes refletem a leitura de 26/07/2026.

Fundamentos

Como o Seggest expõe dados

Não existe uma camada de aplicação entre o navegador e o banco. O front-end fala direto com o PostgreSQL por quatro caminhos, e é isso que a expressão “endpoint do Seggest” significa na prática.

1. Tabelas e views

Cada tabela vira um endpoint REST automaticamente, via PostgREST. Quem decide o que cada pessoa enxerga é o Row Level Security do próprio banco — não o código do front-end.

2. Funções (RPC)

Rotinas em SQL chamadas por POST /rest/v1/rpc/<nome>. Concentram o que não cabe em uma consulta: cálculo de comissão, fechamento mensal, motores de repasse.

3. Edge Functions

Código Deno para o que precisa de rede ou segredo: envio de e-mail, WhatsApp, leitura de PDF, webhooks de terceiros.

4. Storage

Arquivos em buckets — documentos de apólice, anexos de tarefa, fotos. Todos privados, exceto os de identidade visual.

Por que o parceiro não recebe isso direto. Expor o PostgREST a um terceiro significaria confiar o isolamento entre corretoras inteiramente ao RLS de centenas de tabelas. A API de parceiros reduz essa superfície a uma porta só, com escopo explícito e registro de tudo.
Acesso

Autenticação

Toda chamada exige uma chave de API no cabeçalho Authorization. A chave é emitida pelo Grupo VSX, pertence a um parceiro específico e carrega três coisas: a corretora que ela enxerga, os recursos liberados e o limite de requisições por minuto.

Guarde a chave no ato

O Seggest guarda apenas o hash SHA-256 da chave. Ela aparece em texto claro uma única vez, no momento da criação. Se for perdida, o caminho é revogar e emitir outra — não há recuperação.

O que a chave não alcança

O corretora_id da chave é aplicado pelo gateway em toda consulta, depois dos filtros que você enviou. Não há parâmetro que remova esse filtro. Recursos sem coluna de corretora são recusados por padrão, porque neles não haveria como garantir o isolamento.

Revogação

A revogação tem efeito na chamada seguinte, sem propagação nem cache. Chaves podem também ter data de validade e uma lista de IPs autorizados.

Convenções

Paginação, filtros e erros

Paginação

São 50 registros por página, no máximo 500. A resposta traz paginacao.proxima_pagina com a URL pronta da página seguinte, ou null quando acabou — percorrer a lista é seguir esse campo até ele ser nulo.

Filtros

A sintaxe é a do PostgREST: ?status=eq.ativo, ?created_at=gte.2026-01-01, ?nome=ilike.*silva*. Operadores: eq, neq, gt, gte, lt, lte, like, ilike, in, is. Só é possível filtrar e ordenar por colunas liberadas para a sua chave — o resto responde 400 dizendo quais são.

Erros

Todo erro tem o mesmo formato: codigo estável para o seu código tratar, mensagem em português para a pessoa ler e, quando ajuda, dica com o próximo passo.

Limite de requisições

O padrão é 120 por minuto, por chave, em janela deslizante. Ao estourar, a resposta é 429 e o pedido não é processado. Para carga maior, o limite é ajustável por chave.

Referência

Endpoints da API

Base: https://api.seggest.com.br/functions/v1/parceiro-api

GET /v1/_recursos

Devolve o que a sua chave alcança: recursos, permissão de cada um e colunas visíveis. É o ponto de partida de qualquer integração, e o jeito de descobrir mudanças de escopo sem precisar perguntar.

GET /v1/<recurso>

Lista registros com filtros e paginação. <recurso> é o nome que aparece em /v1/_recursos.

GET /v1/<recurso>/<id>

Busca um registro pelo identificador.

POST, PATCH e DELETE

Disponíveis apenas em recursos cuja permissão é escrita. Campos fora da lista liberada são descartados; id e corretora_id nunca vêm do corpo da requisição — o gateway os carimba. Outros verbos, como PUT, respondem 405.

GET /health

Sonda de disponibilidade. Não exige chave.

Recursos que a API pode expor

A API entrega dado de negócio. Configuração, integração, permissão, regra de comissão e motor de automação não saem por ela, mesmo com escopo criado por engano. Os recursos possíveis são estes 25:

ÁreaRecursos
Cadastro clientes cliente_documentos
Ciclo de venda cotacoes propostas proposta_vendedores
Contratos apolices apolice_vidas apolice_vendedores apolice_documentos
Comercial negociacoes
Financeiro comissoes_a_receber parcelas_cliente parcelamentos pagamentos_unicos baixas_recebimento financeiro_lancamentos
Sinistro sinistros sinistro_tipos sinistro_eventos sinistro_documentos
Catálogo operadoras produtos tipos_produto categorias_produto
Operação tarefas

O que a sua chave alcança é um subconjunto disso, definido caso a caso — consulte /v1/_recursos. Precisando de algo que está na tabela acima mas não na sua chave, é só pedir: liberar é configuração, sai no mesmo dia.

Uma consulta por recurso

Não é possível trazer tabelas relacionadas na mesma chamada. Um select com cliente:clientes(nome) responde 400. Consulte cada recurso separadamente e junte os dados do seu lado — é a forma de garantir que o recorte por corretora valha para tudo que sai daqui, sem exceção.

A especificação OpenAPI 3.1 acompanha esta documentação e pode ser importada direto no Postman, Insomnia ou em um gerador de cliente.

Referência

Edge Functions

As funções de borda dos módulos operacionais. Nenhuma faz parte da API de parceiros — estão aqui porque compõem a superfície de rede da plataforma. A coluna de acesso descreve o tipo de integração de cada uma.

Função e abaAcessoO que fazEntrada
analisar-conversa-ia
CRM (NegociacaoPanel, WhatsAppChatDrawer), Atendimento (PersistentAtendeSEG), Cadastro (OportunidadesIATab), Configurações › Integrações (botão de teste)
Chamada pública Analisa conversa de WhatsApp / negociação / perfil do cliente com Claude (Anthropic, tool calling estruturado) e devolve prioridade, score, sentimento, produtos de interesse, script sugerido e próximo passo. Grava o resultado em crm_ia_analises, atualiza prioridade+justificativa em crm_conversas_whatsapp e cria notificação para o atendente quando a prioridade sai 'alta'. Modo 'oportunidades' sugere 3 produtos novos para o cliente. JSON. Modos: {teste:true} (só checa se ANTHROPIC_API_KEY existe); {modo:'oportunidades', contexto_cliente:{cliente, produtos_ja_contratados[], produtos_disponiveis[], regras_vigentes[], scores_atuais[]}}; {modo:'resumo', mensagens:[{direcao,conteudo,enviado_em}], conversa_id?, cliente_id?}; {modo:'negociacao', negociacao_titulo, negociacao_valor, negociacao_etapa, negociacao_prioridade, qtd_tarefas, qtd_mensagens, produtos_ativos, cliente_id?, conversa_id?}; padrão {conversa_id (obrigatório), cliente_id?} — busca as últimas 30 mensagens em crm_mensagens_whatsapp.
atendeseg-ai-summary
CRM (NegociacaoPanel — botão de resumo IA no card), Cadastro (ClientePerfilModal → WhatsAppChatDrawer)
Chamada pública Gera resumo do atendimento do cliente no AtendeSeg. Modo 'escopo' (quando vem negociacao_id): filtra os tickets pelo corretor da negociação (profiles.atendeseg_user_id) e pela data de criação do card, baixa até 300 mensagens e resume com Claude Haiku, com cache de 60 min em atendeseg_ai_cache. Modo 'historico' (padrão): chama o endpoint nativo /contacts/{id}/ai-summary do AtendeSeg. {cliente_id (obrigatório), negociacao_id? (ativa o modo escopo), user_id? (chave do cache)}
atendeseg-auth-refresh
Configurações › Integrações (AtendeSeg) para o modo 'configurar', na prática o modo cron roda por pg_cron (*/30 min, migration 20260609154000_motor_v2_cron.sql) — não há chamador no frontend hoje
Rotina agendada Mantém vivo o JWT da API do AtendeSeg guardado em config_atendeseg.api_token (sem ele, disparo-campanha, atendeseg-send e o motor-automacao param de enviar). Valida o token atual, e se voltar 401/403 faz POST /auth/login com as credenciais cifradas e grava o token novo. Registra falha em config_atendeseg.refresh_erro e notifica os Administradores ativos (só na primeira falha, pra não spammar o cron). O modo 'configurar' grava admin_email/admin_senha_enc. {} (cron: valida e renova se preciso) | {forcar:true} (renova mesmo com token aparentemente válido) | {modo:'configurar', email, senha}
atendeseg-import-history
Atendimento / CRM (histórico das conversas de WhatsApp) — sem chamador no frontend atual
Chamada pública Recupera o histórico completo de mensagens de um ticket do AtendeSeg (API interna /messages/{ticket}, até 30 páginas) e grava em crm_mensagens_whatsapp com upsert por atendeseg_msg_id (re-execução não duplica). Se a conversa não tiver atendeseg_contato_id, busca no detalhe do ticket e corrige o registro. {conversa_id} (UUID de crm_conversas_whatsapp; a conversa precisa ter atendeseg_conversa_id)
atendeseg-recursos
Relacionamento › editor de automações (PickerRecurso, VariaveisTemplateEditor), Central de Disparos
Sessão do usuário Proxy só-leitura da API externa do AtendeSeg para popular dropdowns do app (usuários, templates WABA, chat-flows/bots, produtos, etapas do funil, tags) sem expor o api_token no browser. Normaliza cada envelope diferente da API para [{id, nome, extra}] e mantém cache em memória do isolate por (apiId, recurso) com TTL de 120s. {recurso:'users'|'templates'|'chat-flows'|'products'|'pipeline-steps'|'tags', refresh?:boolean (ignora o cache)}
atendeseg-send
Atendimento / CRM (chat de WhatsApp dentro do card) — sem chamador no frontend atual
Chamada pública Envia uma mensagem de texto no ticket do AtendeSeg a partir de uma conversa do CRM (POST /v1/api/external/{token}/messages, com fallback para /ticket/{id}/messages) e, quando dá certo, registra a mensagem enviada em crm_mensagens_whatsapp e atualiza ultima_mensagem_em na conversa. {conversa_id, mensagem, usuario_id?} — usuario_id é desestruturado do body mas NUNCA é usado
atendeseg-webhook
Configurações › Integrações (URL do webhook + botão 'Testar conexão'), alimenta as abas Atendimento, CRM
Webhook de terceiro Recebe os eventos do AtendeSeg (NewMessage, TicketFinished/FinishedTicketHistoricMessages, UpdateContact/NewContact), canonicaliza o telefone para +55DDD9N, casa o cliente pelos últimos 8 dígitos (clientes + cliente_telefones), resolve a negociação (funil SDR → qualquer funil), cria/atualiza a conversa e grava/edita a mensagem (texto ou mídia). Cria card 'orgânico' no funil SDR quando é inbound espontâneo no canal 284 sem atendente humano. Roda 4 detectores determinísticos sobre o texto: OPT-OUT (recuperacao_optout + move p/ Lead Descartado), TRANSFERÊNCIA/qualificação (recuperacao_setor + move p/ Lead Reaquecido), AGENDAMENTO de renovação (recuperacao_data_renovacao + setor='seguros') e VIGÊNCIA vinda do campo customizado do contato. JSON do AtendeSeg: {event, message:{id, body|caption|text, fromMe, mediaType, mediaUrl, quotedMsgId, msgCreatedAt, ticket:{id, userId, whatsappId, contact:{id, number, name|pushname}}}}. Variantes: {messages:[...]} ou {historico:[...]} nos eventos de finalização; {contact:{id, number, customFields:{'vigência'}}} em UpdateContact/NewContact; {teste_conexao:true, api_token} para o botão de teste.
cadastro-produtor
Formulário público /cadastro-parceiro (public/cadastro-parceiro.html), a fila de aprovação fica em Configurações › Parceiros Pendentes (ParceirosPendentes / useParceirosCadastro)
Chamada pública Recebe o formulário público de cadastro de parceiro/produtor, sobe os anexos (base64) no bucket privado produtores-anexos, grava a inscrição em produtores_cadastro com status 'pendente' e protocolo gerado no servidor, e notifica os admins. NÃO toca em `vendedores` — isso só acontece quando um admin confirma, via fn_confirmar_produtor. {dados:{tipo_pessoa:'PF'|'PJ', nome|razao_social, documento (CPF/CNPJ), email?, telefone?, aceite_estorno:'Sim', aceite_declaracoes:'Sim', assinatura, termos_versao?, aceite_em?, autoriza_posvenda?,...demais campos livres}, arquivos:{<chave>:{name, type, base64 — aceita data URL}}}
calendario-agendar-reuniao
Calendário (AgendarReuniaoModal via hook useAgendarReuniao)
Sessão do usuário {convidadoIds:string[] (UUIDs de profiles), titulo, inicio (ISO), fim (ISO), descricao?, local?, comMeet?:boolean=true}
calendario-disponibilidade
Calendário (AgendarReuniaoModal via hook useAgendarReuniao)
Chamada pública Devolve os blocos ocupado/livre de VÁRIAS pessoas para montar a grade de horários da reunião: junta os eventos do Google (todas as contas conectadas da pessoa, via events.list com fields=items(start,end,status,transparency) — só início/fim, nunca títulos) com os eventos internos do Seggest (criados por ela ou com participação 'aceito'), e mescla os blocos sobrepostos. {usuarioIds:string[], inicio (ISO), fim (ISO)}
calendario-oauth-start
Calendário › Sincronização externa (SincronizacaoExterna via hook useCalendarioSync)
Retorno OAuth Inicia o fluxo OAuth de conexão de calendário externo: valida o provider, confere se as credenciais estão configuradas na plataforma e devolve a URL de consentimento do Google/Microsoft para o frontend redirecionar o navegador. O callback é tratado por outras functions (google-calendar-callback / outlook-calendar-callback). Query string: ?provider=google|microsoft&origin=<origem que iniciou> (o origin também pode vir do header Origin). Header Authorization com o JWT do usuário.
calendario-push-evento
Calendário (hook useEventos — disparado fire-and-forget logo após salvar a edição do evento)
Sessão do usuário Propaga a EDIÇÃO de um evento do Seggest para o provedor externo (PATCH no Google Calendar com sendUpdates=all, ou PATCH no Microsoft Graph), quando o evento já tem external_id + conexao_id. Renova o access_token da conexão se faltar menos de 2 min. Atualiza eventos.ultima_sync. {eventoId} (UUID de eventos)
calendario-sync
Calendário › Sincronização externa (botão 'Sincronizar agora' — SincronizacaoExterna / useCalendarioSync)
Rotina agendada Motor de sincronização bidirecional do Calendário (Google Calendar + Microsoft Graph) numa janela de -30d a +180d: PULL (eventos externos → tabela eventos, com dedup por external_id/ical_uid e delete quando o externo é cancelado) e PUSH (eventos com fonte='seggest' no calendário mapeado → provedor externo), respeitando calendario_conexoes.direcao (push/pull/bidirecional). Renova tokens e grava ultima_sync/ultimo_erro. {} (cron: todas as conexões ativas) | {conexao_id} | {usuario_id} — esses dois só têm efeito quando NÃO há JWT de usuário no header
cron-comissoes-vencidas
Financeiro › Comissões (sem UI — job de pg_cron, nenhuma chamada em src/)
Rotina agendada Job agendado que chama a RPC motor_marcar_comissoes_vencidas() para marcar comissões cujo vencimento passou. Nenhum payload (o body é ignorado).
cron-lembretes-eventos
Calendário (sem UI — pg_cron job 'lembretes-eventos-5min', */5 * * * *)
Rotina agendada Despachar lembretes de eventos do Calendário: varre eventos com lembrete_minutos preenchido, não recorrentes (recorrencia is null), ainda não avisados (lembrete_enviado_em is null) e com inicio no futuro; quando agora >= inicio - lembrete_minutos, insere linhas em notificacoes para o criador + participantes com status 'aceito' (evento_participantes) e marca eventos.lembrete_enviado_em (dedupe idempotente). Recorrência é TODO. Nenhum payload.
disparo-atendeseg-status
Central de Disparos › Configuração (a URL do webhook é exibida em ConfiguracaoTab.tsx:137)
Chamada pública Webhook público de STATUS do AtendeSeg (hookMessageStatus / urlMessageStatus da credencial de API). Casa o ack pelo externalKey (= id da linha em disparo_destinatarios, setado no envio) e atualiza status/entregue_em/lido_em/erro + grava a trilha em disparo_eventos. Mapeamento do ack (whatsapp-web.js): -1 = falha, 1 = enviado (sem ação, evita ruído), 2 = entregue (não rebaixa quem já está 'lido'), 3/4 = lido/played. POST JSON — um objeto ou um array de: { type?: 'hookMessageStatus', ack: number, messageId?: string, externalKey: string (id do disparo_destinatarios), status?, error? }. Eventos com type diferente de hookMessageStatus ou sem externalKey são ignorados.
disparo-campanha
Central de Disparos (hooks/useDisparos.ts — preparar, enviar, enrolar, sincronizar, listar templates, submeter template)
Sessão do usuário Orquestrador único do ciclo de vida da campanha da Central de Disparos. Modos: 'preparar' (resolve o público a partir de campanha.segmento — lista via disparo_lista_contatos ou segmento sobre clientes ativos filtrando tipo_cadastro/origem —, aplica disparo_supressao e materializa 1 linha por campanha×canal×destino em disparo_destinatarios, com suporte a modo_canal 'ambos' vs 'fallback' criando linhas 'reserva'); 'enviar' (pré-voo de prontidão dos canais, lote de pendentes com backoff, e-mail via Resend e WhatsApp via Graph API v21.0 ou via API externa do AtendeSeg, retry com backoff 60/300/900/1800s, auto-pausa por % de falha com notificação ao criador, fallback de canal, conclusão da campanha); 'enrolar' (adiciona UM contato vindo de automação e dispara na hora, idempotente por campanha+canal+destino); 'sincronizar' (pull de reconciliação dos acks no AtendeSeg); 'listar-templates-atendeseg'; 'template' (submete HSM à Meta em /{waba_id}/message_templates e grava meta_template_id/nome). POST JSON: { modo: 'preparar'|'enviar'|'enrolar'|'sincronizar'|'listar-templates-atendeseg'|'template', campanha_id?, template_id?, limite? (padrão 50, teto 200 no enviar; 300/1000 no sincronizar), contato?: { cliente_id?, nome?, email?, telefone?, variaveis?, origem_automacao_id? } }. No modo 'enviar' campanha_id é OPCIONAL — sem ele, varre todas as campanhas 'agendada'/'enviando' devidas.
disparo-dominio
Central de Disparos › Configuração (domínios de e-mail — useDisparos.ts:499)
Sessão do usuário Onboarding self-service de domínio de e-mail na Central de Disparos, integrando com a API de Domínios do Resend (conta única do Seggest, região sa-east-1) — cada corretora registra e verifica o próprio domínio por baixo dessa conta e cadastra os remetentes autorizados. POST JSON: { acao: 'add' | 'verificar' | 'listar' | 'remetentes', dominio? (regex /^(?:[a-z0-9-]+\.)+[a-z]{2,}$/i, obrigatório no add), dominio_id? (uuid local, obrigatório em verificar/remetentes), remetentes?: [{ email, nome? }] (array não-vazio; cada email deve terminar em @<dominio>) }.
disparo-track
Central de Disparos (KPIs de abertura/clique/descadastro das campanhas de e-mail)
Rastreamento de e-mail Tracking de e-mail da Central de Disparos: /open serve um GIF 1x1 e registra a PRIMEIRA abertura (sobe status para 'aberto' se estava enviado/entregue + evento 'aberto'); /click registra o clique (evento por clique, sobe status para 'clicou', preenche aberto_em) e redireciona; /unsubscribe marca 'descadastrou', grava evento e insere em disparo_supressao (upsert com onConflict corretora_id,canal,destino), devolvendo uma página HTML de confirmação em pt-BR. Erros de banco nunca bloqueiam a resposta ao usuário final. Querystring: t=<tracking_token> (todas as rotas) e u=<url destino urlencoded> (apenas /click). Header user-agent é gravado em disparo_eventos.dados.
disparo-webhook
Central de Disparos (webhook da Meta, citado em ConfiguracaoTab.tsx:547)
Webhook de terceiro Webhook público da Meta (WhatsApp Cloud API / Graph) para a Central de Disparos. Trata: (A) recibos de status statuses[] — sent (só log) / delivered / read / failed → atualiza disparo_destinatarios (sem rebaixar 'lido' para 'entregue') e grava disparo_eventos; (B) mensagens recebidas messages[] do tipo texto com palavra-chave de opt-out (ehOptout: SAIR/PARAR/STOP/...) → insere em disparo_supressao (motivo 'keyword') e marca o destinatário mais recente como 'descadastrou'; (C) field 'message_template_status_update' → APPROVED/REJECTED/PENDING atualiza status e motivo_rejeicao em disparo_templates. A corretora é resolvida por value.metadata.phone_number_id → whatsapp_config (com cache local por request). GET: ?hub.mode=subscribe&hub.verify_token=<token>&hub.challenge=<challenge>. POST: payload Graph { entry: [{ changes: [{ field, value: { metadata: { phone_number_id }, statuses: [...], messages: [...] } }] }] } ou { field:'message_template_status_update', value:{ message_template_id, message_template_name, event, reason } }.
email-account-save
Email (pages/Email.tsx), Configurações › Contas de Email (ContasEmailTab.tsx)
Sessão do usuário Criar/atualizar a conta de e-mail (SMTP/IMAP) do módulo Email. Self-service: cada usuário salva a sua. Administrador pode salvar para outro via owner_profile_id. A senha da caixa é cifrada com AES-GCM (_shared/crypto.ts, chave EMAIL_CRED_KEY) e gravada na tabela isolada email_account_secrets — o browser nunca lê a senha de volta. Update é PARCIAL (só altera os campos presentes no body). POST JSON: { id? (update), email (obrigatório na criação), senha (obrigatória na criação; opcional no update — se vier, re-cifra), display_name?, owner_profile_id? (só admin), tipo?: 'pessoal'|'compartilhada', smtp_host?, smtp_port? (default 465), smtp_secure? (default true), smtp_user?, imap_host?, imap_port? (default 993), imap_secure? (default true), imap_user?, ativo?, assinatura?, reply_to? }.
email-account-test
Email (pages/Email.tsx), Configurações › Contas de Email (ContasEmailTab.tsx)
Sessão do usuário Testar a conexão SMTP + IMAP de uma conta de e-mail. Dois modos: { account_id } carrega a conta e decifra a senha de email_account_secrets, e grava o resultado em email_accounts.last_test_ok / last_test_em / last_test_erro; { creds } testa credenciais cruas antes de salvar. Usa probeSmtp/probeImap de _shared/mailer.ts. POST JSON — um dos dois: { account_id: uuid } OU { creds: { email, senha (obrigatória), smtp_host, smtp_port (465), smtp_secure (true), smtp_user, imap_host, imap_port (993), imap_secure (true), imap_user } }.
email-imap
Email (pages/Email.tsx — leitura da caixa, busca, pastas, anexos, rascunhos)
Sessão do usuário Cliente IMAP da caixa do próprio usuário (estilo Outlook) via imapflow. O corpo é extraído baixando só a parte text/html|plain da bodyStructure e decodificando manualmente base64/quoted-printable (sem mailparser, que estoura a CPU do edge runtime), com fallback de charset utf-8 estrito → iso-8859-1/windows-1252 e inline de imagens cid: (até 8, máx ~800 KB cada) convertidas em data: URI. POST JSON: { action, account_id (obrigatório), folder? (default INBOX), uid?, page?, pageSize? (1-100, default 30), flag?, value?, dest?, query?, part?, to?, cc?, bcc?, subject?, html?, text? }. Ações: list_folders | list_messages | get_message | mark_seen | mark_unseen | set_flag | move | delete_message | search | download_attachment | save_draft.
email-send
Email (pages/Email.tsx), CRM › card do cliente, botão ✉️ (components/crm/EnviarEmailModal.tsx)
Sessão do usuário Enviar e-mail por SMTP a partir da caixa do próprio usuário (nodemailer), com suporte a resposta/encaminhamento (inReplyTo/references), anexos e prioridade. Define o HELO/EHLO com o domínio real do remetente (sem isso o edge-runtime anuncia EHLO [127.0.0.1] e a HostGator bloqueia a entrega silenciosamente). Depois do envio, arquiva uma cópia MIME na pasta Enviados via IMAP append (best-effort — detecta a pasta por specialUse \Sent, fallback INBOX.Sent). POST JSON: { account_id (obrigatório), to (obrigatório, string ou array), cc?, bcc?, subject?, text?, html?, inReplyTo?, references?, attachments?: [{ filename, base64, contentType }], priority?: 'high'|'low' }.
extrair-dados-pdf
Plataforma
Chamada pública STUB temporário. A extração de dados de PDF por IA dependia do Lovable AI Gateway, que não existe no Supabase self-hosted; a função apenas loga a invocação e devolve 503. O TODO no arquivo prevê substituir por chamada direta a OpenAI/Google AI. Ignorada (o body nem é lido).
extrair-documento-seguros
Cadastro › Importar PDF (ImportPDFModal.tsx / ImportPDFBatchModal.tsx via hooks/useExtrairPDF.ts)
Sessão do usuário Extrair dados estruturados de PDF do mercado segurador chamando a Anthropic Messages API (modelo claude-sonnet-4-6) com vision nativa de PDF, structured output forçado por tool_use + tool_choice e prompt caching (cache_control ephemeral no system, que cacheia também as tools). Bifurca o JSON Schema entre Seguros Gerais (proposta/apólice: cliente, bem segurado, coberturas, pagamento, comissão, renovação) e Saúde (contrato: contratante, produto ANS, vidas, financeiro, carências). Consolida campos_faltantes da IA com uma checagem server-side de campos críticos. Toda a operação passa por executarOperacaoIA (_shared/credits.ts → RPCs fn_iniciar_operacao_ia / fn_finalizar_operacao_ia): idempotência, débito de créditos e estorno automático em falha. Header Idempotency-Key (ou body.idempotency_key), mínimo 16 caracteres — OBRIGATÓRIO. POST JSON: { pdf_base64 (aceita com ou sem o prefixo data:application/pdf;base64,; máx 10 MB decodificados), nome_arquivo, tipo_documento: 'proposta'|'apolice'|'contrato', ramo_hint? }.
google-calendar-callback
Calendário (retorno do fluxo iniciado em calendario-oauth-start)
Retorno OAuth Callback OAuth do Google Calendar (a redirect URI registrada no Google Cloud DEVE ser https://<edge>/functions/v1/google-calendar-callback). Troca o `code` por tokens (exchangeCode), descobre o e-mail da conta conectada (getContaEmail), resolve a corretora do usuário em profiles e faz upsert em calendario_conexoes (onConflict usuario_id,provider,conta_email) com access_token, refresh_token, token_expira, scope, external_calendar_id='primary', sync_ativo=true. Querystring do Google: ?code=<authorization_code>&state=<payload.assinatura> — ou ?error=<motivo> quando o usuário nega o consentimento.
lead-webhook
Configurações › Campanhas (CampanhasCard.tsx, CampanhaFormDialog.tsx montam a URL `${SUPABASE_URL}/functions/v1/lead-webhook?token=...`), logs no LeadWebhookLogsDialog / hook useLeadWebhookLogs. Os leads caem no CRM (Gestão de Leads / Negociações).
Webhook de terceiro Endpoint público para formulários de site criarem leads no CRM. Acha a campanha pelo token, aplica rate limit por IP, valida payload mínimo (nome) e chama a RPC fn_criar_lead, que cria/reaproveita o cliente, cria a negociação, resolve produto, faz round-robin de consultor e notifica. Toda tentativa (sucesso ou falha) vai para lead_webhook_log. POST /functions/v1/lead-webhook?token=<webhook_token> com JSON { nome | name (obrigatório), email?, telefone | phone?, cpf_cnpj | cpf?,...campos livres }. O payload inteiro é repassado a fn_criar_lead e gravado no log.
meta-leads-webhook
CRM / Gestão de Leads (entrada de leads de anúncios Meta), a configuração fica em config_meta_ads, as campanhas em Configurações › Campanhas (campo meta_form_id).
Webhook de terceiro Recepção nativa de leads do Meta Lead Ads (substitui o Bitrix). Para cada change do tipo 'leadgen': deduplica por negociacoes.external_id, acha a campanha por crm_campanhas.meta_form_id (ativa), busca os field_data do lead na Graph API v21.0 com o page token, normaliza nome/e-mail/telefone (BR, tira +55) e chama fn_criar_lead — que cria cliente, card, faz round-robin e notifica. GET: query hub.mode=subscribe, hub.verify_token, hub.challenge. POST: payload padrão da Meta { entry: [ { id, changes: [ { field:'leadgen', value:{ leadgen_id, form_id, page_id } } ] } ] } + header x-hub-signature-256.
meta-spend-sync
Backend/cron — alimenta meta_ad_insights (CPL/CAC/ROI de Marketing). Na main não encontrei nenhuma tela consumindo meta_ad_insights fora de src/integrations/supabase/types.ts, ou seja, hoje é dado sem UI.
Rotina agendada Sincroniza o gasto de anúncios do Meta Ads (level=campaign, time_increment=1) para public.meta_ad_insights, com retry/backoff em rate limit da Graph API. Percorre todas as ad accounts acessíveis pelo token, pagina os insights do período e faz upsert em lotes de 200 por (corretora_id, meta_campaign_id, dia). Agendada por pg_cron ('meta-spend-sync-diario', 0 5 * * *, migration 20260606140000). JSON { meta_token?: string (senão cai no env META_PAGE_ACCESS_TOKEN), corretora_id?: uuid (default hardcoded a091d013-fcb4-4b07-a5bb-3e6bf23c203f = VSX), dias?: number (default 7) }.
motor-automacao
Relacionamento › editor de automações (TestarAutomacaoDialog + hook useTestarAutomacao chamam { modo:'testar' }), em produção roda majoritariamente por pg_cron.
Rotina agendada Executor v2/v3 do motor de automação do Relacionamento. Lê regras de rel_automacoes + rel_automacao_acoes (+ rel_automacao_arestas no modo grafo), casa com eventos de rel_eventos, avalia condições de gatilho e por ação, e executa: chamadas HTTP (AtendeSeg/WhatsApp), envio de e-mail, db_update, db_insert, criar_tarefa (com observadores via fn_add_tarefa_observador), criar_negociacao (túnel entre funis) e disparo_enrolar. Respeita dry_run, idempotência por evento+ação e por janela de horas, e registra tudo em rel_disparos. JSON, variando pelo modo: { modo:'drain', limite?:number (máx 100, default 25) } — claim atômico via RPC rel_claim_eventos; { modo:'agendado', forcar_envio:true } — varredura legada (sem forcar retorna 'pulado'); { modo:'evento', evento_id:uuid }; { modo:'testar', automacao_id:uuid, negociacao_id|entidade_id:uuid, payload?:{} } — sempre simula, nada é gravado; { tipo:'negociacao_criada', negociacao_id:uuid, corretora_id?, payload? } — execução sob demanda sem fila. A flag global forcar_envio:true IGNORA o dry_run e executa de verdade.
outlook-calendar-callback
Calendário (conexão de calendário externo Outlook/Microsoft, par do calendario-oauth-start, do google-calendar-callback).
Retorno OAuth Callback OAuth da Microsoft/Outlook: troca o `code` por tokens, descobre o e-mail da conta, e faz upsert em calendario_conexoes (usuario_id, corretora_id herdada de profiles, access_token, refresh_token, token_expira, scope, external_calendar_id='primary', sync_ativo=true), redirecionando o usuário de volta para /calendario. O fluxo é iniciado pela edge calendario-oauth-start, que exige JWT e assina o state. Query string do provedor: ?code=<authorization_code>&state=<payload.assinatura>, ou ?error=<erro_oauth>. A redirect URI registrada no Azure precisa ser https://<edge>/functions/v1/outlook-calendar-callback.
send-push
Chat interno do Seggest (notificações push do navegador, tabelas chat_mensagens, chat_participantes, chat_conversas, push_subscriptions).
Chamada pública Envia Web Push (npm:web-push) da mensagem nova do chat interno para todos os participantes da conversa, exceto o remetente e os que silenciaram. Monta título (nome do grupo ou do remetente) e prévia por tipo (imagem/gif/sticker/arquivo/áudio/vídeo/texto truncado em 120 chars) e remove automaticamente as push_subscriptions que retornarem 404/410. JSON { record: <linha de chat_mensagens> } (formato do trigger) ou o próprio registro direto. Campos usados: id, conversa_id, remetente_id, tipo, conteudo, anexo_tipo, anexo_nome, excluida_em. Se vier `id`, a função re-busca a mensagem no banco e prefere os dados de lá.
send-recovery-email
Tela de Login › "Esqueci minha senha" (src/components/auth/EsqueciSenhaDialog.tsx), Configurações › Usuários (UsuariosTab.tsx, para o admin disparar o reset de um usuário).
Chamada pública Envia o e-mail de recuperação de senha com o link do GoTrue apontando para <APP_BASE>/redefinir-senha, usando template próprio com o branding da plataforma (getBranding) e o nome do usuário (busca best-effort em profiles). Blinda enumeração de contas: qualquer entrada devolve sempre a mesma resposta genérica. JSON { email: string } (validado por regex simples; e-mail inválido também recebe a resposta genérica).
telefonia-gravacao-sync
Telefonia (histórico de Chamadas / player de gravação), a configuração fica em Configurações › Integrações › Telefonia Sonax.
Rotina agendada Backfill das gravações de chamadas: busca em `chamadas` até 25 registros com duracao_seg > 0, sonax_call_id preenchido e gravacao_path nulo (mais recentes primeiro), baixa o áudio da API dbdial do Sonax (acao=pega_gravacao), valida que o binário é áudio de verdade (RIFF/ID3/0xFF e >1000 bytes) e sobe para o bucket `gravacoes` em <corretora_id>/<ano>/<mes>/<sonax_call_id>.<wav|mp3>, atualizando chamadas.gravacao_path. Nenhuma — sem body nem query params. Todo o estado vem de config_telefonia e da tabela chamadas.
telefonia-webhook
Configurações › Integrações › Telefonia Sonax (TelefoniaSonaxCard.tsx monta a URL do webhook), os dados aparecem no módulo Telefonia / histórico de Chamadas, no card do cliente.
Webhook de terceiro Recebe os eventos de chamada do Sonax (acao=recebida|finaliza) e faz upsert idempotente em `chamadas` por (corretora_id, sonax_call_id). Resolve a corretora e o corretor pelo ramal (telefonia_ramais / telefonia_ramal_membros), tenta casar o cliente pelos últimos 8 dígitos do telefone, consulta o /history do webphone Sonax para descobrir a direção (entrada/saída), baixa a gravação para o bucket `gravacoes` quando vem URL, e faz merge NÃO-regressivo (não rebaixa status finalizado para em_andamento nem zera duração/gravação já conhecidas), tratando corrida 23505 com fallback para UPDATE. GET/POST em /functions/v1/telefonia-webhook?secret=XXXX com campos do Sonax: acao, id_chamada (ou call_id/id/uniqueid/callid/protocolo), ramal (ou aliasramal/extension/agent), numero/telefone/destino/origem, tipo/direcao/direction, status/situacao/resultado, duracao/duration/billsec, data/inicio/start, gravacao/recording/url_gravacao, failed_code/codigo/cause. O payload cru é gravado na coluna `raw`.
Operação

Rastreamento de uso

Toda chamada à API vira um registro, inclusive as recusadas por chave inválida, escopo insuficiente ou limite excedido. Ficam guardados: chave e parceiro, método e caminho, filtros enviados, status, duração, quantidade de registros retornados, IP e user-agent.

O conteúdo dos dados nunca é guardado — o registro serve para auditoria de acesso, não para duplicar a base.

O que isso significa para você

O volume que sua integração consome é visível do nosso lado, por dia e por recurso. Se precisar de um limite maior, de um recurso novo ou de uma janela de carga pesada, é só combinar antes — é mais simples que descobrir depois por um pico no gráfico.