API do Pingo

Com a API, o seu site, formulário, planilha ou sistema conversa com o Pingo: envia o lead já com a origem do anúncio, consulta, move de etapa no funil e puxa números. Ela vem a partir do plano Corrente e cada conta cria as próprias chaves.

  • Endereço base: https://www.pingotracker.com.br/api/v1
  • Tudo em JSON. Os nomes de campos, os códigos de erro e as permissões são em inglês (para o seu sistema tratar); as mensagens de erro são em português.
  • Datas em ISO 8601 (UTC). Telefone só com dígitos e código do país (ex.: 5541999990000). Valores em reais, como número.
  • Use sempre a partir do seu servidor. A chave nunca vai em página pública, app ou repositório aberto.

Começando em 4 passos

  1. 1. Confira o plano. A API vem no plano Corrente e acima. Sem ela, a tela de chaves mostra o convite para trocar de plano.
  2. 2. Crie a chave. No Pingo, vá em Configurações > API > Criar chave (só o dono da conta). Dê um nome (ex.: "Site da clínica"), marque só as permissões que esse sistema precisa e copie a chave: ela aparece uma única vez.
  3. 3. Guarde no servidor. Coloque a chave numa variável de ambiente, por exemplo PINGO_API_KEY.
  4. 4. Teste. Peça a lista de funis:
curl "https://www.pingotracker.com.br/api/v1/pipelines" \
  -H "Authorization: Bearer $PINGO_API_KEY"

Veio uma lista de funis com etapas? Está pronto. Os ids de funil e etapa dessa resposta são os que você usa para criar leads direto numa etapa ou para movê-los.

Autenticação

Toda chamada leva a chave no cabeçalho:

Authorization: Bearer pgo_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
  • A chave é de uma conta: ela só enxerga e só altera dados dessa conta. Nenhum id de outra conta funciona.
  • Chave ausente, mal formada, desconhecida ou revogada dão a mesma resposta (401 invalid_api_key).
  • Não há CORS de propósito: o navegador não consegue chamar a API, o que impede o uso da chave em página pública.
  • Vazou? Revogue em Configurações > API e crie outra. A revogação vale na hora. Quando a conta troca de dono, todas as chaves são revogadas.
  • Cada conta pode ter até 5 chaves ativas. Use uma por sistema, para revogar uma sem derrubar as outras.
  • O dono da conta recebe um aviso, no sino do Pingo e por e-mail, sempre que uma chave é criada ou revogada. Se não foi ele, é sinal para revogar na hora e trocar a senha.

Permissões da chave

Marque na criação só o que o sistema precisa. Uma chave só de escrita (para o formulário do site) não consegue ler a base de leads.

PermissãoO que liberaRotas
leads:readConsultar leads. Ler nome, telefone, e-mail, tags e negócios de qualquer lead da conta.GET /leads, POST /leads/lookup, GET /leads/{id}
leads:writeCriar e atualizar leads. Enviar leads novos (ex.: de um formulário do site) e atualizar nome, e-mail, tags e notas.POST /leads, PATCH /leads/{id}
pipeline:readVer funis e etapas. Listar os funis e as etapas.GET /pipelines
pipeline:writeMover lead de etapa. Mover o negócio de um lead de etapa (não fecha venda e não dispara mensagem).POST /leads/{id}/stage
metrics:readVer métricas. Ver números agregados (leads por período e por origem), sem dados de pessoas.GET /metrics

Respostas e erros

Sucesso devolve { "data": ... }; listas devolvem { "data": [...], "next_cursor": ... }. Erro devolve sempre o mesmo formato, e o cabeçalho X-Request-Id traz o mesmo identificador:

{
  "error": {
    "code": "validation_error",
    "message": "Alguns campos não passaram na validação.",
    "request_id": "req_9f2c41d07a3b86e5",
    "details": {
      "fields": [
        {
          "field": "phone",
          "message": "Telefone inválido. Envie com DDD (ex.: 41999990000) ou com +código do país."
        }
      ]
    }
  }
}

Ao falar com o suporte sobre uma chamada, informe o request_id. Trate o code no seu sistema (a mensagem pode mudar de texto).

CódigoHTTPSignificado
invalid_api_key401Chave ausente, mal formada, desconhecida ou revogada (a resposta é a mesma nos quatro casos).
api_not_enabled403O plano da conta não inclui a API (ela vem a partir do plano Corrente).
plan_inactive403A licença da conta não está ativa.
comercial_not_enabled403O módulo Comercial não está ligado na conta.
insufficient_scope403A chave não tem a permissão que esta rota exige.
invalid_json400O corpo não é um JSON válido.
payload_too_large413O corpo passa de 16 KB.
validation_error422Algum campo não passou na validação. error.details.fields diz quais.
not_found404O recurso não existe na conta (ou é de outra conta: a resposta é igual).
ambiguous_lead409Mais de um cadastro com o mesmo contato.
external_id_conflict409O external_id já foi usado em um envio de outro telefone.
ambiguous_deal409O lead tem mais de um negócio aberto no funil; informe deal_id.
pipeline_not_configured409O funil não tem etapa de entrada.
stage_in_other_pipeline409A etapa é de outro funil. (Em POST /leads vem como 422.)
won_requires_closing409Etapa de ganho: o fechamento é registrado no Pingo. (Em POST /leads vem como 422.)
deal_already_won409O negócio já está em etapa de ganho e não sai dela pela API.
notes_full409A ficha do lead não comporta mais texto.
rate_limited429Muitas requisições. Espere o tempo do cabeçalho Retry-After.
internal_error500Erro do nosso lado. Informe o request_id ao suporte.

Listas e o cursor: devolva em cursor o next_cursor da resposta anterior até ele vir null.

Limites

RegraLimite
Por endereço de IP (todas as chaves)300 chamadas por minuto
Por chave120 chamadas por minuto
Gravações por chave (POST e PATCH; a busca POST /leads/lookup só lê e não entra aqui)60 por minuto
GET /metrics por chave20 por minuto
Envios de lead por conta (POST /leads)3.000 por dia
Tamanho do corpo16 KB
Chaves ativas por conta5

Passou do limite? A resposta é 429 rate_limited com o cabeçalho Retry-After (segundos). Espere esse tempo antes de tentar de novo. Se você reenvia leads, mande external_id: repetir a chamada não duplica nada.

Origem do lead

Você não diz de onde o lead veio: manda os sinais que tem (attribution) e o Pingo calcula a origem com a mesma regra do resto do aplicativo. É o que faz o lead do seu site aparecer no Pingo com a origem (Meta, Google, busca, direto...) e a campanha que você informou em utm_campaign. A API só registra a origem: ela nunca envia conversão para o Meta ou o Google. Os eventos de conversão saem pelas etapas do funil de marketing, quando o Pixel está configurado e a equipe marca a venda.

Sinais recebidosOrigem gravada
utm_source ou utm_medium com facebook, instagram, meta, fb ou ig, e vem fbclid (ou fbc)meta_ads (anúncio do Meta)
Mesmo utm de Meta, SEM fbclid nem fbc (mesmo que o utm_medium seja cpc ou paid)social (rede social, sem clique de anúncio)
utm de Google (google, adwords, gads ou youtube) e vem gclid, gbraid, wbraid ou gad_source (mesmo com utm_medium organic)google_ads (anúncio do Google)
Mesmo utm de Google, SEM nenhum desses quatro sinais (mesmo que o utm_medium seja cpc)organic_google (busca orgânica)
Qualquer outro utm_source ou utm_medium (mesmo com gclid ou fbclid junto)organic
Sem utm, com gclid, gbraid, wbraid ou gad_sourcegoogle_ads
Sem utm e sem sinal do Google, com fbclid (ou fbc)meta_ads
Sem utm nem clique, referrer do Googleorganic_google
Sem utm nem clique, referrer de Instagram, Facebook, Threads, X/Twitter, TikTok, linktr.ee, bio.link, beacons.ai ou t.cosocial
Sem utm nem clique, qualquer outro referrerreferral
Nenhum sinaluntracked (Não rastreado)
  • Primeiro contato vence. Se o lead já tem uma origem registrada (qualquer uma diferente de untracked e direct, inclusive social, organic e referral), uma chamada nova não muda nenhum dado de origem dele. Se a origem é untracked ou direct, o Pingo preenche a origem e só os campos que ainda estão vazios.
  • Guarde os parâmetros da URL (utm_*, gclid, fbclid) quando a pessoa chega no site e mande junto com o formulário. Sem eles o lead entra como untracked (Não rastreado).
  • origin e utm só aparecem nas respostas se o plano da conta inclui a Origem automática; a origem é gravada de qualquer forma.
  • O utm decide primeiro; só sem utm entram os cliques e o referrer. Quando o utm cita Meta e Google ao mesmo tempo, vale o Meta; sem utm, o Google vence o Meta.
  • Envie os sinais da PRIMEIRA visita (guarde em cookie ou localStorage), não o referrer da página do formulário: depois de navegar dentro do site, esse referrer é o próprio site e vira referral.
  • O referrer precisa ser a URL completa, com https://. Só o endereço do site e o caminho são guardados (o que vem depois do ? é descartado).
  • Sem fbclid, um lead de anúncio do Meta fica como social. Sem gclid, gbraid, wbraid ou gad_source, um lead de anúncio do Google fica como organic_google.
  • O utm é lido por "contém": textos como "digital" ou "design" (que contêm "ig") são lidos como Meta. Use nomes claros em utm_source (google, facebook, instagram, newsletter...).
  • Só o Google conta como busca orgânica. Bing e DuckDuckGo entram como referral.
  • untracked (Não rastreado) é o lead sem nenhum sinal: a equipe pode preencher a origem à mão no Chat. Ele também aparece em origin e em by_origin.
  • utm_content e utm_term são guardados na resposta do formulário, mas não entram no cálculo da origem.
  • Um lead antigo que estava como untracked ou direct pode ter a origem preenchida uma vez, quando a API trouxer sinais. Isso muda o by_origin do período em que ele foi criado.

Receita: formulário do site

O caso mais comum. O formulário envia para o seu servidor, e o servidor chama o Pingo com a chave. Assim a chave não fica exposta e você controla o que é enviado.

// Next.js (app router): app/api/contato/route.ts
// A chave fica só no servidor (variável de ambiente), nunca no código que vai para o navegador.
export async function POST(req: Request) {
  // O navegador manda os utm que guardou da URL e um envioId gerado UMA vez por formulário (ex.: crypto.randomUUID() quando a página carrega).
  const { nome, telefone, email, utm, envioId } = await req.json();

  const resposta = await fetch("https://www.pingotracker.com.br/api/v1/leads", {
    method: "POST",
    headers: {
      Authorization: `Bearer ${process.env.PINGO_API_KEY}`,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      name: nome,
      phone: telefone,
      email,
      tags: ["site"],
      external_id: envioId, // o mesmo envioId em toda repetição do MESMO envio (clique duplo, nova tentativa): o lead não duplica
      attribution: {
        utm_source: utm?.source,
        utm_medium: utm?.medium,
        utm_campaign: utm?.campaign,
        gclid: utm?.gclid,
        fbclid: utm?.fbclid,
        referrer: utm?.referrer,
      },
    }),
  });

  return Response.json({ ok: resposta.ok }, { status: resposta.ok ? 200 : 502 });
}

Endpoints

Leads

POST/leadspermissão leads:write

Criar ou atualizar um lead

Cria o lead e o coloca no funil. Se já existe cadastro com o mesmo telefone, atualiza em vez de duplicar.

  • O telefone é o que identifica o lead. O Pingo reconhece o mesmo número com ou sem o 9º dígito e com ou sem o 55, então reenviar "41 99999-0000" e "+55 41 9196-8668" não cria dois cadastros.
  • Você NÃO envia a origem. Ela é calculada pelo Pingo a partir dos sinais de attribution (utm_source, utm_medium, fbclid, gclid...), com a mesma regra do resto do aplicativo. Sem nenhum sinal, o lead fica como untracked (Não rastreado). Sinal com formato inválido é ignorado e voltado num aviso (warnings), sem derrubar o lead.
  • Vale o primeiro contato: se o lead já tem uma origem registrada (qualquer uma diferente de untracked e direct, inclusive social, organic e referral), a chamada não muda nenhum dado de origem dele (utm, fbc, gclid...). Se a origem é untracked ou direct, o Pingo preenche a origem e só os campos de origem que ainda estão vazios, então a origem de um lead antigo pode mudar uma única vez.
  • Para repetir o envio com segurança (formulário reenviado, webhook que chega duas vezes), mande um external_id único por envio. Com o mesmo external_id, o Pingo devolve duplicate: true e não grava nada de novo.
  • O lead entra na etapa de entrada do funil padrão. Para outro funil ou etapa, informe deal.pipeline_id e deal.stage_id (veja GET /pipelines). Se o lead já tem negócio aberto nesse funil, ele NÃO é movido: para mover, use POST /leads/{id}/stage.
  • Esta chamada só grava. Não envia mensagem ao lead e não dispara NA HORA nenhuma automação do funil. Atenção: se a etapa tem uma automação por tempo (por exemplo, follow-up para quem fica parado há alguns dias), ela passa a valer para o lead da API como vale para qualquer outro lead.
  • A nota (notes) é acrescentada à ficha do lead, marcada com [API · nome da chave · data], sem apagar o que a equipe já escreveu. Tags novas são criadas na conta (até 5 por chamada).
  • Uma chave SEM leads:read (a de um formulário, por exemplo) recebe sempre a mesma resposta curta, { "received": true } com status 202, seja o lead novo ou já existente: assim a chave de escrita não serve para descobrir quem já é cliente. Com leads:read, a resposta traz id, created, duplicate, deal e o cadastro (lead); created: false (status 200) quer dizer que o telefone já era conhecido no Pingo (cadastro ou conversa).

Corpo (JSON)

CampoTipoDescrição
phoneobrigatóriotextoTelefone com DDD (ex.: 41999990000) ou com + e código do país (ex.: +14155550123). Pode vir com espaço, parênteses e traço; letras e ramal são recusados. Número com 10 ou 11 dígitos sem + só é aceito se for brasileiro de verdade (DDD que existe); um zero antes do DDD (041...) é tirado.
nametexto (até 120)Nome do lead. Em um cadastro que já existe, o nome não é sobrescrito.
emailtextoE-mail. Só preenche se o cadastro ainda não tem e-mail.
notestexto (até 500)Observação acrescentada à ficha do lead.
tagslista de textos (até 5, cada uma até 40)Tags aplicadas ao lead. As que não existem são criadas.
external_idtexto (até 100; letras, números e . _ : @ -)Identificador DO ENVIO na sua origem (um por envio, não um valor fixo). Repetir o mesmo valor com o mesmo telefone não duplica nada; o mesmo valor com OUTRO telefone dá 409 external_id_conflict.
consentverdadeiro/falsoSe true, registra o consentimento LGPD do lead. Nunca remove um consentimento já dado.
attributionobjetoSinais de origem, todos texto e opcionais: utm_source, utm_medium, utm_campaign, utm_content, utm_term, fbclid, fbc (o valor do cookie _fbc do Meta, se você o tiver), gclid, gbraid, wbraid, gad_source e referrer (URL completa, com https://; só o endereço e o caminho são guardados). Os identificadores de clique (fbclid, gclid, gbraid, wbraid) têm letras, números, _ e - (8 a 500 caracteres); fora disso são ignorados com aviso.
deal.pipeline_idtextoFunil de destino. Sem isto, vale o funil padrão.
deal.stage_idtextoEtapa de destino (do mesmo funil). Não pode ser etapa de ganho.
deal.valuenúmeroValor PREVISTO do negócio em reais, quando o negócio é criado agora (não é venda fechada). Se o funil da conta tem uma automação que envia conversão ao Meta, ela pode usar esse valor quando o negócio for movido no Pingo.
curl -X POST "https://www.pingotracker.com.br/api/v1/leads" \
  -H "Authorization: Bearer $PINGO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Maria Silva",
    "phone": "41999990000",
    "email": "maria@exemplo.com.br",
    "notes": "Quer horário à tarde",
    "tags": [
      "site"
    ],
    "external_id": "form-2026-0001",
    "consent": true,
    "attribution": {
      "utm_source": "google",
      "utm_medium": "cpc",
      "utm_campaign": "implante-curitiba",
      "gclid": "Cj0KCQjwExemploGclid123",
      "referrer": "https://www.google.com/"
    },
    "deal": {
      "value": 1500.5
    }
  }'

Resposta 201

{
  "data": {
    "id": "cm1lead0000000000000000a1",
    "created": true,
    "duplicate": false,
    "deal": {
      "id": "cm1negoc0000000000000000a1",
      "pipeline_id": "cm1funil000000000000000a1",
      "stage_id": "cm1etapa000000000000entr1",
      "status": "open",
      "value": 1500.5,
      "entered_stage_at": "2026-10-15T13:20:11.000Z",
      "created_at": "2026-10-15T13:20:11.000Z"
    },
    "lead": {
      "id": "cm1lead0000000000000000a1",
      "name": "Maria Silva",
      "phone": "5541999990000",
      "email": "maria@exemplo.com.br",
      "tags": [
        "site",
        "vip"
      ],
      "origin": "google_ads",
      "utm": {
        "source": "google",
        "medium": "cpc",
        "campaign": "implante-curitiba"
      },
      "deals": [
        {
          "id": "cm1negoc0000000000000000a1",
          "pipeline_id": "cm1funil000000000000000a1",
          "stage_id": "cm1etapa000000000000entr1",
          "status": "open",
          "value": 1500.5,
          "entered_stage_at": "2026-10-15T13:20:11.000Z",
          "created_at": "2026-10-15T13:20:11.000Z"
        }
      ],
      "created_at": "2026-10-15T13:20:11.000Z",
      "updated_at": "2026-10-15T13:20:11.000Z"
    }
  }
}

Resposta 202: Chave sem leads:read (só escrita): resposta uniforme

{
  "data": {
    "received": true
  }
}

Erros desta rota (além dos gerais)

HTTPCódigoQuando
409ambiguous_leadHá mais de um cadastro com este telefone no Pingo. Resolva a duplicidade no Pingo. (Chave sem leads:read recebe a resposta curta 202 e o envio não é aplicado.)
409external_id_conflictO external_id já foi usado em um envio de outro telefone.
409pipeline_not_configuredO funil informado não tem etapa de entrada.
422validation_errorCampo inválido, campo desconhecido, telefone inválido ou funil/etapa que não existe na conta.
422stage_in_other_pipelineA etapa informada não é do funil informado.
422won_requires_closingA etapa é de ganho: o fechamento (valor) é registrado no Pingo, não pela API.
GET/leadspermissão leads:read

Listar leads

Lista os leads da conta, de 100 em 100 no máximo, com filtros que não são dado pessoal.

  • As páginas são por cursor: devolva em cursor o next_cursor da resposta anterior até ele vir null.
  • Para sincronizar de tempos em tempos, use updated_since com a hora da última sincronização menos 5 minutos de folga. A data de atualização do lead considera também a mudança de etapa dos negócios. Um lead pode aparecer mais de uma vez em sincronizações seguidas; trate pelo id.
  • Para achar UM lead por telefone ou e-mail, use POST /leads/lookup (telefone e e-mail não devem ir na URL).
  • origin e utm só aparecem se o plano da conta inclui a Origem automática.

Parâmetros da consulta

CampoTipoDescrição
limitinteiro (1 a 100)Quantos leads por página. Padrão 50.
cursortextoO next_cursor da página anterior.
pipeline_idtextoSó leads com negócio neste funil.
stage_idtextoSó leads com negócio nesta etapa.
tagtextoSó leads com esta tag (sem diferenciar maiúscula).
updated_sincedata e hora ISO 8601Só leads atualizados a partir deste momento.
curl -X GET "https://www.pingotracker.com.br/api/v1/leads?limit=50&updated_since=2026-10-15T00%3A00%3A00Z" \
  -H "Authorization: Bearer $PINGO_API_KEY"

Resposta 200

{
  "data": [
    {
      "id": "cm1lead0000000000000000a1",
      "name": "Maria Silva",
      "phone": "5541999990000",
      "email": "maria@exemplo.com.br",
      "tags": [
        "site",
        "vip"
      ],
      "origin": "google_ads",
      "utm": {
        "source": "google",
        "medium": "cpc",
        "campaign": "implante-curitiba"
      },
      "deals": [
        {
          "id": "cm1negoc0000000000000000a1",
          "pipeline_id": "cm1funil000000000000000a1",
          "stage_id": "cm1etapa000000000000entr1",
          "status": "open",
          "value": 1500.5,
          "entered_stage_at": "2026-10-15T13:20:11.000Z",
          "created_at": "2026-10-15T13:20:11.000Z"
        }
      ],
      "created_at": "2026-10-15T13:20:11.000Z",
      "updated_at": "2026-10-15T13:20:11.000Z"
    }
  ],
  "next_cursor": null
}

Erros desta rota (além dos gerais)

HTTPCódigoQuando
422validation_errorParâmetro inválido ou desconhecido (ex.: limit acima de 100).
POST/leads/lookuppermissão leads:read

Achar um lead por telefone ou e-mail

Devolve o lead que tem aquele telefone (ou e-mail). É POST de propósito: dado pessoal não deve ir na URL.

  • Informe exatamente um entre phone e email.
  • O telefone é comparado com e sem o 9º dígito e com e sem o 55. O e-mail não diferencia maiúscula. Número de outro país vai com o + na frente (ex.: +14155550123), mesmo que a resposta o traga só com dígitos: sem o +, 10 ou 11 dígitos só valem se forem brasileiros.
  • Se houver mais de um cadastro com o mesmo contato, a resposta é 409 (ambiguous_lead): a API não adivinha qual é o certo.

Corpo (JSON)

CampoTipoDescrição
phonetextoTelefone a procurar.
emailtextoE-mail a procurar (use este OU o telefone).
curl -X POST "https://www.pingotracker.com.br/api/v1/leads/lookup" \
  -H "Authorization: Bearer $PINGO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "phone": "41999990000"
  }'

Resposta 200

{
  "data": {
    "id": "cm1lead0000000000000000a1",
    "name": "Maria Silva",
    "phone": "5541999990000",
    "email": "maria@exemplo.com.br",
    "tags": [
      "site",
      "vip"
    ],
    "origin": "google_ads",
    "utm": {
      "source": "google",
      "medium": "cpc",
      "campaign": "implante-curitiba"
    },
    "deals": [
      {
        "id": "cm1negoc0000000000000000a1",
        "pipeline_id": "cm1funil000000000000000a1",
        "stage_id": "cm1etapa000000000000entr1",
        "status": "open",
        "value": 1500.5,
        "entered_stage_at": "2026-10-15T13:20:11.000Z",
        "created_at": "2026-10-15T13:20:11.000Z"
      }
    ],
    "created_at": "2026-10-15T13:20:11.000Z",
    "updated_at": "2026-10-15T13:20:11.000Z"
  }
}

Erros desta rota (além dos gerais)

HTTPCódigoQuando
404not_foundNenhum lead com esse contato.
409ambiguous_leadMais de um cadastro com esse contato.
422validation_errorTelefone inválido, ou os dois (ou nenhum) informados.
GET/leads/{id}permissão leads:read

Consultar um lead

Devolve o lead pelo id, com tags, origem e negócios.

  • Um id que não existe na sua conta e um id de outra conta dão exatamente a mesma resposta: 404.

Parâmetros do caminho

CampoTipoDescrição
idobrigatóriotextoO id do lead.
curl -X GET "https://www.pingotracker.com.br/api/v1/leads/ID_DO_LEAD" \
  -H "Authorization: Bearer $PINGO_API_KEY"

Resposta 200

{
  "data": {
    "id": "cm1lead0000000000000000a1",
    "name": "Maria Silva",
    "phone": "5541999990000",
    "email": "maria@exemplo.com.br",
    "tags": [
      "site",
      "vip"
    ],
    "origin": "google_ads",
    "utm": {
      "source": "google",
      "medium": "cpc",
      "campaign": "implante-curitiba"
    },
    "deals": [
      {
        "id": "cm1negoc0000000000000000a1",
        "pipeline_id": "cm1funil000000000000000a1",
        "stage_id": "cm1etapa000000000000entr1",
        "status": "open",
        "value": 1500.5,
        "entered_stage_at": "2026-10-15T13:20:11.000Z",
        "created_at": "2026-10-15T13:20:11.000Z"
      }
    ],
    "created_at": "2026-10-15T13:20:11.000Z",
    "updated_at": "2026-10-15T13:20:11.000Z"
  }
}

Erros desta rota (além dos gerais)

HTTPCódigoQuando
404not_foundLead não encontrado na conta.
PATCH/leads/{id}permissão leads:write

Atualizar um lead

Muda nome, e-mail, tags e acrescenta uma nota. O telefone não muda por aqui.

  • Envie só o que quer mudar, ao menos um campo.
  • email: null apaga o e-mail. add_tags cria as tags que não existem; remove_tags ignora as que não existem. O telefone não pode ser alterado (ele liga o cadastro à conversa do WhatsApp).
  • A mudança vale só no Pingo: o cadastro do seu sistema de gestão (Feegow, Clinicorp, Conta Azul...) não é alterado, então os dois podem ficar diferentes.
  • A nota é acrescentada à ficha, nunca substitui. Se a ficha não comporta mais texto (limite de 2.000 caracteres), a resposta é 409 notes_full e NADA é alterado.

Parâmetros do caminho

CampoTipoDescrição
idobrigatóriotextoO id do lead.

Corpo (JSON)

CampoTipoDescrição
nametexto (até 120)Novo nome.
emailtexto ou nullNovo e-mail, ou null para apagar.
add_tagslista de textos (até 5)Tags a acrescentar.
remove_tagslista de textos (até 5)Tags a retirar.
notestexto (até 500)Nota acrescentada à ficha.
curl -X PATCH "https://www.pingotracker.com.br/api/v1/leads/ID_DO_LEAD" \
  -H "Authorization: Bearer $PINGO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Maria Silva",
    "add_tags": [
      "retorno"
    ],
    "remove_tags": [
      "site"
    ],
    "notes": "Ligar na quinta"
  }'

Resposta 200

{
  "data": {
    "id": "cm1lead0000000000000000a1",
    "updated": true,
    "lead": {
      "id": "cm1lead0000000000000000a1",
      "name": "Maria Silva",
      "phone": "5541999990000",
      "email": "maria@exemplo.com.br",
      "tags": [
        "site",
        "vip"
      ],
      "origin": "google_ads",
      "utm": {
        "source": "google",
        "medium": "cpc",
        "campaign": "implante-curitiba"
      },
      "deals": [
        {
          "id": "cm1negoc0000000000000000a1",
          "pipeline_id": "cm1funil000000000000000a1",
          "stage_id": "cm1etapa000000000000entr1",
          "status": "open",
          "value": 1500.5,
          "entered_stage_at": "2026-10-15T13:20:11.000Z",
          "created_at": "2026-10-15T13:20:11.000Z"
        }
      ],
      "created_at": "2026-10-15T13:20:11.000Z",
      "updated_at": "2026-10-15T13:20:11.000Z"
    }
  }
}

Erros desta rota (além dos gerais)

HTTPCódigoQuando
404not_foundLead não encontrado na conta.
409notes_fullA ficha do lead está cheia. Nada foi alterado.
422validation_errorCampo inválido ou desconhecido (inclusive phone), ou corpo vazio.

Funil

POST/leads/{id}/stagepermissão pipeline:write

Mover o lead de etapa

Move o negócio aberto do lead para outra etapa do mesmo funil.

  • Mover pela API NÃO dispara a automação da etapa: não manda mensagem ao lead e não envia conversão ao Meta. É o mesmo que mover em massa no Pingo sem marcar "disparar a automação". Automações por tempo da etapa nova ("parado há N dias") continuam valendo.
  • A API não entra em etapa de ganho (fechar exige registrar o valor no Pingo) e não tira o negócio de uma etapa de ganho (não desfaz venda). Mover para uma etapa de perda e reabrir (sair da perda) funcionam.
  • Se o lead tem mais de um negócio aberto no funil da etapa, informe deal_id. Mover para a etapa em que o negócio já está devolve changed: false.

Parâmetros do caminho

CampoTipoDescrição
idobrigatóriotextoO id do lead.

Corpo (JSON)

CampoTipoDescrição
stage_idobrigatóriotextoEtapa de destino (veja GET /pipelines).
deal_idtextoNegócio a mover, quando o lead tem mais de um aberto no funil.
curl -X POST "https://www.pingotracker.com.br/api/v1/leads/ID_DO_LEAD/stage" \
  -H "Authorization: Bearer $PINGO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "stage_id": "cm1etapa00000000000000pre1"
  }'

Resposta 200

{
  "data": {
    "changed": true,
    "deal": {
      "id": "cm1negoc0000000000000000a1",
      "pipeline_id": "cm1funil000000000000000a1",
      "stage_id": "cm1etapa00000000000000pre1",
      "status": "open",
      "value": 1500.5,
      "entered_stage_at": "2026-10-15T14:02:40.000Z",
      "created_at": "2026-10-15T13:20:11.000Z"
    }
  }
}

Erros desta rota (além dos gerais)

HTTPCódigoQuando
404not_foundLead, etapa ou negócio não encontrado na conta, ou o lead não tem negócio aberto nesse funil.
409ambiguous_dealMais de um negócio aberto no funil da etapa. Informe deal_id.
409stage_in_other_pipelineA etapa é de outro funil que o do negócio.
409won_requires_closingA etapa é de ganho.
409deal_already_wonO negócio já está numa etapa de ganho.
GET/pipelinespermissão pipeline:read

Listar funis e etapas

Os funis da conta com suas etapas: são os ids que POST /leads e POST /leads/{id}/stage pedem.

  • O funil padrão vem primeiro. is_entry marca a etapa onde o lead novo nasce; is_won e is_lost marcam as etapas de ganho e de perda.
curl -X GET "https://www.pingotracker.com.br/api/v1/pipelines" \
  -H "Authorization: Bearer $PINGO_API_KEY"

Resposta 200

{
  "data": [
    {
      "id": "cm1funil000000000000000a1",
      "name": "Comercial",
      "is_default": true,
      "stages": [
        {
          "id": "cm1etapa000000000000entr1",
          "name": "Leads de Entrada",
          "order": 0,
          "is_entry": true,
          "is_won": false,
          "is_lost": false
        },
        {
          "id": "cm1etapa00000000000000pre1",
          "name": "Pré Vendas",
          "order": 1,
          "is_entry": false,
          "is_won": false,
          "is_lost": false
        },
        {
          "id": "cm1etapa000000000000fech1",
          "name": "Fechado",
          "order": 5,
          "is_entry": false,
          "is_won": true,
          "is_lost": false
        },
        {
          "id": "cm1etapa000000000000perd1",
          "name": "Perdido (sem contato)",
          "order": 6,
          "is_entry": false,
          "is_won": false,
          "is_lost": true
        }
      ]
    }
  ]
}

Métricas

GET/metricspermissão metrics:read

Métricas do período

Números agregados da conta (leads por dia e por origem, negócios por etapa). Nenhum dado de pessoa.

  • O período vai de from a to, os dois inclusive, em dias de Brasília (padrão: os últimos 30 dias; no máximo 366 dias).
  • leads conta as conversas criadas no período, de qualquer canal (WhatsApp, formulários, API). Dias sem lead não aparecem em daily. scheduled conta os leads do período que estão AGORA numa etapa de agendamento: quem já avançou para outra etapa deixa de contar. closed conta os que estão numa etapa de venda ou numa etapa com valor configurado (uma etapa "Agendou R$ 450" conta). Os dois são null se a conta não configurou a etapa. attended são as consultas com comparecimento na agenda do período.
  • pipeline.stages[].open_deals é o retrato de HOJE (negócios abertos por etapa), não depende do período.
  • by_origin só aparece se o plano da conta inclui a Origem automática. Receita não faz parte desta versão.
  • Esta rota é mais pesada: limite de 20 chamadas por minuto por chave.

Parâmetros da consulta

CampoTipoDescrição
fromdata AAAA-MM-DDPrimeiro dia do período.
todata AAAA-MM-DDÚltimo dia do período (inclusive).
pipeline_idtextoFunil para o retrato de negócios por etapa. Padrão: o funil padrão.
curl -X GET "https://www.pingotracker.com.br/api/v1/metrics?from=2026-10-01&to=2026-10-15" \
  -H "Authorization: Bearer $PINGO_API_KEY"

Resposta 200

{
  "data": {
    "period": {
      "from": "2026-10-01",
      "to": "2026-10-15"
    },
    "leads": 128,
    "scheduled": 31,
    "closed": 9,
    "attended": 24,
    "daily": [
      {
        "date": "2026-10-14",
        "leads": 9
      },
      {
        "date": "2026-10-15",
        "leads": 12
      }
    ],
    "by_origin": [
      {
        "origin": "google_ads",
        "leads": 60
      },
      {
        "origin": "meta_ads",
        "leads": 48
      },
      {
        "origin": "direct",
        "leads": 20
      }
    ],
    "pipeline": {
      "id": "cm1funil000000000000000a1",
      "name": "Comercial",
      "stages": [
        {
          "id": "cm1etapa000000000000entr1",
          "name": "Leads de Entrada",
          "open_deals": 14
        },
        {
          "id": "cm1etapa00000000000000pre1",
          "name": "Pré Vendas",
          "open_deals": 22
        }
      ]
    }
  }
}

Erros desta rota (além dos gerais)

HTTPCódigoQuando
404not_foundpipeline_id não existe na conta.
422validation_errorData inválida, período invertido ou maior que 366 dias.

O que a API não faz

  • Não envia mensagem de WhatsApp nem de Instagram.
  • Não dispara as automações do funil na hora: criar ou mover um lead pela API só grava, não manda mensagem nem conversão ao Meta. Automações por tempo da etapa (como o follow-up de quem fica parado há alguns dias) continuam valendo para o lead da API.
  • Não fecha negócio nem registra valor de venda: etapa de ganho é recusada (o fechamento é feito no Pingo).
  • Não apaga lead, não lê conversas e não troca o telefone de um lead.
  • Não avisa o seu sistema quando algo muda (sem webhooks de saída nesta versão): para acompanhar mudanças, consulte GET /leads?updated_since=... de tempos em tempos.

Postman e OpenAPI

A coleção do Postman já vem com todas as rotas, exemplos e a variável api_key para você colar a chave. O arquivo OpenAPI serve para gerar clientes de código e importar em outras ferramentas.

Dúvidas ou algo que a API ainda não cobre? Escreva para contato@pingotracker.com.br com o request_id da chamada, se houver.