# Arquivar funil transferindo as conversas Source: https://developers.nuvia.ai/api-reference/agents/arquivar-funil-transferindo-as-conversas https://api.nuvia.ai/api/docs/user-json post /v1/agents/{id}/archive ISSUE-5818. Funil sem conversas arquiva direto. Com conversas, exige funil de destino ACTIVE e mapeamento de etapa de origem para etapa de destino cobrindo toda etapa que tem conversa. A transferência e o arquivamento acontecem na mesma transação: se sobrar qualquer conversa no funil, nada é arquivado. # Atualizar agente Source: https://developers.nuvia.ai/api-reference/agents/atualizar-agente https://api.nuvia.ai/api/docs/user-json put /v1/agents/{id} Atualiza as informações de um agente existente. # Buscar agente Source: https://developers.nuvia.ai/api-reference/agents/buscar-agente https://api.nuvia.ai/api/docs/user-json get /v1/agents/{id} Retorna os detalhes de um agente específico. # Campanhas ativas que usam o agente Source: https://developers.nuvia.ai/api-reference/agents/campanhas-ativas-que-usam-o-agente https://api.nuvia.ai/api/docs/user-json get /v1/agents/{id}/active-campaigns Retorna as campanhas ACTIVE da empresa que ativam este agente (send_config.agent_to_activate). Usado para explicar por que a desativação do agente foi bloqueada. # Clonar agente Source: https://developers.nuvia.ai/api-reference/agents/clonar-agente https://api.nuvia.ai/api/docs/user-json post /v1/agents/{id}/clone Cria uma cópia completa de um agente existente com base no ID fornecido. O novo agente terá todas as configurações idênticas ao original (prompts, configurações gerais, steps e follow-ups), exceto o ID e o nome (que receberá o sufixo "(Cópia)"). # Criar agente Source: https://developers.nuvia.ai/api-reference/agents/criar-agente https://api.nuvia.ai/api/docs/user-json post /v1/agents Cria um novo agente de atendimento. # Deletar agente Source: https://developers.nuvia.ai/api-reference/agents/deletar-agente https://api.nuvia.ai/api/docs/user-json delete /v1/agents/{id} Remove um agente do sistema. # Listar agentes Source: https://developers.nuvia.ai/api-reference/agents/listar-agentes https://api.nuvia.ai/api/docs/user-json get /v1/agents Retorna uma lista de agentes de atendimento. # Listar agentes (payload enxuto) Source: https://developers.nuvia.ai/api-reference/agents/listar-agentes-payload-enxuto https://api.nuvia.ai/api/docs/user-json get /v1/agents/summary Mesma lista de /agents, porém com payload reduzido (sem prompts, welcome_message, etc.) para telas que só precisam de id/nome/status/avatar. Use este endpoint para dropdowns, selects e cards. # O que impede arquivar este funil, e o que precisa ser migrado Source: https://developers.nuvia.ai/api-reference/agents/o-que-impede-arquivar-este-funil-e-o-que-precisa-ser-migrado https://api.nuvia.ai/api/docs/user-json get /v1/agents/{id}/archive-preflight ISSUE-5818. Devolve os vínculos que bloqueiam o arquivamento (campanha ACTIVE, inbox com este funil como padrão, time com este funil como default_agent) e a contagem de conversas por etapa, para o fluxo de arquivamento pedir o mapeamento etapa a etapa. # Atualizar contato Source: https://developers.nuvia.ai/api-reference/contacts/atualizar-contato https://api.nuvia.ai/api/docs/user-json put /v1/contacts/{id} Atualiza os dados de um contato existente (nome, e-mail, atributos customizados, etc.) # Atualizar nome do contato Source: https://developers.nuvia.ai/api-reference/contacts/atualizar-nome-do-contato https://api.nuvia.ai/api/docs/user-json put /v1/contacts/{id}/name Atualiza apenas o nome de um contato específico # Buscar contato por ID Source: https://developers.nuvia.ai/api-reference/contacts/buscar-contato-por-id https://api.nuvia.ai/api/docs/user-json get /v1/contacts/{id} Retorna os dados completos de um contato específico # Buscar contatos por telefones Source: https://developers.nuvia.ai/api-reference/contacts/buscar-contatos-por-telefones https://api.nuvia.ai/api/docs/user-json post /v1/contacts/find-by-phones Busca contatos existentes por uma lista de números de telefone. Útil para reconciliação no import de CSV. # Criar contato Source: https://developers.nuvia.ai/api-reference/contacts/criar-contato https://api.nuvia.ai/api/docs/user-json post /v1/contacts Cria um novo contato no sistema. Campos customizados podem ser adicionados via custom_attributes. # Desvincular contato de CRM externo Source: https://developers.nuvia.ai/api-reference/contacts/desvincular-contato-de-crm-externo https://api.nuvia.ai/api/docs/user-json delete /v1/contacts/{id}/crm-link Remove a referência ao CRM externo (crm_type, crm_external_id, crm_last_synced_at) do contato. Atualmente usado pela ação "Desvincular HubSpot" na listagem de contatos. # Excluir contato Source: https://developers.nuvia.ai/api-reference/contacts/excluir-contato https://api.nuvia.ai/api/docs/user-json delete /v1/contacts/{id} Remove um contato da base. Só é permitido quando o contato não possui vínculos ativos (conversas, mensagens, campanhas, logs de enriquecimento ou falhas de envio). Nesse caso retorna 409 com o detalhe do que bloqueia. Vínculos de listas e de empresa (employees) são desvinculados automaticamente. # Listar campanhas de um contato Source: https://developers.nuvia.ai/api-reference/contacts/listar-campanhas-de-um-contato https://api.nuvia.ai/api/docs/user-json get /v1/contacts/{contactId}/campaigns Retorna as campanhas em que o contato está inscrito, com nome, status, canal e data de início. # Listar contatos Source: https://developers.nuvia.ai/api-reference/contacts/listar-contatos https://api.nuvia.ai/api/docs/user-json get /v1/contacts Retorna uma lista paginada de contatos com filtros opcionais (nome, telefone, e-mail, busca textual) # Listar contatos de uma empresa Source: https://developers.nuvia.ai/api-reference/contacts/listar-contatos-de-uma-empresa https://api.nuvia.ai/api/docs/user-json get /v1/contacts/by-business/{businessId} Retorna os contatos vinculados ao business, paginado e ordenável por nome ou cargo. # Listar contatos para CRM Source: https://developers.nuvia.ai/api-reference/contacts/listar-contatos-para-crm https://api.nuvia.ai/api/docs/user-json get /v1/contacts/crm Retorna uma lista paginada de contatos com sua última conversa, filtros por etapa, inbox, status, etc. # Listar contatos vinculados à empresa do contato Source: https://developers.nuvia.ai/api-reference/contacts/listar-contatos-vinculados-à-empresa-do-contato https://api.nuvia.ai/api/docs/user-json get /v1/contacts/{contactId}/company-contacts Retorna os demais contatos da mesma empresa (business) do contato, paginado e ordenável por nome ou cargo. # Listar conversas de um contato Source: https://developers.nuvia.ai/api-reference/contacts/listar-conversas-de-um-contato https://api.nuvia.ai/api/docs/user-json get /v1/contacts/{contactId}/conversations Retorna todas as conversas associadas a um contato, com dados populados de inbox, usuário, agente e etapa do funil. # Listar listas de um contato Source: https://developers.nuvia.ai/api-reference/contacts/listar-listas-de-um-contato https://api.nuvia.ai/api/docs/user-json get /v1/contacts/{contactId}/lists Retorna as listas (tabelas de contatos) em que o contato está presente, com nome, total de itens e data de inclusão. # Listar o histórico de atividade de um contato Source: https://developers.nuvia.ai/api-reference/contacts/listar-o-histórico-de-atividade-de-um-contato https://api.nuvia.ai/api/docs/user-json get /v1/contacts/{contactId}/activities Retorna a timeline agregada do contato (notas, entrada em listas e criação), ordenada da atividade mais recente para a mais antiga. # Atribuir agente à conversa Source: https://developers.nuvia.ai/api-reference/conversations/atribuir-agente-à-conversa https://api.nuvia.ai/api/docs/user-json put /v1/conversations/{id}/assign-agent Atribui um agente de IA a uma conversa específica # Atribuir dono à conversa Source: https://developers.nuvia.ai/api-reference/conversations/atribuir-dono-à-conversa https://api.nuvia.ai/api/docs/user-json put /v1/conversations/{id}/assign-owner Define o dono (responsável) da conversa vinculando um usuário. NÃO altera quem está respondendo (who_answering) nem coloca a conversa na fila de atendimento humano. # Atribuir prioridade à conversa Source: https://developers.nuvia.ai/api-reference/conversations/atribuir-prioridade-à-conversa https://api.nuvia.ai/api/docs/user-json put /v1/conversations/{id}/assign-priority Define ou atualiza a prioridade de uma conversa (URGENT, HIGH, NORMAL, LOW) # Atribuir time à conversa Source: https://developers.nuvia.ai/api-reference/conversations/atribuir-time-à-conversa https://api.nuvia.ai/api/docs/user-json put /v1/conversations/{id}/assign-team Atribui um time a uma conversa específica # Atribuir usuário à conversa Source: https://developers.nuvia.ai/api-reference/conversations/atribuir-usuário-à-conversa https://api.nuvia.ai/api/docs/user-json put /v1/conversations/{id}/assign-user Atribui um usuário (atendente) a uma conversa específica # Atualizar conversa Source: https://developers.nuvia.ai/api-reference/conversations/atualizar-conversa https://api.nuvia.ai/api/docs/user-json put /v1/conversations/{id} Atualiza os dados de uma conversa existente # Atualizar passo da conversa Source: https://developers.nuvia.ai/api-reference/conversations/atualizar-passo-da-conversa https://api.nuvia.ai/api/docs/user-json put /v1/conversations/{id}/step Atualiza o passo atual do fluxo do agente em uma conversa # Atualizar status da conversa Source: https://developers.nuvia.ai/api-reference/conversations/atualizar-status-da-conversa https://api.nuvia.ai/api/docs/user-json put /v1/conversations/{id}/status Atualiza o status de uma conversa (OPEN, RESOLVED) # Buscar conversa por ID Source: https://developers.nuvia.ai/api-reference/conversations/buscar-conversa-por-id https://api.nuvia.ai/api/docs/user-json get /v1/conversations/{id} Retorna os dados completos de uma conversa específica # Criar conversa Source: https://developers.nuvia.ai/api-reference/conversations/criar-conversa https://api.nuvia.ai/api/docs/user-json post /v1/conversations Cria uma nova conversa entre um contato e um inbox # Listar conversas Source: https://developers.nuvia.ai/api-reference/conversations/listar-conversas https://api.nuvia.ai/api/docs/user-json get /v1/conversations Retorna uma lista paginada de conversas com filtros opcionais (inbox, agente, time, usuários, status, período de datas, etc.). # Marcar conversa como lida Source: https://developers.nuvia.ai/api-reference/conversations/marcar-conversa-como-lida https://api.nuvia.ai/api/docs/user-json put /v1/conversations/{id}/mark-as-read Limpa a marcação "requer atenção" da conversa. A conversa sai do chip "Requer atenção" e do badge, mas o macro estado, o dono, o status e a etapa NÃO mudam. Idempotente: sem atenção pendente, nada é escrito. # Retomar controle da IA Source: https://developers.nuvia.ai/api-reference/conversations/retomar-controle-da-ia https://api.nuvia.ai/api/docs/user-json put /v1/conversations/{id}/resume-ai Devolve o controle da conversa para a IA. Opcionalmente gera uma mensagem contextual para o contato. # Atualizar valor de um campo customizado Source: https://developers.nuvia.ai/api-reference/custom-fields/atualizar-valor-de-um-campo-customizado https://api.nuvia.ai/api/docs/user-json put /v1/custom-fields/{id}/value Atualiza o valor de um campo customizado específico em uma conversa. Dependendo do contexto do campo (conversation, contact ou business), atualiza na conversa, no contato ou na empresa do contato — o contato e a empresa são resolvidos a partir da conversa informada, por isso `conversationId` é obrigatório mesmo para campo de contato. Aceita todos os tipos: `text`, `number` e `date` recebem o valor direto; `select`/`multi_select` recebem o `option_id` (ou a lista deles), que sai de `GET /v1/custom-fields/{id}/options`. Valor inválido devolve 422 com `accepted_values`. Campo ou conversa de outra empresa devolve 403/404. # Listar campos customizados Source: https://developers.nuvia.ai/api-reference/custom-fields/listar-campos-customizados https://api.nuvia.ai/api/docs/user-json get /v1/custom-fields Retorna uma lista paginada de campos customizados da empresa. Use para descobrir o `slug` de cada campo — é o `slug`, não o `_id`, que identifica o campo ao gravar valor via `PUT /v1/contacts/{id}` ou `PUT /v1/conversations/{id}`. # Listar opções de um campo select/multi_select Source: https://developers.nuvia.ai/api-reference/custom-fields/listar-opções-de-um-campo-selectmulti_select https://api.nuvia.ai/api/docs/user-json get /v1/custom-fields/{id}/options Retorna as opções ativas do campo. O `_id` de cada opção é o valor aceito ao gravar um campo `select`/`multi_select`. # Atualizar inbox Source: https://developers.nuvia.ai/api-reference/inboxes/atualizar-inbox https://api.nuvia.ai/api/docs/user-json put /v1/inboxes/{id} Atualiza as configurações de um inbox existente (nome, webhook, agente padrão, configurações de API, etc.) # Buscar inbox por ID Source: https://developers.nuvia.ai/api-reference/inboxes/buscar-inbox-por-id https://api.nuvia.ai/api/docs/user-json get /v1/inboxes/{id} Retorna os dados completos de um inbox específico # Criar inbox Source: https://developers.nuvia.ai/api-reference/inboxes/criar-inbox https://api.nuvia.ai/api/docs/user-json post /v1/inboxes Cria um novo inbox (canal de atendimento) para receber e enviar mensagens. Suporta múltiplos canais: WhatsApp Business API, Evolution API, etc. # Deletar inbox Source: https://developers.nuvia.ai/api-reference/inboxes/deletar-inbox https://api.nuvia.ai/api/docs/user-json delete /v1/inboxes/{id} Remove um inbox do sistema (marca como DELETED, não remove fisicamente do banco) # Listar inboxes Source: https://developers.nuvia.ai/api-reference/inboxes/listar-inboxes https://api.nuvia.ai/api/docs/user-json get /v1/inboxes Retorna uma lista paginada de inboxes (canais de atendimento) com filtros opcionais # Atualizar conhecimento ou mídia Source: https://developers.nuvia.ai/api-reference/knowledge/atualizar-conhecimento-ou-mídia https://api.nuvia.ai/api/docs/user-json patch /v1/knowledge/{id} Atualiza nome e/ou descrição de um conhecimento ou mídia # Buscar conhecimento ou mídia por ID Source: https://developers.nuvia.ai/api-reference/knowledge/buscar-conhecimento-ou-mídia-por-id https://api.nuvia.ai/api/docs/user-json get /v1/knowledge/{id} Retorna os detalhes de um conhecimento ou mídia específico # Criar conhecimento em markdown Source: https://developers.nuvia.ai/api-reference/knowledge/criar-conhecimento-em-markdown https://api.nuvia.ai/api/docs/user-json post /v1/knowledge/autcl Cria um item do tipo AUTCL: conteúdo markdown editável pela própria API, sem upload de arquivo. O texto vira chunks + embeddings em background — o item nasce `PROCESSING` e vai para `READY`. A cada edição os embeddings são regerados. # Criar conhecimento ou mídia Source: https://developers.nuvia.ai/api-reference/knowledge/criar-conhecimento-ou-mídia https://api.nuvia.ai/api/docs/user-json post /v1/knowledge Envie o arquivo em `multipart/form-data`. Com `type=KNOWLEDGE` (PDF/DOCX) o arquivo é processado para busca semântica e o item nasce `PROCESSING` até virar `READY`. Com `type=MEDIA` (imagem, vídeo, áudio ou documento para envio em conversas) o arquivo é só armazenado e já nasce `READY`. # Listar conhecimentos e mídias Source: https://developers.nuvia.ai/api-reference/knowledge/listar-conhecimentos-e-mídias https://api.nuvia.ai/api/docs/user-json get /v1/knowledge Lista todos os conhecimentos e mídias da empresa com paginação e filtros # Enviar mensagem de texto Source: https://developers.nuvia.ai/api-reference/messages/enviar-mensagem-de-texto https://api.nuvia.ai/api/docs/user-json post /v1/messages/send Envia uma mensagem de texto simples para uma conversa. Suporta múltiplos tipos de conteúdo (TEXT, IMAGE, AUDIO, VIDEO, DOCUMENT). # Enviar template em massa Source: https://developers.nuvia.ai/api-reference/messages/enviar-template-em-massa https://api.nuvia.ai/api/docs/user-json post /v1/messages/send-bulk-template Dispara um template aprovado do WhatsApp para vários contatos em uma única requisição (`multipart/form-data`). Os contatos vêm pelo campo `contacts` (JSON) **ou** por um arquivo CSV/XLSX no campo `file`, com as colunas `name` e `phone` — um dos dois é obrigatório. Os parâmetros do template vão em `components` e precisam casar em número e tipo com o template aprovado. O processamento é síncrono e parcial: a resposta traz `totalProcessed`, `sentCount`, `errorCount`, os contatos enviados e a lista de `errors` por linha. Contato com erro não interrompe os demais. Por serem templates, os envios valem fora da janela de 24 horas, mas continuam sujeitos ao limite diário do tier da conta no WhatsApp. # Listar anexos de uma conversa Source: https://developers.nuvia.ai/api-reference/messages/listar-anexos-de-uma-conversa https://api.nuvia.ai/api/docs/user-json get /v1/messages/conversation/{id}/attachments Retorna uma lista paginada de anexos (IMAGE/VIDEO/DOCUMENT) de uma conversa, com URL assinada e contexto do remetente para resolução client-side # Listar mensagens de uma conversa Source: https://developers.nuvia.ai/api-reference/messages/listar-mensagens-de-uma-conversa https://api.nuvia.ai/api/docs/user-json get /v1/messages/conversation/{id} Retorna uma lista paginada de mensagens de uma conversa específica # Adicionar linhas à tabela Source: https://developers.nuvia.ai/api-reference/tables/adicionar-linhas-à-tabela https://api.nuvia.ai/api/docs/user-json post /v1/tables/{id}/rows # Atualizar labels das colunas Source: https://developers.nuvia.ai/api-reference/tables/atualizar-labels-das-colunas https://api.nuvia.ai/api/docs/user-json patch /v1/tables/{id}/columns # Atualizar o campo data de uma linha Source: https://developers.nuvia.ai/api-reference/tables/atualizar-o-campo-data-de-uma-linha https://api.nuvia.ai/api/docs/user-json patch /v1/tables/rows/{rowId}/data Só para listas. Escreve estado contextual da linha (validação, enriquecimento) sem alterar as referências a contato ou empresa. # Atualizar um dataset por planilha Source: https://developers.nuvia.ai/api-reference/tables/atualizar-um-dataset-por-planilha https://api.nuvia.ai/api/docs/user-json post /v1/tables/{id}/sync Aplica o delta pela coluna-chave, sem apagar o que não veio na planilha. Por padrão gera um preview aguardando confirmação (`POST /:id/sync-reports/{reportId}/confirm`); com `?apply=true` aplica direto. Acompanhe em `GET /:id/sync-reports`. # Atualizar uma linha da tabela Source: https://developers.nuvia.ai/api-reference/tables/atualizar-uma-linha-da-tabela https://api.nuvia.ai/api/docs/user-json patch /v1/tables/{tableId}/rows/{rowId} # Atualizar view de uma lista Source: https://developers.nuvia.ai/api-reference/tables/atualizar-view-de-uma-lista https://api.nuvia.ai/api/docs/user-json patch /v1/tables/{id}/views/{viewId} Atualiza nome e/ou ordem das colunas de uma view. # Buscar tabela por ID Source: https://developers.nuvia.ai/api-reference/tables/buscar-tabela-por-id https://api.nuvia.ai/api/docs/user-json get /v1/tables/{id} # Configurar o sync por upload Source: https://developers.nuvia.ai/api-reference/tables/configurar-o-sync-por-upload https://api.nuvia.ai/api/docs/user-json patch /v1/tables/{id}/sync-config Define a coluna-chave de negócio (`sync_key_column`) e os critérios de ranking (`ranking_config`) usados a cada sync. # Confirmar um sync abortado por deleção em massa Source: https://developers.nuvia.ai/api-reference/tables/confirmar-um-sync-abortado-por-deleção-em-massa https://api.nuvia.ai/api/docs/user-json post /v1/tables/{id}/sync-reports/{reportId}/confirm Reprocessa o mesmo arquivo com a deleção autorizada. Responde 202 e processa em background. # Criar lista Source: https://developers.nuvia.ai/api-reference/tables/criar-lista https://api.nuvia.ai/api/docs/user-json post /v1/tables/list Cria uma lista (`table_kind=list`) para organizar contatos ou empresas. Diferente de um dataset, a lista não é fonte de dados: é um contexto sobre registros que já existem. # Criar nova view para uma lista Source: https://developers.nuvia.ai/api-reference/tables/criar-nova-view-para-uma-lista https://api.nuvia.ai/api/docs/user-json post /v1/tables/{id}/views Cria uma nova view personalizada para a lista. Se column_keys não for informado, copia todas as colunas da lista. # Criar tabela manual Source: https://developers.nuvia.ai/api-reference/tables/criar-tabela-manual https://api.nuvia.ai/api/docs/user-json post /v1/tables/manual # Descartar um preview de sync Source: https://developers.nuvia.ai/api-reference/tables/descartar-um-preview-de-sync https://api.nuvia.ai/api/docs/user-json post /v1/tables/{id}/sync-reports/{reportId}/discard Encerra um sync que aguardava confirmação. Nada é aplicado na tabela. # Excluir view de uma lista Source: https://developers.nuvia.ai/api-reference/tables/excluir-view-de-uma-lista https://api.nuvia.ai/api/docs/user-json delete /v1/tables/{id}/views/{viewId} # Exportar lista em CSV Source: https://developers.nuvia.ai/api-reference/tables/exportar-lista-em-csv https://api.nuvia.ai/api/docs/user-json get /v1/tables/{id}/export-csv Exporta as linhas em CSV. Listas respeitam view/filtros/ordenação; datasets exportam as colunas gerenciadas (round-trip do sync por upload). # Exportar lista em CSV (seleção grande) Source: https://developers.nuvia.ai/api-reference/tables/exportar-lista-em-csv-seleção-grande https://api.nuvia.ai/api/docs/user-json post /v1/tables/{id}/export-csv Mesma exportação do GET, com os parâmetros no body. Necessário quando a seleção tem mais de 100 linhas: na query string o parser converte o array em objeto (qs arrayLimit) e a URL estoura o maxHeaderSize do Node. # Importar CSV para uma lista existente Source: https://developers.nuvia.ai/api-reference/tables/importar-csv-para-uma-lista-existente https://api.nuvia.ai/api/docs/user-json post /v1/tables/{id}/import-csv Importa dados de um CSV para uma lista existente. Cria contatos novos, atualiza existentes conforme fieldResolutions, e vincula à lista. Duplicatas são ignoradas. # Importar tabela Source: https://developers.nuvia.ai/api-reference/tables/importar-tabela https://api.nuvia.ai/api/docs/user-json post /v1/tables # Inserir linhas em lote Source: https://developers.nuvia.ai/api-reference/tables/inserir-linhas-em-lote https://api.nuvia.ai/api/docs/user-json post /v1/tables/rows/batch Só para listas. Cada linha precisa de exatamente uma referência — `contact_id` ou `business_id` — compatível com o `object_type` da lista. Duplicatas são ignoradas. # Listar linhas da tabela com paginação Source: https://developers.nuvia.ai/api-reference/tables/listar-linhas-da-tabela-com-paginação https://api.nuvia.ai/api/docs/user-json get /v1/tables/{id}/rows # Listar relatórios de sync da tabela Source: https://developers.nuvia.ai/api-reference/tables/listar-relatórios-de-sync-da-tabela https://api.nuvia.ai/api/docs/user-json get /v1/tables/{id}/sync-reports Ordenados do mais recente para o mais antigo. # Listar tabelas Source: https://developers.nuvia.ai/api-reference/tables/listar-tabelas https://api.nuvia.ai/api/docs/user-json get /v1/tables # Listar views de uma lista Source: https://developers.nuvia.ai/api-reference/tables/listar-views-de-uma-lista https://api.nuvia.ai/api/docs/user-json get /v1/tables/{id}/views Retorna todas as views de uma lista, incluindo a view default. # Recalcular a coluna _score Source: https://developers.nuvia.ai/api-reference/tables/recalcular-a-coluna-_score https://api.nuvia.ai/api/docs/user-json post /v1/tables/{id}/recompute-score Reaplica o `ranking_config` já configurado nas linhas atuais, sem novo upload. # Remover múltiplas linhas da tabela em batch Source: https://developers.nuvia.ai/api-reference/tables/remover-múltiplas-linhas-da-tabela-em-batch https://api.nuvia.ai/api/docs/user-json delete /v1/tables/{tableId}/rows/batch # Remover tabela Source: https://developers.nuvia.ai/api-reference/tables/remover-tabela https://api.nuvia.ai/api/docs/user-json delete /v1/tables/{id} # Remover todas as linhas da lista Source: https://developers.nuvia.ai/api-reference/tables/remover-todas-as-linhas-da-lista https://api.nuvia.ai/api/docs/user-json delete /v1/tables/{tableId}/rows/all Remove todas as linhas que atendem aos filtros/view. Pode excluir IDs específicos via excludeRowIds. # Remover uma linha da tabela Source: https://developers.nuvia.ai/api-reference/tables/remover-uma-linha-da-tabela https://api.nuvia.ai/api/docs/user-json delete /v1/tables/{tableId}/rows/{rowId} # Simular o ranking da lista Source: https://developers.nuvia.ai/api-reference/tables/simular-o-ranking-da-lista https://api.nuvia.ai/api/docs/user-json post /v1/tables/{id}/ranking-preview Aplica os critérios em memória e devolve o top-N na ordem resultante. Nada é persistido. # Sugerir a coluna-chave do sync Source: https://developers.nuvia.ai/api-reference/tables/sugerir-a-coluna-chave-do-sync https://api.nuvia.ai/api/docs/user-json get /v1/tables/{id}/sync-config/suggestions Analisa a unicidade de cada coluna e devolve `suggested_key` — a primeira coluna com valores únicos, ou `null` se nenhuma servir. # Atualizar a configuração de webhook Source: https://developers.nuvia.ai/api-reference/webhooks/atualizar-a-configuração-de-webhook https://api.nuvia.ai/api/docs/user-json put /v1/webhooks/{id} Use o `id` devolvido por `GET /v1/webhooks`. Webhook de outra empresa devolve 403. # Buscar a configuração de webhook da empresa Source: https://developers.nuvia.ai/api-reference/webhooks/buscar-a-configuração-de-webhook-da-empresa https://api.nuvia.ai/api/docs/user-json get /v1/webhooks Devolve **um objeto** de configuração ou `null` — não é uma lista. Cada empresa tem no máximo um webhook. # Criar a configuração de webhook Source: https://developers.nuvia.ai/api-reference/webhooks/criar-a-configuração-de-webhook https://api.nuvia.ai/api/docs/user-json post /v1/webhooks Cada empresa tem **no máximo um** webhook. Se já existir um, esta chamada devolve 409 — atualize o existente com `PUT /v1/webhooks/{id}` ou apague com `DELETE /v1/webhooks/{id}` antes de criar outro. # Remover a configuração de webhook Source: https://developers.nuvia.ai/api-reference/webhooks/remover-a-configuração-de-webhook https://api.nuvia.ai/api/docs/user-json delete /v1/webhooks/{id} Depois de remover, a empresa volta a poder criar um webhook novo via `POST /v1/webhooks`. # Autenticação Source: https://developers.nuvia.ai/autenticacao Como autenticar suas requisições na API da Nuvia com uma API Key Toda requisição à API da Nuvia é autenticada por um **token Bearer** enviado no header `Authorization`. Esta página explica como autenticar chamadas com uma API Key que você **já possui**. Para gerar, listar e revogar chaves, veja o [Guia de API Key](/guia-api-key). ## Base URL ``` https://api.nuvia.ai ``` Todas as rotas da API REST usam o prefixo de versão `/v1`. Por exemplo, listar agentes é `GET https://api.nuvia.ai/v1/agents`. A API Key da Nuvia **não** usa um header `X-API-Key` nem um token no formato `sk_...`. A chave é enviada como um **token Bearer** no header `Authorization`: ``` Authorization: Bearer ``` Enviar a chave em `X-API-Key` resulta em `401`, porque o servidor não lê esse header. ## Duas formas de autenticar A API aceita dois tipos de identidade **no mesmo header** `Authorization: Bearer`: * **API Key de empresa**: é o que você usa para **integração programática**. A chave é vinculada à sua empresa e aos escopos definidos na criação; pode ter validade opcional (`expiresAt`). É o método recomendado para servidores, scripts e integrações. * **JWT humano**: o token de sessão emitido pelo fluxo de login do aplicativo (`POST /v1/auth/login`). Representa um usuário humano, não uma integração. Você não precisa dele para consumir a API via API Key. Os endpoints de login pertencem à plataforma e **não aparecem na [Referência da API](/api-reference)**, que cobre a superfície consumível por API Key. O servidor identifica automaticamente qual dos dois foi enviado pelo próprio conteúdo do token. Você não sinaliza o tipo em lugar nenhum. Para o resto desta documentação, assumimos o uso de **API Key de empresa**. ## Autenticando uma requisição Inclua o header `Authorization` em toda chamada. O exemplo abaixo lista os agentes da sua empresa (requer o escopo `agents:read`): ```bash cURL theme={null} curl https://api.nuvia.ai/v1/agents \ -H "Authorization: Bearer $NUVIA_API_KEY" ``` ```javascript JavaScript theme={null} const res = await fetch("https://api.nuvia.ai/v1/agents", { headers: { Authorization: `Bearer ${process.env.NUVIA_API_KEY}`, }, }); const data = await res.json(); ``` ```python Python theme={null} import os import requests res = requests.get( "https://api.nuvia.ai/v1/agents", headers={"Authorization": f"Bearer {os.environ['NUVIA_API_KEY']}"}, ) data = res.json() ``` A API Key é um **token de acesso completo** ao escopo concedido. Trate-a como um segredo: guarde em variável de ambiente ou cofre de segredos, nunca no código-fonte nem no controle de versão. ## Multi-tenant e o header `X-Company-Id` O tenant (empresa) de uma API Key de empresa é resolvido **pelo próprio token**. Você não precisa informá-lo. O header `X-Company-Id` só é obrigatório para chaves globais de uso interno e é **ignorado** para API Keys de empresa e para JWT humano. Em resumo: **integrando com uma API Key de empresa, você não envia `X-Company-Id`.** ## Erros de autenticação As respostas de erro de autenticação seguem o formato `{ statusCode, message, error }`. ### 401: não autenticado Retornado quando o token está ausente, é inválido, expirou ou foi revogado. ```json theme={null} { "statusCode": 401, "message": "Autenticação inválida", "error": "Unauthorized" } ``` O campo `message` detalha a causa quando possível, por exemplo `"API Key inválida"`, `"API Key expirada"`, `"API Key revogada"` ou `"API Key não encontrada"`. ### 403: sem permissão Retornado quando o token é válido, mas a API Key **não tem o escopo** necessário para a ação, ou o endpoint não está disponível para API Keys. ```json theme={null} { "statusCode": 403, "message": "API Key não possui o escopo necessário para esta ação", "error": "Forbidden" } ``` Se você recebe `403` em uma chamada que deveria funcionar, verifique se a chave foi criada com o escopo exigido pelo endpoint. Os escopos são definidos no momento da criação da chave. Veja o [Guia de API Key](/guia-api-key). ## Próximos passos Como gerar, listar e revogar chaves, e quais escopos existem. Faça sua primeira chamada à API em poucos minutos. # Guia de API Key Source: https://developers.nuvia.ai/guia-api-key Como gerar, listar e revogar API Keys da Nuvia, e quais escopos existem Uma API Key é o token que sua integração usa para autenticar na API da Nuvia. Para saber **como enviar** a chave nas requisições, veja [Autenticação](/autenticacao). Esta página cobre o **ciclo de vida** da chave: criar, listar, revogar e escolher escopos. As API Keys são criadas e gerenciadas por um **usuário humano** autenticado com o token de login do aplicativo (JWT humano, veja [Autenticação](/autenticacao)). Uma API Key **não** gerencia outras API Keys: os endpoints de `/v1/api-keys` não aceitam autenticação por API Key. ## Criar uma API Key Envie um `POST /v1/api-keys` autenticado como usuário. O corpo aceita: | Campo | Tipo | Obrigatório | Descrição | | ----------- | ----------------- | ----------- | -------------------------------------------------------------------------- | | `name` | string | Sim | Nome de identificação da chave (até 100 caracteres). | | `scopes` | string\[] | Sim | Lista de escopos no formato `:` (veja o catálogo abaixo). | | `expiresAt` | string (ISO 8601) | Não | Data futura de expiração. Se omitido, a chave não expira por tempo. | ```bash cURL theme={null} curl -X POST https://api.nuvia.ai/v1/api-keys \ -H "Authorization: Bearer $NUVIA_USER_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "name": "Integração de produção", "scopes": ["contacts:read", "messages:create"], "expiresAt": "2027-01-01T00:00:00.000Z" }' ``` ```javascript JavaScript theme={null} const res = await fetch("https://api.nuvia.ai/v1/api-keys", { method: "POST", headers: { Authorization: `Bearer ${process.env.NUVIA_USER_TOKEN}`, "Content-Type": "application/json", }, body: JSON.stringify({ name: "Integração de produção", scopes: ["contacts:read", "messages:create"], expiresAt: "2027-01-01T00:00:00.000Z", }), }); const { accessToken, apiKey } = await res.json(); ``` ```python Python theme={null} import os import requests res = requests.post( "https://api.nuvia.ai/v1/api-keys", headers={"Authorization": f"Bearer {os.environ['NUVIA_USER_TOKEN']}"}, json={ "name": "Integração de produção", "scopes": ["contacts:read", "messages:create"], "expiresAt": "2027-01-01T00:00:00.000Z", }, ) body = res.json() access_token = body["accessToken"] ``` A resposta (`201`) traz o token em `accessToken` e os metadados da chave em `apiKey`: ```json theme={null} { "accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...", "apiKey": { "name": "Integração de produção", "scopes": ["contacts:read", "messages:create"], "status": "ACTIVE", "keyPreview": "...a1b2", "expiresAt": "2027-01-01T00:00:00.000Z" } } ``` O valor completo do token aparece **uma única vez**, no campo `accessToken` da resposta de criação. A Nuvia **não armazena o token** e não há como recuperá-lo depois: só ficam guardados metadados e uma prévia (`keyPreview`, os últimos 4 caracteres). Copie e guarde o token com segurança nesse momento. Se você perder o token, revogue a chave e crie uma nova. ## Listar API Keys `GET /v1/api-keys` retorna as chaves da sua empresa (com paginação `{ data, meta }`). A resposta traz apenas metadados, nunca o token. ```bash cURL theme={null} curl https://api.nuvia.ai/v1/api-keys \ -H "Authorization: Bearer $NUVIA_USER_TOKEN" ``` ```javascript JavaScript theme={null} const res = await fetch("https://api.nuvia.ai/v1/api-keys", { headers: { Authorization: `Bearer ${process.env.NUVIA_USER_TOKEN}` }, }); const { data, meta } = await res.json(); ``` ```python Python theme={null} import os import requests res = requests.get( "https://api.nuvia.ai/v1/api-keys", headers={"Authorization": f"Bearer {os.environ['NUVIA_USER_TOKEN']}"}, ) data = res.json()["data"] ``` ## Revogar uma API Key `DELETE /v1/api-keys/:id` revoga a chave imediatamente e responde `204 No Content`. A operação é **idempotente**: revogar uma chave já revogada não causa erro. A chave precisa pertencer à sua empresa. ```bash cURL theme={null} curl -X DELETE https://api.nuvia.ai/v1/api-keys/652f1a9c8b3e4d0012a7f4c1 \ -H "Authorization: Bearer $NUVIA_USER_TOKEN" ``` Uma vez revogada, a chave para de autenticar em qualquer requisição. ## Escopos disponíveis Escopos seguem o formato `:`. Ao criar uma chave, conceda **apenas** os escopos de que a integração precisa. A tabela abaixo lista o catálogo disponível no painel, agrupado por subject. | Subject | Ações | O que o subject libera | | ---------------------- | --------------------------------------- | --------------------------------------------------------------------------------------------------------------- | | `agents` | `read` · `create` · `update` · `delete` | Agentes de IA: listar, criar, clonar e atualizar. | | `contacts` | `read` · `create` · `update` · `delete` | Contatos: gerenciar contatos e seus vínculos. | | `conversations` | `read` · `create` · `update` | Conversas: listar e atualizar (atribuir agente, dono, prioridade, equipe). | | `campaigns` | `read` · `create` · `update` · `delete` | Campanhas: gerenciar campanhas, ativação e analytics. | | `campaign-enrollments` | `read` · `create` | Inscrições em campanha: inscrever contatos (individual, por lista, funil ou `contact_ids`) e listar inscrições. | | `triggers` | `create` | Gatilhos de campanha: disparar a inscrição por evento. | | `messages` | `read` · `create` | Mensagens: ler mensagens e anexos de uma conversa e enviar (texto e template). | | `inboxes` | `read` · `create` · `update` | Inboxes: gerenciar caixas de entrada. | | `tables` | `read` · `create` · `update` · `delete` | Tabelas e listas: gerenciar tabelas, colunas e exportações. | | `knowledge-base` | `read` · `create` · `update` | Base de conhecimento: gerenciar itens de conhecimento. | | `webhooks` | `read` · `create` · `update` · `delete` | Webhooks: gerenciar configurações de webhook. | | `search-v2` | `read` · `create` | Busca de empresas e prospects (Brasil e global) e autocomplete. | | `linkedin-search` | `read` · `create` | Busca no LinkedIn: perfis, empresas e parâmetros. | | `enrichment` | `read` · `create` | Enriquecimento de contatos e consulta de elegibilidade/créditos. | O painel só oferece os escopos deste catálogo. Se um endpoint retornar `403` mesmo com uma chave válida, confirme que a chave foi criada com o escopo exigido por aquele endpoint. **Exceção conhecida:** `DELETE /v1/inboxes/{id}` exige o escopo `inboxes:delete`, que **não está** no catálogo do painel: uma chave criada por lá recebe `403` nesse endpoint. Para concedê-lo, crie a chave por `POST /v1/api-keys` incluindo `"inboxes:delete"` em `scopes`: a criação valida apenas o formato `:`, não o catálogo. Todos os demais escopos exigidos pelos endpoints da Referência estão no catálogo. ## Modelo de posse Uma API Key pertence à **empresa** (o tenant), não ao usuário que a criou. O usuário criador é registrado apenas para auditoria. Uma consequência importante: A chave **não é revogada automaticamente** quando o usuário que a criou é desativado ou removido da empresa. Ela continua válida. Para encerrar o acesso de uma chave, **revogue-a explicitamente** com `DELETE /v1/api-keys/:id`. ## Boas práticas de segurança A API Key é um Bearer token que dá acesso a tudo o que os seus escopos permitem. Guarde-a em variável de ambiente ou cofre de segredos, nunca no código-fonte nem no controle de versão. Conceda somente os escopos necessários para a integração. Evite criar chaves com o catálogo inteiro "por precaução". Use `expiresAt` para chaves de vida curta ou temporárias, reduzindo a janela de exposição caso a chave vaze. Revogue chaves antigas, de testes ou não utilizadas. Como a chave sobrevive à saída do usuário criador, a limpeza é responsabilidade da empresa. ## Próximos passos Como enviar a API Key nas requisições e entender os erros de auth. Como a API trata limites de requisição hoje. # Exemplos de código Source: https://developers.nuvia.ai/guias/code-samples Snippets reutilizáveis da API da Nuvia em cURL, JavaScript, Python, PHP e Go Padrões de uso prontos para copiar e adaptar, nas linguagens mais comuns. Para a lista completa de endpoints, use a [Referência da API](/api-reference); para obter uma chave, veja o [Guia de API Key](/guia-api-key). Todas as chamadas usam a base `https://api.nuvia.ai` com o prefixo `/v1` e o header `Authorization: Bearer `. Veja [Autenticação](/autenticacao). ## Configuração Guarde a chave em uma variável de ambiente (`NUVIA_API_KEY`), nunca no código. ```bash cURL theme={null} export NUVIA_API_KEY="sua-api-key" # base: https://api.nuvia.ai/v1 ``` ```javascript JavaScript theme={null} const BASE = "https://api.nuvia.ai/v1"; const KEY = process.env.NUVIA_API_KEY; const headers = { Authorization: `Bearer ${KEY}` }; ``` ```python Python theme={null} import os BASE = "https://api.nuvia.ai/v1" HEADERS = {"Authorization": f"Bearer {os.environ['NUVIA_API_KEY']}"} ``` ```php PHP theme={null} ## Requisição autenticada (GET) Lista os agentes da empresa (`GET /v1/agents`, escopo `agents:read`). ```bash cURL theme={null} curl "https://api.nuvia.ai/v1/agents" \ -H "Authorization: Bearer $NUVIA_API_KEY" ``` ```javascript JavaScript theme={null} const res = await fetch("https://api.nuvia.ai/v1/agents", { headers: { Authorization: `Bearer ${process.env.NUVIA_API_KEY}` }, }); const body = await res.json(); ``` ```python Python theme={null} import os, requests res = requests.get( "https://api.nuvia.ai/v1/agents", headers={"Authorization": f"Bearer {os.environ['NUVIA_API_KEY']}"}, ) body = res.json() ``` ```php PHP theme={null} true, CURLOPT_HTTPHEADER => ["Authorization: Bearer " . getenv("NUVIA_API_KEY")], ]); $body = json_decode(curl_exec($ch), true); curl_close($ch); ``` ```go Go theme={null} package main import ( "encoding/json" "net/http" "os" ) func main() { req, _ := http.NewRequest("GET", "https://api.nuvia.ai/v1/agents", nil) req.Header.Set("Authorization", "Bearer "+os.Getenv("NUVIA_API_KEY")) res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() var body map[string]any json.NewDecoder(res.Body).Decode(&body) } ``` ## POST com corpo JSON Cria um contato (`POST /v1/contacts`, escopo `contacts:create`). ```bash cURL theme={null} curl -X POST "https://api.nuvia.ai/v1/contacts" \ -H "Authorization: Bearer $NUVIA_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "firstname": "Maria", "lastname": "Silva", "phone": "+5511999999999", "email": "maria@empresa.com" }' ``` ```javascript JavaScript theme={null} const res = await fetch("https://api.nuvia.ai/v1/contacts", { method: "POST", headers: { Authorization: `Bearer ${process.env.NUVIA_API_KEY}`, "Content-Type": "application/json", }, body: JSON.stringify({ firstname: "Maria", lastname: "Silva", phone: "+5511999999999", email: "maria@empresa.com", }), }); const contact = await res.json(); ``` ```python Python theme={null} import os, requests res = requests.post( "https://api.nuvia.ai/v1/contacts", headers={"Authorization": f"Bearer {os.environ['NUVIA_API_KEY']}"}, json={ "firstname": "Maria", "lastname": "Silva", "phone": "+5511999999999", "email": "maria@empresa.com", }, ) contact = res.json() ``` ```php PHP theme={null} "Maria", "lastname" => "Silva", "phone" => "+5511999999999", "email" => "maria@empresa.com", ]); $ch = curl_init("https://api.nuvia.ai/v1/contacts"); curl_setopt_array($ch, [ CURLOPT_RETURNTRANSFER => true, CURLOPT_POST => true, CURLOPT_POSTFIELDS => $payload, CURLOPT_HTTPHEADER => [ "Authorization: Bearer " . getenv("NUVIA_API_KEY"), "Content-Type: application/json", ], ]); $contact = json_decode(curl_exec($ch), true); curl_close($ch); ``` ```go Go theme={null} package main import ( "bytes" "encoding/json" "net/http" "os" ) func main() { payload, _ := json.Marshal(map[string]string{ "firstname": "Maria", "lastname": "Silva", "phone": "+5511999999999", "email": "maria@empresa.com", }) req, _ := http.NewRequest("POST", "https://api.nuvia.ai/v1/contacts", bytes.NewReader(payload)) req.Header.Set("Authorization", "Bearer "+os.Getenv("NUVIA_API_KEY")) req.Header.Set("Content-Type", "application/json") res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() } ``` ## Paginação Endpoints de listagem retornam `{ data, meta }`, com `meta` contendo `page`, `rowsPerPage`, `totalCount`, `hasNextPage` e `hasPreviousPage`. Use os query params `page` (começa em 1) e `rowsPerPage`, e itere enquanto `meta.hasNextPage` for `true`. ```bash cURL theme={null} page=1 while : ; do resp=$(curl -s "https://api.nuvia.ai/v1/contacts?page=$page&rowsPerPage=50" \ -H "Authorization: Bearer $NUVIA_API_KEY") echo "$resp" | jq '.data[]' [ "$(echo "$resp" | jq -r '.meta.hasNextPage')" = "true" ] || break page=$((page + 1)) done ``` ```javascript JavaScript theme={null} async function listAllContacts() { const all = []; let page = 1; while (true) { const res = await fetch( `https://api.nuvia.ai/v1/contacts?page=${page}&rowsPerPage=50`, { headers: { Authorization: `Bearer ${process.env.NUVIA_API_KEY}` } }, ); const { data, meta } = await res.json(); all.push(...data); if (!meta.hasNextPage) break; page++; } return all; } ``` ```python Python theme={null} import os, requests def list_all_contacts(): headers = {"Authorization": f"Bearer {os.environ['NUVIA_API_KEY']}"} all_items, page = [], 1 while True: res = requests.get( "https://api.nuvia.ai/v1/contacts", headers=headers, params={"page": page, "rowsPerPage": 50}, ) body = res.json() all_items += body["data"] if not body["meta"]["hasNextPage"]: break page += 1 return all_items ``` ```php PHP theme={null} true, CURLOPT_HTTPHEADER => ["Authorization: Bearer " . getenv("NUVIA_API_KEY")], ]); $body = json_decode(curl_exec($ch), true); curl_close($ch); $all = array_merge($all, $body["data"]); $page++; } while ($body["meta"]["hasNextPage"]); return $all; } ``` ```go Go theme={null} package main import ( "encoding/json" "fmt" "net/http" "os" ) type page struct { Data []map[string]any `json:"data"` Meta struct { HasNextPage bool `json:"hasNextPage"` } `json:"meta"` } func listAllContacts() ([]map[string]any, error) { var all []map[string]any for p := 1; ; p++ { url := fmt.Sprintf("https://api.nuvia.ai/v1/contacts?page=%d&rowsPerPage=50", p) req, _ := http.NewRequest("GET", url, nil) req.Header.Set("Authorization", "Bearer "+os.Getenv("NUVIA_API_KEY")) res, err := http.DefaultClient.Do(req) if err != nil { return nil, err } var body page json.NewDecoder(res.Body).Decode(&body) res.Body.Close() all = append(all, body.Data...) if !body.Meta.HasNextPage { return all, nil } } } ``` ## Tratamento de erros Cheque o código de status. Erros de autenticação retornam `{ statusCode, message, error }` (veja [Autenticação](/autenticacao)): `401` (token inválido/expirado/revogado) e `403` (falta escopo). ```bash cURL theme={null} code=$(curl -s -o resp.json -w "%{http_code}" "https://api.nuvia.ai/v1/agents" \ -H "Authorization: Bearer $NUVIA_API_KEY") if [ "$code" -ge 400 ]; then echo "Erro $code:"; cat resp.json fi ``` ```javascript JavaScript theme={null} const res = await fetch("https://api.nuvia.ai/v1/agents", { headers: { Authorization: `Bearer ${process.env.NUVIA_API_KEY}` }, }); if (!res.ok) { const err = await res.json(); throw new Error(`${res.status}: ${err.message}`); } ``` ```python Python theme={null} import os, requests res = requests.get( "https://api.nuvia.ai/v1/agents", headers={"Authorization": f"Bearer {os.environ['NUVIA_API_KEY']}"}, ) if not res.ok: err = res.json() raise RuntimeError(f"{res.status_code}: {err.get('message')}") ``` ```php PHP theme={null} true, CURLOPT_HTTPHEADER => ["Authorization: Bearer " . getenv("NUVIA_API_KEY")], ]); $raw = curl_exec($ch); $code = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); if ($code >= 400) { $err = json_decode($raw, true); throw new RuntimeException("{$code}: " . ($err["message"] ?? "erro")); } ``` ```go Go theme={null} package main import ( "encoding/json" "fmt" "net/http" "os" ) func fetchAgents() error { req, _ := http.NewRequest("GET", "https://api.nuvia.ai/v1/agents", nil) req.Header.Set("Authorization", "Bearer "+os.Getenv("NUVIA_API_KEY")) res, err := http.DefaultClient.Do(req) if err != nil { return err } defer res.Body.Close() if res.StatusCode >= 400 { var e struct { Message string `json:"message"` } json.NewDecoder(res.Body).Decode(&e) return fmt.Errorf("%d: %s", res.StatusCode, e.Message) } return nil } ``` ## Retry com backoff em `429` Alguns fluxos respondem `429 Too Many Requests`. As respostas **não** incluem headers de rate limit (nem `Retry-After`). Veja [Rate limits](/guias/rate-limits) e use um backoff exponencial próprio. ```bash cURL theme={null} url="https://api.nuvia.ai/v1/agents" for attempt in 1 2 3 4 5; do code=$(curl -s -o /dev/null -w "%{http_code}" "$url" \ -H "Authorization: Bearer $NUVIA_API_KEY") [ "$code" != "429" ] && break sleep $((2 ** (attempt - 1))) # 1s, 2s, 4s, 8s... done ``` ```javascript JavaScript theme={null} async function withRetry(fn, max = 5) { for (let attempt = 0; attempt < max; attempt++) { const res = await fn(); if (res.status !== 429) return res; await new Promise((r) => setTimeout(r, 2 ** attempt * 1000)); } throw new Error("Limite de tentativas atingido (429)"); } const res = await withRetry(() => fetch("https://api.nuvia.ai/v1/agents", { headers: { Authorization: `Bearer ${process.env.NUVIA_API_KEY}` }, }), ); ``` ```python Python theme={null} import os, time, requests def with_retry(make_request, max_attempts=5): for attempt in range(max_attempts): res = make_request() if res.status_code != 429: return res time.sleep(2 ** attempt) # 1s, 2s, 4s, 8s... raise RuntimeError("Limite de tentativas atingido (429)") headers = {"Authorization": f"Bearer {os.environ['NUVIA_API_KEY']}"} res = with_retry(lambda: requests.get("https://api.nuvia.ai/v1/agents", headers=headers)) ``` ```php PHP theme={null} true, CURLOPT_HTTPHEADER => ["Authorization: Bearer " . getenv("NUVIA_API_KEY")], ]); $body = curl_exec($ch); $code = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); return [$body, $code]; }; $body = withRetry($makeRequest); ``` ```go Go theme={null} package main import ( "net/http" "time" ) func withRetry(makeRequest func() (*http.Response, error), max int) (*http.Response, error) { var res *http.Response var err error for attempt := 0; attempt < max; attempt++ { res, err = makeRequest() if err != nil { return nil, err } if res.StatusCode != http.StatusTooManyRequests { return res, nil } res.Body.Close() time.Sleep(time.Duration(1< Estes snippets de retry são exemplos mínimos. Em produção, adicione **jitter** (aleatoriedade no tempo de espera) e um **teto de espera**, para evitar que vários clientes tentem de novo ao mesmo tempo (*thundering herd*). ## Próximos passos Cenários ponta a ponta: mensagens, webhooks, campanhas e contatos. Todos os endpoints, parâmetros e respostas. # Exemplos de integração Source: https://developers.nuvia.ai/guias/exemplos-integracao Cenários ponta a ponta com a API da Nuvia: mensagens, webhooks, campanhas e contatos Casos de uso completos que você pode rodar de verdade com uma API Key. Todas as chamadas usam o header `Authorization: Bearer`. Veja [Autenticação](/autenticacao) e o [Guia de API Key](/guia-api-key) para obter e configurar a chave. Base: `https://api.nuvia.ai`, prefixo `/v1`. Cada caso indica os **escopos** de API Key necessários. Conceda apenas esses na criação da chave. ## Caso 1: Enviar sua primeira mensagem **Escopos:** `inboxes:read`, `conversations:read`, `messages:read`, `messages:create`. Liste as caixas de entrada conectadas à sua empresa. ```bash cURL theme={null} curl https://api.nuvia.ai/v1/inboxes \ -H "Authorization: Bearer $NUVIA_API_KEY" ``` ```javascript JavaScript theme={null} const res = await fetch("https://api.nuvia.ai/v1/inboxes", { headers: { Authorization: `Bearer ${process.env.NUVIA_API_KEY}` }, }); const { data } = await res.json(); ``` ```python Python theme={null} import os, requests res = requests.get( "https://api.nuvia.ai/v1/inboxes", headers={"Authorization": f"Bearer {os.environ['NUVIA_API_KEY']}"}, ) data = res.json()["data"] ``` O envio de mensagem é feito dentro de uma conversa. Liste conversas para pegar um `conversationId` (ou crie uma com `POST /v1/conversations`). ```bash cURL theme={null} curl "https://api.nuvia.ai/v1/conversations" \ -H "Authorization: Bearer $NUVIA_API_KEY" ``` `POST /v1/messages/send` com o `conversationId` e o objeto `message`. ```bash cURL theme={null} curl -X POST https://api.nuvia.ai/v1/messages/send \ -H "Authorization: Bearer $NUVIA_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "conversationId": "ID_DA_CONVERSA", "message": { "content": "Olá! Enviado via API.", "contentType": "TEXT" } }' ``` ```javascript JavaScript theme={null} await fetch("https://api.nuvia.ai/v1/messages/send", { method: "POST", headers: { Authorization: `Bearer ${process.env.NUVIA_API_KEY}`, "Content-Type": "application/json", }, body: JSON.stringify({ conversationId: "ID_DA_CONVERSA", message: { content: "Olá! Enviado via API.", contentType: "TEXT" }, }), }); ``` ```python Python theme={null} import os, requests requests.post( "https://api.nuvia.ai/v1/messages/send", headers={"Authorization": f"Bearer {os.environ['NUVIA_API_KEY']}"}, json={ "conversationId": "ID_DA_CONVERSA", "message": {"content": "Olá! Enviado via API.", "contentType": "TEXT"}, }, ) ``` Use `contentType: "TEXT"` para mensagens de texto. `GET /v1/messages/conversation/:id` retorna as mensagens; anexos ficam em `GET /v1/messages/conversation/:id/attachments`. ```bash cURL theme={null} curl "https://api.nuvia.ai/v1/messages/conversation/ID_DA_CONVERSA" \ -H "Authorization: Bearer $NUVIA_API_KEY" ``` ## Caso 2: Receber eventos via webhooks Registre uma URL sua para a Nuvia notificar em tempo real (mensagens, conversas, contatos). Este caso mostra o fluxo ponta a ponta; o formato do payload, a lista completa de eventos e as garantias de entrega estão no [guia de Webhooks](/guias/webhooks). **Escopos:** para registrar e consultar, `webhooks:create` e `webhooks:read`; para gerenciar, `webhooks:update` e `webhooks:delete` (+ `messages:create` se você responder automaticamente). `POST /v1/webhooks`. São 10 eventos válidos: `MESSAGE_SENT`, `MESSAGE_RECEIVED`, `MESSAGE_DELIVERED`, `MESSAGE_READ`, `CONVERSATION_CREATED`, `CONVERSATION_UPDATED`, `CONTACT_CREATED`, `CONTACT_UPDATED`, `FOLLOWUP_SENT` e `FIELD_UPDATED`. Veja o que cada um entrega na [tabela de eventos](/guias/webhooks). Sua empresa tem **um** webhook: se já houver um configurado, esta chamada devolve `409`. Atualize o existente em vez de criar outro. ```bash cURL theme={null} curl -X POST https://api.nuvia.ai/v1/webhooks \ -H "Authorization: Bearer $NUVIA_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "url": "https://seu-servidor.com/nuvia/webhook", "events": ["MESSAGE_RECEIVED", "CONVERSATION_CREATED"], "status": "ACTIVE" }' ``` ```javascript JavaScript theme={null} await fetch("https://api.nuvia.ai/v1/webhooks", { method: "POST", headers: { Authorization: `Bearer ${process.env.NUVIA_API_KEY}`, "Content-Type": "application/json", }, body: JSON.stringify({ url: "https://seu-servidor.com/nuvia/webhook", events: ["MESSAGE_RECEIVED", "CONVERSATION_CREATED"], status: "ACTIVE", }), }); ``` ```python Python theme={null} import os, requests requests.post( "https://api.nuvia.ai/v1/webhooks", headers={"Authorization": f"Bearer {os.environ['NUVIA_API_KEY']}"}, json={ "url": "https://seu-servidor.com/nuvia/webhook", "events": ["MESSAGE_RECEIVED", "CONVERSATION_CREATED"], "status": "ACTIVE", }, ) ``` Campos opcionais: `custom_headers` (para você validar a origem) e `status` (`ACTIVE`/`INACTIVE`). Quando um evento ocorre, a Nuvia faz um `POST` para a sua `url`, com o header `X-Webhook-Event` e um corpo de três campos: ```json theme={null} { "event": "MESSAGE_RECEIVED", "timestamp": "2026-08-13T14:03:00.000Z", "data": {} } ``` `data` traz o recurso do evento: a mensagem, a conversa ou o contato, no mesmo formato dos `GET` correspondentes. `FIELD_UPDATED` é a exceção e tem estrutura própria. Responda `2xx` em até **10 segundos** e processe em background. Não há retry: se a sua resposta falhar ou estourar o tempo, o evento é perdido. Detalhes em [Garantias de entrega](/guias/webhooks#garantias-de-entrega). A partir do callback, você pode agir via API: responda com `POST /v1/messages/send` (Caso 1) ou baixe anexos com `GET /v1/messages/conversation/:id/attachments`. `GET /v1/webhooks` devolve **um objeto** com a configuração da empresa (ou `null`). Não é uma lista. Use o `id` desse objeto para atualizar com `PUT /v1/webhooks/:id` ou remover com `DELETE /v1/webhooks/:id`. Para pausar sem perder a configuração, prefira `PUT` com `status: "INACTIVE"`. ## Caso 3: Campanhas e disparo em massa **Escopos:** `campaigns:create`, `campaigns:read`, `campaigns:update`, `campaigns:delete` (+ `messages:create` para o atalho de template em massa). `POST /v1/campaigns`. Campos obrigatórios: `name`, `channel_type`, `trigger_type` e `audience_config`; opcionais incluem `description`, `trigger_config`, `behavior_config` e `sender_config`. As estruturas internas desses objetos de configuração estão na [Referência da API](/api-reference/campaigns). Siga o schema de lá. A **audiência é definida na própria criação**, dentro de `audience_config` (por `contact_ids`, `lists` ou `filters`). Não há um passo de matrícula (enrollment) separado a fazer via API. A campanha já nasce com a audiência que você informar aqui. Use os previews (não criam nada): `POST /v1/campaigns/audience-preview` conta os contatos da audiência e `POST /v1/campaigns/preview-message` resolve as variáveis da mensagem. Ative com `POST /v1/campaigns/:id/activate` (pause com `/pause`). Acompanhe com `GET /v1/campaigns/:id/analytics` e `GET /v1/campaigns/:id/step-analytics`, e exporte os contatos com `GET /v1/campaigns/:id/enrollments/export`. ```bash cURL theme={null} curl -X POST https://api.nuvia.ai/v1/campaigns/ID_DA_CAMPANHA/activate \ -H "Authorization: Bearer $NUVIA_API_KEY" ``` **Atalho:** para enviar um template de WhatsApp para vários contatos sem montar uma campanha, use `POST /v1/messages/send-bulk-template` (escopo `messages:create`). O passo a passo, com os parâmetros de template e os limites da Meta, está no guia [Template em massa no WhatsApp](/guias/whatsapp-template-massa). ## Caso 4: Sincronizar contatos Mantenha seu CRM externo e a Nuvia em sincronia. **Escopos:** `contacts:read`, `contacts:create`, `contacts:update`, `contacts:delete`. Antes de criar, resolva os telefones para ver quais já existem: `POST /v1/contacts/find-by-phones`. ```bash cURL theme={null} curl -X POST https://api.nuvia.ai/v1/contacts/find-by-phones \ -H "Authorization: Bearer $NUVIA_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "phones": ["+5511999999999", "+5511888888888"] }' ``` ```javascript JavaScript theme={null} const res = await fetch("https://api.nuvia.ai/v1/contacts/find-by-phones", { method: "POST", headers: { Authorization: `Bearer ${process.env.NUVIA_API_KEY}`, "Content-Type": "application/json", }, body: JSON.stringify({ phones: ["+5511999999999", "+5511888888888"] }), }); ``` ```python Python theme={null} import os, requests res = requests.post( "https://api.nuvia.ai/v1/contacts/find-by-phones", headers={"Authorization": f"Bearer {os.environ['NUVIA_API_KEY']}"}, json={"phones": ["+5511999999999", "+5511888888888"]}, ) ``` `POST /v1/contacts`. Campos: `firstname`, `lastname`, `phone`, `email`, `company` e `properties`. ```bash cURL theme={null} curl -X POST https://api.nuvia.ai/v1/contacts \ -H "Authorization: Bearer $NUVIA_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "firstname": "Maria", "lastname": "Silva", "phone": "+5511999999999", "email": "maria@empresa.com" }' ``` ```javascript JavaScript theme={null} await fetch("https://api.nuvia.ai/v1/contacts", { method: "POST", headers: { Authorization: `Bearer ${process.env.NUVIA_API_KEY}`, "Content-Type": "application/json", }, body: JSON.stringify({ firstname: "Maria", lastname: "Silva", phone: "+5511999999999", email: "maria@empresa.com", }), }); ``` ```python Python theme={null} import os, requests requests.post( "https://api.nuvia.ai/v1/contacts", headers={"Authorization": f"Bearer {os.environ['NUVIA_API_KEY']}"}, json={ "firstname": "Maria", "lastname": "Silva", "phone": "+5511999999999", "email": "maria@empresa.com", }, ) ``` Atualize um contato com `PUT /v1/contacts/:id` (ou só o nome com `PUT /v1/contacts/:id/name`) e liste/pagine com `GET /v1/contacts`. Para **remover o vínculo** de um contato com um CRM externo, use `DELETE /v1/contacts/:id/crm-link`: isso **apenas desfaz a vinculação; o contato continua existindo** na Nuvia (não é exclusão de contato). ## Outras superfícies públicas Consumíveis por API Key e cobertas na Referência: **Agentes**, **Tabelas e listas**, **Conversas** e **Base de conhecimento**. Veja o mapa em [Seções da API](/secoes-da-api). ## Próximos passos Escopos, criação e revogação de chaves. Todos os endpoints, parâmetros e respostas. # Coleção Postman Source: https://developers.nuvia.ai/guias/postman Baixe a coleção oficial da API da Nuvia e importe no Postman para testar os endpoints A coleção do Postman reúne os endpoints consumíveis por API Key já organizados por domínio, com os mesmos grupos da [Referência da API](/api-reference), prontos para você testar com a sua **API Key**. Ela usa as convenções descritas em [Autenticação](/autenticacao): autenticação por **Bearer Token** e base `https://api.nuvia.ai`. A coleção é gerada a partir da mesma especificação que alimenta a Referência, então as duas mostram exatamente a mesma superfície. ## Baixar a coleção Arquivo `.zip` com a coleção no formato Postman v2.1. Descompacte para obter o `nuvia-postman-collection.json`. O download é um `.zip`. Descompacte-o antes de importar. Dentro há um único arquivo, `nuvia-postman-collection.json`, que é a coleção em si. ## Importar no Postman Extraia o `.zip` baixado. Você terá o arquivo `nuvia-postman-collection.json`. No Postman, clique em **Import** (canto superior esquerdo) e selecione o `nuvia-postman-collection.json`. A coleção **Nuvia API** aparece na barra lateral, com os endpoints agrupados por domínio: Agentes, Contatos, Conversas, Mensagens, Caixas de Entrada, Campanhas, Inscrições em Campanha, Tabelas e Listas, Base de Conhecimento e Webhooks. A coleção usa duas variáveis. Abra a coleção **Nuvia API**, vá até a aba **Variables** e preencha: | Variável | Valor | | --------------- | ------------------------------------------ | | `baseUrl` | `https://api.nuvia.ai` (já vem preenchido) | | `NUVIA_API_KEY` | a sua API Key | Salve. Veja como gerar uma chave no [Guia de API Key](/guia-api-key). Escolha qualquer requisição de leitura (por exemplo, **listar agentes**) e clique em **Send**. A autenticação já está configurada na coleção. Cada requisição herda o **Bearer Token** com a sua `NUVIA_API_KEY`. ## Como a autenticação está configurada A coleção define a autenticação **no nível da coleção**: o tipo é **Bearer Token** e o token é a variável `{{NUVIA_API_KEY}}`. Todas as requisições **herdam** essa configuração, então você não precisa preencher o cabeçalho `Authorization` em cada uma: basta definir a variável `NUVIA_API_KEY` uma vez. A coleção cobre só o que uma API Key consegue chamar. O fluxo de login da plataforma e a gestão de chaves (`/v1/api-keys`) exigem o token de usuário e ficam de fora. Veja o [Guia de API Key](/guia-api-key) para criar e revogar chaves. Algumas requisições trazem o cabeçalho `x-company-id` **desabilitado**. Ele só é necessário para API Keys globais de uso interno; com uma chave de empresa, deixe como está. A `NUVIA_API_KEY` é uma credencial sensível. Não compartilhe a coleção com o valor da variável preenchido, e prefira usar uma variável de **ambiente** do Postman em vez de salvar o valor direto na coleção. ## Próximos passos Como autenticar suas chamadas com uma API Key. Casos de uso completos com cURL, JavaScript e Python. # Rate limits Source: https://developers.nuvia.ai/guias/rate-limits Como a API da Nuvia trata limites de requisição hoje Esta página descreve, de forma factual, os limites de requisição que a API da Nuvia aplica **hoje**. Para autenticar suas chamadas, veja [Autenticação](/autenticacao). ## API REST (chamadas com API Key) Atualmente **não há limite de requisições por rota** aplicado às chamadas autenticadas por API Key. Não publicamos um número de requisições por segundo ou por minuto para a API REST principal porque não existe um limite desse tipo em vigor. Mesmo sem limite por rota hoje, projete sua integração para ser resiliente: trate respostas `429 Too Many Requests` com **retry e backoff exponencial**. Assim, se limites forem aplicados no futuro, seu código já lida com eles sem alteração. ## Limites que existem hoje Alguns fluxos específicos têm limite aplicado. Eles respondem `429 Too Many Requests` com o corpo: ```json theme={null} { "statusCode": 429, "message": "..." } ``` | Fluxo | Limite | Janela | Contado por | | ---------------------------------------- | -------------- | ----------- | ----------- | | OAuth / MCP (`/token`, `/register`) | 60 requisições | 60 segundos | Endereço IP | | Recuperação de senha (`forgot-password`) | 3 requisições | 1 hora | E-mail | Essas respostas `429` **não** incluem headers de rate limit: não há `X-RateLimit-Limit`, `X-RateLimit-Remaining` nem `Retry-After`. Não dependa desses headers para decidir quando repetir a requisição; use sua própria estratégia de backoff. ## Recomendação Ao receber `429`, aguarde antes de repetir e aumente o intervalo a cada nova tentativa (backoff exponencial), com um teto de tentativas. Como as respostas `429` não trazem headers de rate limit, baseie o backoff no seu próprio controle de tempo, não em valores retornados pela API. # Webhooks Source: https://developers.nuvia.ai/guias/webhooks Receba eventos da Nuvia no seu servidor: formato do payload, eventos disponíveis e garantias de entrega Um webhook faz o caminho inverso da API: em vez de você consultar a Nuvia, a Nuvia envia um `POST` para o seu servidor sempre que algo acontece na sua operação: uma mensagem chega, um contato é criado, um campo é preenchido pelo agente. Cada empresa tem **no máximo um** webhook. Não é uma coleção: você configura uma URL e escolhe quais eventos ela recebe. Tentar criar um segundo devolve `409`. ## Configurar `POST /v1/webhooks` com a URL e a lista de eventos. Escopo necessário: `webhooks:create`. ```bash cURL theme={null} curl -X POST https://api.nuvia.ai/v1/webhooks \ -H "Authorization: Bearer $NUVIA_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "url": "https://seu-servidor.com/nuvia/webhook", "events": ["MESSAGE_RECEIVED", "CONTACT_CREATED"], "custom_headers": { "X-Meu-Token": "um-segredo-seu" }, "status": "ACTIVE" }' ``` ```javascript JavaScript theme={null} await fetch("https://api.nuvia.ai/v1/webhooks", { method: "POST", headers: { Authorization: `Bearer ${process.env.NUVIA_API_KEY}`, "Content-Type": "application/json", }, body: JSON.stringify({ url: "https://seu-servidor.com/nuvia/webhook", events: ["MESSAGE_RECEIVED", "CONTACT_CREATED"], custom_headers: { "X-Meu-Token": "um-segredo-seu" }, status: "ACTIVE", }), }); ``` ```python Python theme={null} import os, requests requests.post( "https://api.nuvia.ai/v1/webhooks", headers={"Authorization": f"Bearer {os.environ['NUVIA_API_KEY']}"}, json={ "url": "https://seu-servidor.com/nuvia/webhook", "events": ["MESSAGE_RECEIVED", "CONTACT_CREATED"], "custom_headers": {"X-Meu-Token": "um-segredo-seu"}, "status": "ACTIVE", }, ) ``` | Campo | Tipo | Obrigatório | Descrição | | ---------------- | ---------------------- | ----------- | ---------------------------------------------------------------------- | | `url` | string | Sim | URL que vai receber os `POST`. | | `events` | string\[] | Sim | Ao menos um evento da tabela abaixo. | | `custom_headers` | objeto | Não | Headers extras enviados em toda entrega. Use-os para validar a origem. | | `status` | `ACTIVE` \| `INACTIVE` | Não | Default `ACTIVE`. Em `INACTIVE` nada é entregue. | ## O que a Nuvia envia Toda entrega é um `POST` com estes headers: | Header | Valor | | ----------------- | ------------------------------------------------- | | `Content-Type` | `application/json` | | `X-Webhook-Event` | O nome do evento, igual ao campo `event` do corpo | | *(seus headers)* | Tudo que você configurou em `custom_headers` | E o corpo tem sempre a mesma estrutura de três campos: ```json theme={null} { "event": "MESSAGE_RECEIVED", "timestamp": "2026-08-13T14:03:00.000Z", "data": {} } ``` * **`event`**: o evento que disparou a entrega. * **`timestamp`**: ISO 8601 UTC, gerado no momento em que a entrega foi enfileirada. * **`data`**: o recurso relacionado ao evento (veja a tabela abaixo). O corpo **não** identifica a empresa: não existe `companyId` no envelope. Se o seu servidor atende várias empresas da Nuvia, use uma URL por empresa ou um valor distinto em `custom_headers` para saber de quem é o evento. ## Eventos disponíveis | Evento | Quando dispara | O que vem em `data` | | ---------------------- | ------------------------------------------ | -------------------------------------- | | `MESSAGE_RECEIVED` | Mensagem recebida de um contato | A mensagem | | `MESSAGE_SENT` | Mensagem enviada pela sua operação | A mensagem | | `MESSAGE_DELIVERED` | WhatsApp confirmou a entrega | A mensagem, com o status já atualizado | | `MESSAGE_READ` | O contato leu a mensagem | A mensagem, com o status já atualizado | | `CONVERSATION_CREATED` | Nova conversa aberta | A conversa | | `CONVERSATION_UPDATED` | Conversa alterada | A conversa | | `CONTACT_CREATED` | Novo contato criado | O contato | | `CONTACT_UPDATED` | Contato alterado | O contato | | `FOLLOWUP_SENT` | Follow-up disparado pelo agente | O follow-up | | `FIELD_UPDATED` | Campo personalizado preenchido ou alterado | Estrutura própria (veja abaixo) | Nos eventos de mensagem, conversa e contato, `data` traz o recurso no mesmo formato que a [Referência da API](/api-reference) devolve nos `GET` correspondentes, por exemplo `GET /v1/messages/conversation/{id}` para mensagens. Trate `data` de forma tolerante: leia os campos que você usa e ignore o resto. Campos novos podem aparecer conforme a plataforma evolui, e isso não é considerado quebra de contrato. ### `FIELD_UPDATED` é diferente Esse evento não devolve uma entidade, e sim a descrição da alteração: ```json theme={null} { "event": "FIELD_UPDATED", "timestamp": "2026-08-13T14:03:00.000Z", "data": { "field": { "_id": "65f1a2b3c4d5e6f7a8b9c0d1", "slug": "orcamento", "title": "Orçamento", "context": "contact" }, "value": "50000", "contactId": "65f1a2b3c4d5e6f7a8b9c0d2", "conversationId": "65f1a2b3c4d5e6f7a8b9c0d3", "companyId": "65f1a2b3c4d5e6f7a8b9c0d4" } } ``` `field.context` indica a que o campo pertence: `contact`, `conversation` ou `business`. `value` tem o tipo do campo: string, número, booleano ou lista. `conversationId` só vem quando a alteração aconteceu dentro de uma conversa. ## Validar que a chamada veio da Nuvia **Não há assinatura HMAC.** A Nuvia não assina o corpo da requisição, então não existe como verificar criptograficamente a origem. O mecanismo disponível é o `custom_headers`: cadastre um valor secreto e confira em toda requisição. ```javascript Node.js theme={null} app.post("/nuvia/webhook", (req, res) => { if (req.get("X-Meu-Token") !== process.env.NUVIA_WEBHOOK_TOKEN) { return res.sendStatus(401); } res.sendStatus(200); // responda primeiro processarEmBackground(req.body); // processe depois }); ``` Use HTTPS e um valor longo e aleatório. Como o segredo viaja em header a cada entrega, trate-o como credencial: rotacione com `PUT /v1/webhooks/{id}` se suspeitar de vazamento. ## Garantias de entrega Estas são as características reais da entrega. Leia antes de construir algo que dependa de webhook: Se o seu servidor estiver fora do ar, devolver `5xx` ou estourar o tempo limite, **o evento é perdido**. A falha é registrada do lado da Nuvia, mas nada é reenviado. Para dados críticos, reconcilie periodicamente com a API (por exemplo, listando mensagens da conversa) em vez de confiar só no webhook. A Nuvia aguarda no máximo 10 segundos pela sua resposta. Responda `2xx` imediatamente e faça o processamento em background. Se você processar antes de responder, entregas legítimas viram timeout. Os eventos de status vêm do WhatsApp, que pode entregá-los fora de ordem (um `MESSAGE_DELIVERED` chegando depois do `MESSAGE_READ` da mesma mensagem). A Nuvia não reordena. Trate cada evento pelo estado que ele carrega, sem assumir sequência. `MESSAGE_DELIVERED` e `MESSAGE_READ` só são enviados quando o status realmente muda. O WhatsApp reenvia o mesmo status várias vezes, e essas repetições são descartadas: você não recebe duplicata por causa disso. Ainda assim, escreva um handler idempotente: use o identificador da mensagem como chave. Com `status: "INACTIVE"`, ou para eventos que você não incluiu em `events`, a Nuvia não enfileira entrega alguma, e não há histórico para recuperar depois. Reativar não recupera o período parado. ## Gerenciar a configuração | Ação | Chamada | Escopo | | --------- | -------------------------- | ----------------- | | Consultar | `GET /v1/webhooks` | `webhooks:read` | | Atualizar | `PUT /v1/webhooks/{id}` | `webhooks:update` | | Remover | `DELETE /v1/webhooks/{id}` | `webhooks:delete` | O `GET` devolve **um objeto** com a configuração da empresa, ou `null` se não houver nenhuma. Não é uma lista. O `id` usado no `PUT` e no `DELETE` vem desse objeto. Depois de remover, a empresa volta a poder criar um webhook novo. Para pausar temporariamente sem perder a configuração, prefira `PUT` com `status: "INACTIVE"` em vez de apagar. ## Próximos passos O webhook dentro de um caso de uso completo, com resposta automática. Parâmetros e respostas dos endpoints de webhook. # Template em massa no WhatsApp Source: https://developers.nuvia.ai/guias/whatsapp-template-massa Dispare um template aprovado do WhatsApp para vários contatos numa única requisição `POST /v1/messages/send-bulk-template` envia um template aprovado do WhatsApp para uma lista de contatos de uma vez. Por serem templates, os envios valem **fora da janela de 24 horas**: esse é o caminho para iniciar conversa com quem não falou com você recentemente. **Escopo:** `messages:create`. O template precisa estar **aprovado na Meta** antes. Esta chamada dispara um template existente; ela não cria nem submete templates para aprovação. ## Campos da requisição | Campo | Tipo | Obrigatório | Descrição | | -------------- | ------- | ----------- | --------------------------------------------------------------------------------------- | | `inboxId` | string | Sim | Inbox (conexão de WhatsApp) que envia as mensagens. | | `templateName` | string | Sim | Nome do template como registrado no WhatsApp Business. | | `languageCode` | string | Não | Formato `pt_BR`, `en_US` ou só `en`. Default: `pt_BR`. | | `components` | array | Não | Parâmetros dinâmicos do template (veja abaixo). | | `contacts` | array | Condicional | Lista de `{ name, phone }`. Obrigatório se você não enviar arquivo. | | `file` | arquivo | Condicional | CSV ou XLSX com as colunas `name` e `phone`. Obrigatório se você não enviar `contacts`. | `phone` precisa do código do país, sem símbolos: `5511999999999`. `name` não pode ser vazio. ## Enviar para uma lista de contatos ```bash cURL theme={null} curl -X POST https://api.nuvia.ai/v1/messages/send-bulk-template \ -H "Authorization: Bearer $NUVIA_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "inboxId": "ID_DO_INBOX", "templateName": "boas_vindas", "languageCode": "pt_BR", "components": [ { "type": "body", "parameters": [{ "type": "text", "text": "João" }] } ], "contacts": [ { "name": "João Silva", "phone": "5511999999999" }, { "name": "Maria Santos", "phone": "5511888888888" } ] }' ``` Para listas grandes, envie um arquivo em vez do array: `multipart/form-data` com o CSV ou XLSX no campo `file` e os demais campos no formulário. O arquivo precisa das colunas `name` e `phone`: ```csv theme={null} name,phone João Silva,5511999999999 Maria Santos,5511888888888 ``` Combinar **arquivo** com `components` de parâmetros dinâmicos é um caso que vale testar com poucos contatos antes de usar em produção. Se os parâmetros não forem aplicados como você espera, fale com o suporte. ## Parâmetros do template Um template aprovado tem lacunas (`{{1}}`, `{{2}}`) e blocos: cabeçalho, corpo e botões. Você preenche isso em `components`, e o número e o tipo de parâmetros precisam **casar exatamente** com o template aprovado, caso contrário a Meta recusa o envio. | Bloco (`type`) | O que aceita em `parameters` | | -------------- | ----------------------------------------------------------- | | `header` | `text`, `image`, `video`, `document` | | `body` | `text`, `currency`, `date_time` | | `button` | `text` (botão de URL dinâmica), `payload` (resposta rápida) | Tipos de parâmetro: | `type` | Campos | Exemplo | | ----------- | ------------------------------------ | ----------------------------------------------------------------------------------------- | | `text` | `text` | `{ "type": "text", "text": "João" }` | | `image` | `image.link` | `{ "type": "image", "image": { "link": "https://..." } }` | | `video` | `video.link` | `{ "type": "video", "video": { "link": "https://..." } }` | | `document` | `document.link`, `document.filename` | `{ "type": "document", "document": { "link": "https://...", "filename": "boleto.pdf" } }` | | `currency` | `currencyCode`, `currencyAmount` | `{ "type": "currency", "currencyCode": "BRL", "currencyAmount": 150.5 }` | | `date_time` | `dateTime` (ISO 8601) | `{ "type": "date_time", "dateTime": "2026-01-31T23:59:59Z" }` | | `payload` | `payload` | `{ "type": "payload", "payload": "produto_1" }` | Imagem, vídeo e documento entram no cabeçalho por **URL pública HTTPS**. Você não precisa fazer upload de arquivo nem preparar nada antes. Basta que a URL seja acessível pela Meta. ### Exemplos por tipo de template Template: cabeçalho de imagem + `Olá {{1}}! Confira nossa promoção de {{2}}.` ```json theme={null} "components": [ { "type": "header", "parameters": [ { "type": "image", "image": { "link": "https://example.com/promo.jpg" } } ] }, { "type": "body", "parameters": [ { "type": "text", "text": "João" }, { "type": "text", "text": "Black Friday" } ] } ] ``` Template: `Seu pedido #{{1}} foi confirmado.` + botão que aponta para `.../track/{{1}}`. O `index` do botão é uma **string** e começa em `"0"`: ```json theme={null} "components": [ { "type": "body", "parameters": [{ "type": "text", "text": "12345" }] }, { "type": "button", "sub_type": "url", "index": "0", "parameters": [{ "type": "text", "text": "12345" }] } ] ``` Template: cabeçalho de documento + `Olá {{1}}, segue seu boleto.` ```json theme={null} "components": [ { "type": "header", "parameters": [ { "type": "document", "document": { "link": "https://example.com/boleto.pdf", "filename": "boleto_janeiro.pdf" } } ] }, { "type": "body", "parameters": [{ "type": "text", "text": "João Silva" }] } ] ``` Template: `Sua fatura de {{1}} no valor de {{2}} vence em {{3}}.` ```json theme={null} "components": [ { "type": "body", "parameters": [ { "type": "text", "text": "Janeiro/2026" }, { "type": "currency", "currencyCode": "BRL", "currencyAmount": 150.5 }, { "type": "date_time", "dateTime": "2026-01-31T23:59:59Z" } ] } ] ``` A formatação final (`R$ 150,50`, `31/01/2026`) é feita pelo WhatsApp, conforme o idioma do aparelho de quem recebe. Templates de **carrossel** não são aceitos neste endpoint. Use o envio individual de template. ## A resposta é parcial O processamento é síncrono e um contato com erro **não interrompe** os demais. A resposta traz o resultado consolidado: ```json theme={null} { "totalProcessed": 100, "sentCount": 95, "errorCount": 5, "sentContacts": [ { "conversationId": "65f1a2b3c4d5e6f7a8b9c0d1", "phoneNumber": "5511999999999" } ], "errors": [ { "row": 5, "contact": "João Silva", "error": "Número de telefone inválido" }, { "row": 23, "contact": "Maria Santos", "error": "Template não encontrado para este inbox" } ] } ``` Um `200` **não** significa que todo mundo recebeu. Sempre leia `errorCount` e `errors`. Se você ignorar esse bloco, falhas de envio passam despercebidas. `row` aponta a linha do arquivo ou o índice no array `contacts`. Reenviar para quem falhou é responsabilidade da sua integração: não há retry automático. ## Limites que valem conhecer * **Tier da conta no WhatsApp**: a Meta limita o número de conversas únicas iniciadas por dia (1.000, 10.000 ou 100.000, conforme o tier da sua conta). O disparo respeita esse teto: acima dele, os envios passam a falhar. * **Tamanho de mídia**: imagem até 5 MB (JPG, PNG), vídeo até 16 MB (MP4, 3GPP), documento até 100 MB (PDF, DOC/DOCX, XLS/XLSX, PPT/PPTX, TXT), áudio até 16 MB. * **Links de mídia**: precisam ser URLs HTTPS públicas, acessíveis pela Meta. URL atrás de login ou de rede interna falha. * **Tamanho do lote**: envie em blocos de até 1.000 contatos por requisição. ## Boas práticas Dispare primeiro para o seu próprio número e confira o resultado no aparelho. Parâmetro fora de ordem só aparece na mensagem final. Use o formato internacional sem símbolos (`5511999999999`). Número inválido vira linha em `errors`, não exceção. `sentContacts` devolve a conversa criada para cada contato: é por ela que você acompanha a resposta, via [webhooks](/guias/webhooks) ou `GET /v1/messages/conversation/{id}`. Reenvie apenas as linhas de `errors`, depois de corrigir o motivo. ## Próximos passos Receba as respostas de quem foi impactado pelo disparo. Contrato completo do endpoint e dos demais envios. # Introdução Source: https://developers.nuvia.ai/index A API da Nuvia para automação de vendas e atendimento via WhatsApp A Nuvia é uma plataforma de CRM e IA para vendas e atendimento via WhatsApp. A API permite integrar contatos, conversas, mensagens, campanhas e agentes de IA diretamente ao seu sistema. Tudo o que sua equipe faz na plataforma, você também faz programaticamente. As chamadas são autenticadas por uma **API Key** de empresa e organizadas sob a base `https://api.nuvia.ai` com o prefixo de versão `/v1`. Para começar, veja o [Início rápido](/quickstart). ## O que dá pra fazer Crie, atualize e consulte contatos e seus vínculos. Liste conversas e gerencie atribuição de agente, dono, prioridade e equipe. Envie texto e templates de WhatsApp, e leia o histórico de uma conversa. Crie e ative campanhas, e acompanhe seus resultados. Gerencie os agentes de IA que atendem e qualificam seus contatos. Organize dados em tabelas e listas, com colunas e exportação. Receba eventos da sua operação no seu servidor, em tempo real. Busque empresas e prospects e enriqueça contatos (escopos `search-v2`, `enrichment`). ## MCP para assistentes de IA A Nuvia também expõe um servidor **MCP** (Model Context Protocol) que permite conectar assistentes de IA à plataforma. Como conectar assistentes de IA ao MCP da Nuvia. ## Comece por aqui Do zero à primeira requisição bem-sucedida. Como autenticar suas chamadas com uma API Key. Gere, liste e revogue chaves, e escolha os escopos. Todos os endpoints, parâmetros e respostas. # Início rápido Source: https://developers.nuvia.ai/quickstart Do zero à sua primeira requisição bem-sucedida na API da Nuvia Este guia leva você da estaca zero até a **primeira requisição autenticada** na API da Nuvia. Você precisa de uma conta em uma empresa na Nuvia. As API Keys são criadas por um usuário da empresa e pertencem à empresa (o tenant). Autenticado como usuário, crie uma chave com o escopo mínimo de que você precisa. Para este guia, use `agents:read` (permite listar agentes). ```bash cURL theme={null} curl -X POST https://api.nuvia.ai/v1/api-keys \ -H "Authorization: Bearer $NUVIA_USER_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "name": "Início rápido", "scopes": ["agents:read"] }' ``` A resposta traz o token no campo `accessToken`. O token completo aparece **uma única vez**, na criação. A Nuvia não o armazena e não há como recuperá-lo depois. Copie e guarde com segurança agora. O fluxo completo (listar, revogar, escopos) está no [Guia de API Key](/guia-api-key). Envie a API Key no header `Authorization: Bearer`. Use aqui o mesmo token que você copiou no Step 2: o valor de `accessToken` é a sua API Key (nos exemplos abaixo, a variável `NUVIA_API_KEY`). O exemplo lista os agentes da sua empresa: ```bash cURL theme={null} curl https://api.nuvia.ai/v1/agents \ -H "Authorization: Bearer $NUVIA_API_KEY" ``` ```javascript JavaScript theme={null} const res = await fetch("https://api.nuvia.ai/v1/agents", { headers: { Authorization: `Bearer ${process.env.NUVIA_API_KEY}`, }, }); const { data, meta } = await res.json(); ``` ```python Python theme={null} import os import requests res = requests.get( "https://api.nuvia.ai/v1/agents", headers={"Authorization": f"Bearer {os.environ['NUVIA_API_KEY']}"}, ) body = res.json() ``` Uma resposta bem-sucedida retorna **`200 OK`**. Endpoints de listagem seguem o formato `{ data, meta }`, em que `data` traz os itens e `meta` traz a paginação: ```json theme={null} { "data": [ { "id": "652f1a9c8b3e4d0012a7f4c1", "name": "Agente de Vendas" } ], "meta": { "page": 1, "rowsPerPage": 20, "totalCount": 1, "hasNextPage": false, "hasPreviousPage": false } } ``` Se você recebeu `200` e um corpo com `data`, sua integração está autenticada e funcionando. * **`401`**: token ausente, inválido, expirado ou revogado. Confira o header `Authorization`. * **`403`**: a chave é válida, mas não tem o escopo exigido pelo endpoint. Os formatos de erro e as causas estão detalhados em [Autenticação](/autenticacao). ## Próximos passos Explore todos os endpoints, parâmetros e respostas. Escopos, revogação e boas práticas de segurança. # Seções da API Source: https://developers.nuvia.ai/secoes-da-api Mapa das áreas funcionais da API da Nuvia e os escopos de API Key de cada uma Um mapa das áreas funcionais da API da Nuvia para você localizar o que precisa antes de mergulhar na [Referência da API](/api-reference). Cada domínio indica os **escopos de API Key** associados. A lista completa de ações por escopo está no [Guia de API Key](/guia-api-key). ## Agentes | Domínio | O que faz | Escopos | | -------------------------------- | -------------------------------------------------------------- | -------- | | [Agentes](/api-reference/agents) | Gerenciar os agentes de IA: listar, criar, clonar e atualizar. | `agents` | ## Contatos e conversas | Domínio | O que faz | Escopos | | ----------------------------------------- | ------------------------------------------------------------------------------------------------ | --------------- | | [Contatos](/api-reference/contacts) | Criar, atualizar e consultar contatos e seus vínculos. | `contacts` | | [Conversas](/api-reference/conversations) | Listar conversas e gerenciar atribuição de agente, dono, prioridade e equipe. | `conversations` | | [Mensagens](/api-reference/messages) | Enviar texto e templates de WhatsApp e ler o histórico de uma conversa, com os anexos recebidos. | `messages` | | [Inboxes](/api-reference/inboxes) | Gerenciar as caixas de entrada da operação. | `inboxes` | ## Campanhas | Domínio | O que faz | Escopos | | ------------------------------------------------------------- | -------------------------------------------------------------------------------------------------- | ---------------------- | | [Campanhas](/api-reference/campaigns) | Criar e ativar campanhas e acompanhar seus resultados. | `campaigns` | | [Inscrições em Campanha](/api-reference/campaign-enrollments) | Inscrever contatos numa campanha, individualmente ou em massa (por lista, funil ou `contact_ids`). | `campaign-enrollments` | ## Dados e conhecimento | Domínio | O que faz | Escopos | | ------------------------------------------------ | -------------------------------------------------------------- | ---------------- | | [Tabelas e listas](/api-reference/tables) | Organizar dados em tabelas e listas, com colunas e exportação. | `tables` | | [Base de conhecimento](/api-reference/knowledge) | Gerenciar itens de conhecimento e mídias usados pelos agentes. | `knowledge-base` | ## Busca e enriquecimento Essas capacidades são consumíveis por API Key, mas **não têm página na Referência** ainda, então use os escopos abaixo para acessá-las. | Capacidade | O que faz | Escopos | | ----------------------------- | ---------------------------------------------------------------------------------------------- | ----------------- | | Busca de empresas e prospects | Buscar empresas e prospects por firmografia, cargo, localização, CNPJ, etc. (Brasil e global). | `search-v2` | | Busca no LinkedIn | Buscar perfis e empresas no LinkedIn. | `linkedin-search` | | Enriquecimento de contatos | Enriquecer e-mail e telefone de contatos. | `enrichment` | ## Próximos passos Todos os endpoints, parâmetros e respostas. Catálogo completo de escopos e ações. # Criar inscrições em massa a partir de contact_ids Source: https://developers.nuvia.ai/api-reference/campaign-enrollments/criar-inscrições-em-massa-a-partir-de-contact_ids https://api.nuvia.ai/api/docs/user-json post /v1/campaigns/{campaignId}/enrollments/bulk Inscreve os contatos informados na campanha. Contatos já inscritos são ignorados; a resposta traz `created` e `skipped`. # Criar inscrições em massa a partir de listas Source: https://developers.nuvia.ai/api-reference/campaign-enrollments/criar-inscrições-em-massa-a-partir-de-listas https://api.nuvia.ai/api/docs/user-json post /v1/campaigns/{campaignId}/enrollments/bulk-from-lists Processa em background e retorna imediatamente com `jobId` e `status: processing`. O progresso é publicado no WebSocket, no evento `campaign:enrollment:progress`. # Criar inscrições em massa a partir do funil Source: https://developers.nuvia.ai/api-reference/campaign-enrollments/criar-inscrições-em-massa-a-partir-do-funil https://api.nuvia.ai/api/docs/user-json post /v1/campaigns/{campaignId}/enrollments/bulk-from-funnel Inscreve os contatos do funil do agente, opcionalmente restritos a uma etapa (`agent_step_id`) e a filtros por campo (`match_criteria`). # Inscrever um contato na campanha Source: https://developers.nuvia.ai/api-reference/campaign-enrollments/inscrever-um-contato-na-campanha https://api.nuvia.ai/api/docs/user-json post /v1/campaigns/{campaignId}/enrollments/from-contact Cria o contato se ele ainda não existir e o inscreve na campanha. Identifique por `contact.phone` (E.164) e/ou `contact.linkedin_identifier` — ao menos um; campanha de WhatsApp exige phone, de LinkedIn exige linkedin. Só campanhas ACTIVE (409 caso contrário). Conversa ativa ou canal incompatível devolvem `status: "skipped"`. `contact.external_id` sobrescreve o vínculo de CRM do contato. # Listar enrollments da campanha Source: https://developers.nuvia.ai/api-reference/campaign-enrollments/listar-enrollments-da-campanha https://api.nuvia.ai/api/docs/user-json get /v1/campaigns/{campaignId}/enrollments # Analytics da campanha Source: https://developers.nuvia.ai/api-reference/campaigns/analytics-da-campanha https://api.nuvia.ai/api/docs/user-json get /v1/campaigns/{id}/analytics Métricas agregadas por contato único. # Analytics da campanha agrupados por step Source: https://developers.nuvia.ai/api-reference/campaigns/analytics-da-campanha-agrupados-por-step https://api.nuvia.ai/api/docs/user-json get /v1/campaigns/{id}/step-analytics # Arquivar campanha Source: https://developers.nuvia.ai/api-reference/campaigns/arquivar-campanha https://api.nuvia.ai/api/docs/user-json delete /v1/campaigns/{id} # Ativar campanha Source: https://developers.nuvia.ai/api-reference/campaigns/ativar-campanha https://api.nuvia.ai/api/docs/user-json post /v1/campaigns/{id}/activate # Atualizar campanha Source: https://developers.nuvia.ai/api-reference/campaigns/atualizar-campanha https://api.nuvia.ai/api/docs/user-json patch /v1/campaigns/{id} # Buscar campanha por ID Source: https://developers.nuvia.ai/api-reference/campaigns/buscar-campanha-por-id https://api.nuvia.ai/api/docs/user-json get /v1/campaigns/{id} # Contar campanhas por status Source: https://developers.nuvia.ai/api-reference/campaigns/contar-campanhas-por-status https://api.nuvia.ai/api/docs/user-json get /v1/campaigns/meta/count-by-status # Criar nova campanha Source: https://developers.nuvia.ai/api-reference/campaigns/criar-nova-campanha https://api.nuvia.ai/api/docs/user-json post /v1/campaigns # Disparar step manualmente Source: https://developers.nuvia.ai/api-reference/campaigns/disparar-step-manualmente https://api.nuvia.ai/api/docs/user-json post /v1/campaigns/{id}/steps/{stepId}/execute # Exportar contatos da campanha em CSV Source: https://developers.nuvia.ai/api-reference/campaigns/exportar-contatos-da-campanha-em-csv https://api.nuvia.ai/api/docs/user-json get /v1/campaigns/{id}/enrollments/export # Listar campanhas Source: https://developers.nuvia.ai/api-reference/campaigns/listar-campanhas https://api.nuvia.ai/api/docs/user-json get /v1/campaigns # Listar enrollments da campanha Source: https://developers.nuvia.ai/api-reference/campaigns/listar-enrollments-da-campanha https://api.nuvia.ai/api/docs/user-json get /v1/campaigns/{id}/enrollments # Listar execuções da campanha Source: https://developers.nuvia.ai/api-reference/campaigns/listar-execuções-da-campanha https://api.nuvia.ai/api/docs/user-json get /v1/campaigns/{id}/executions # Listar execuções de um enrollment específico Source: https://developers.nuvia.ai/api-reference/campaigns/listar-execuções-de-um-enrollment-específico https://api.nuvia.ai/api/docs/user-json get /v1/campaigns/{id}/enrollments/{enrollmentId}/executions # Pausar campanha Source: https://developers.nuvia.ai/api-reference/campaigns/pausar-campanha https://api.nuvia.ai/api/docs/user-json post /v1/campaigns/{id}/pause # Simular a audiência da campanha Source: https://developers.nuvia.ai/api-reference/campaigns/simular-a-audiência-da-campanha https://api.nuvia.ai/api/docs/user-json post /v1/campaigns/audience-preview Conta os contatos que seriam inscritos, com validação por canal. Nenhuma inscrição é criada. # Simular a mensagem da campanha Source: https://developers.nuvia.ai/api-reference/campaigns/simular-a-mensagem-da-campanha https://api.nuvia.ai/api/docs/user-json post /v1/campaigns/preview-message Resolve as variáveis do template a partir de uma linha de lista (`list_id` + `row_id`) ou de um contato (`contact_id`) e devolve a mensagem formatada. Nada é enviado. # MCP da Nuvia Source: https://developers.nuvia.ai/mcp-nuvia Conecte assistentes de IA (Claude, ChatGPT, Cursor) aos dados da sua empresa na Nuvia via MCP Assistentes de IA como o Claude e o ChatGPT são ótimos para conversar, mas não enxergam os dados da sua empresa. O **MCP** (Model Context Protocol) é um padrão aberto que faz essa ponte: com o servidor MCP da Nuvia, o seu assistente passa a acessar contatos, listas, conversas e campanhas da sua conta como **tools** que ele mesmo decide chamar durante a conversa. Você pede em linguagem natural, por exemplo *"crie uma lista com os leads de tecnologia em São Paulo"*, e ele busca, cria ou atualiza a informação para você, sem escrever código. As tools respeitam as **permissões e o consumo de créditos** da sua conta, exatamente como as ações feitas pela interface. ## MCP ou API REST? São dois caminhos diferentes, para usos diferentes: | | MCP | API REST | | ------------ | -------------------------------------------------- | -------------------------------------------------------- | | Para quê | Uso via **assistente de IA**, em linguagem natural | **Integração programática** (servidores, scripts) | | Autenticação | **OAuth 2.1** (login + autorização no cliente) | **API Key** (Bearer), veja [Autenticação](/autenticacao) | | Escopo | `mcp:tools` | escopos de API Key (`agents`, `contacts`, …) | O MCP **não** usa a API Key REST. A autenticação do MCP é **OAuth 2.1**, com o escopo `mcp:tools`: um sistema separado dos escopos de API Key. Não tente autenticar no MCP com uma API Key, nem reaproveitar os escopos REST aqui. O servidor MCP da Nuvia fica em `https://api.nuvia.ai/mcp` (transporte Streamable HTTP). Essa é a URL que você adiciona como conector no seu assistente de IA. ## Como conectar Apenas usuários com perfil **Usuário** ou **Admin** podem usar o MCP. O fluxo é o mesmo em clientes compatíveis como **claude.ai**, **Claude Desktop** e **Cursor**: No seu assistente de IA, adicione um conector MCP com a URL `https://api.nuvia.ai/mcp`. O cliente abre o fluxo OAuth da Nuvia. Faça login e clique em **Autorizar** para conceder o acesso. Peça em linguagem natural, mencionando o conector da Nuvia quando necessário. O passo a passo detalhado por aplicativo (com telas) muda com frequência e está no artigo oficial: [Como conectar o MCP da Nuvia](https://docs.nuvia.ai/pt-BR/articles/15422389-como-conectar-o-mcp-da-nuvia). ## Ferramentas disponíveis As tools cobrem ações equivalentes às da plataforma, organizadas em seis grupos. ### Busca Prospecção na base global e na base Brasil (CNPJ), e resolução de valores de filtro. | Ferramenta | O que faz | | ----------------------------- | ------------------------------------------------------------------------------------------------- | | `search_businesses` | Busca empresas na base global, por porte, país, indústria, receita, tecnologia usada, etc. | | `search_prospects` | Busca pessoas/decisores na base global, por cargo, senioridade, localização e firmografia. | | `search_brazil_companies` | Busca empresas brasileiras na base de CNPJ, por UF, CNAE, situação cadastral, porte, sócio, etc. | | `lookup_filter_values` | Resolve um termo livre (ex.: "software") no valor exato aceito pelos filtros da busca global. | | `lookup_brazil_filter_values` | Mesma função, para os filtros da base brasileira (CNAE, natureza jurídica, cidade, UF, etc.). | | `link_brazil_to_global` | Cruza uma empresa brasileira (pelo CNPJ) com a base global, para depois buscar seus decisores. | | `link_global_to_brazil` | Caminho inverso: a partir do domínio de uma empresa global, traz os dados cadastrais brasileiros. | ### Listas e registros Gerenciar listas de CRM e os registros dentro delas. | Ferramenta | O que faz | | --------------------- | ----------------------------------------------------------------------------------------------------------------- | | `list_lists` | Lista as listas de CRM da empresa, com nome, tipo (Contato/Empresa), colunas e quantidade de registros. | | `get_list` | Traz metadados e colunas detalhadas de uma lista: passo usado antes de adicionar ou atualizar registros. | | `create_list` | Cria uma lista, do tipo Contato ou Empresa (o tipo não muda depois de criada). Não verifica duplicidade por nome. | | `add_list_column` | Adiciona novas colunas a uma lista existente, preservando as atuais. | | `list_records` | Lista os registros (linhas) de uma lista, organizados por nome de coluna. | | `add_records` | Adiciona contatos ou empresas **já existentes no CRM** a uma lista. | | `update_record` | Atualiza uma linha da lista, mesclando com o que já existe (não apaga as demais colunas). | | `update_records` | Igual ao anterior, em lote (até 100 linhas por chamada). | | `save_search_results` | Salva os resultados de uma busca global como contatos/empresas no CRM, opcionalmente já em uma lista. Assíncrono. | | `get_save_status` | Consulta o andamento do salvamento até concluir. | `create_list` **não verifica duplicidade por nome**: pedir para criar a mesma lista duas vezes cria duas listas separadas. Como o pedido em linguagem natural facilita duplicar sem querer, confirme se a lista já existe antes de criar. Resultados de busca global **não entram direto** em uma lista: primeiro materialize-os como registros do CRM com `save_search_results`, depois referencie-os com `add_records`. ### Contatos Trabalha com a base de contatos da conta como um todo (não apenas dentro de uma lista). | Ferramenta | O que faz | | ------------------------ | ---------------------------------------------------------------------------------------------- | | `list_contacts` | Lista/busca contatos do CRM, por nome, e-mail ou telefone. | | `find_contacts_by_phone` | Resolve uma lista de telefones para os contatos correspondentes, útil para checar duplicidade. | | `create_contact` | Cria um contato (nome, DDI e telefone obrigatórios; e-mail, cargo e outros opcionais). | | `create_contacts` | Cria contatos em lote (até 100 por chamada). | | `update_contact` | Atualiza um contato existente (só os campos enviados são alterados). | | `update_contacts` | Atualiza contatos em lote (até 100 por chamada). | | `add_contact_note` | Adiciona uma anotação a um contato (até 5000 caracteres). | | `list_contact_notes` | Lista as anotações de um contato, da mais recente para a mais antiga. | Operações em lote não travam se um item falhar: a falha fica isolada e os demais itens são processados normalmente. ### Conversas | Ferramenta | O que faz | | -------------------- | -------------------------------------------------------------------------------------------------- | | `list_conversations` | Lista as conversas de atendimento, com contato, inbox, agente, status e resumo da última mensagem. | | `list_messages` | Lista o conteúdo de uma conversa (texto, tipo, remetente, data e anexos). | As tools de Conversas são **somente leitura**. O envio de mensagens **não** é exposto via MCP. Para responder ou disparar uma conversa, use a plataforma. ### Campanhas | Ferramenta | O que faz | | ---------------- | -------------------------------------------------------------------------------------------------- | | `list_campaigns` | Lista as campanhas da empresa (arquivadas não aparecem), com status, canal, métricas e remetentes. | | `get_campaign` | Traz os detalhes de uma campanha: status, canal, gatilho e métricas. | As tools de Campanhas são **somente leitura**. Criar, editar ou disparar campanhas continua sendo feito na plataforma. ### Enriquecimento | Ferramenta | O que faz | | ------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | | `enrich_list` | Dispara o enriquecimento de e-mail e/ou telefone dos contatos elegíveis de uma lista inteira ou de um recorte (view/filtros). Assíncrono. | | `get_enrich_status` | Consulta o andamento (0 a 100%) do enriquecimento. | **Créditos:** buscar e cruzar dados nunca consome crédito. A **única** tool que consome crédito é `enrich_list`: **e-mail = 1 crédito/contato** e **telefone = 10 créditos/contato**. O custo é proporcional ao número de contatos **elegíveis** no alvo, que pode ser a lista inteira ou um recorte (view/filtros). Por isso o assistente confirma o tamanho antes de disparar; atenção em listas grandes. ## Exemplos de uso Peça em linguagem natural. Alguns exemplos: * *"Utilize o conector da Nuvia para buscar contatos com o cargo 'Diretor de Marketing' em empresas de tecnologia no Brasil."* * *"Utilize o conector da Nuvia para criar uma lista chamada 'Leads Enterprise SP' do tipo Contato."* * *"Utilize o conector da Nuvia para enriquecer o e-mail e o telefone dos contatos da lista 'Leads Enterprise SP'."* Dependendo do assistente, pode ser necessário repetir "utilize o conector da Nuvia" a cada solicitação, sobretudo se você tiver outros conectores ativos com ações parecidas. ## Solução de problemas Se o conector aparecer inativo, peça ao assistente para chamar a tool `whoami`. Se a resposta não vier ou não trouxer o nome da sua empresa, refaça a autorização (login + **Autorizar**) na tela do cliente MCP. O passo a passo está em [Como conectar o MCP da Nuvia](https://docs.nuvia.ai/pt-BR/articles/15422389-como-conectar-o-mcp-da-nuvia). ## Auditoria Todas as chamadas ao MCP são auditadas. Na plataforma, acesse **Configurações → Auditoria MCP** para ver autenticações, sessões e chamadas de ferramentas feitas pela sua empresa. ## Próximos passos Artigo oficial com todos os detalhes e exemplos de uso. Para integração programática via API Key, veja o mapa de domínios.