Ir para o conteúdo
Para desenvolvedores

API do Digiflow

Conecte o site, o aplicativo ou o ERP do seu cliente ao CRM. Chave com escopo, JSON dos dois lados e especificação OpenAPI para importar no Postman.

Começando

Três passos até a primeira chamada

Escrita e leitura na mesma chave: o sistema de fora manda lead, evento e pedido, e consulta contatos, negócios, funis e agenda. Não existe parâmetro de conta na URL, a chave já diz de quem é o dado, e nunca enxerga outra conta.

01

Peça a chave ao administrador

Quem cria é o administrador da conta, no CRM, em Configurações → API. A chave começa com df_, pode ter validade e aparece uma vez só na tela: depois nem o suporte enxerga o valor.

02

A chave carrega os escopos marcados

Cada chave faz só o que foi liberado nela: leads:write, eventos:write, pedidos:write, contatos:read, negocios:read e agenda:read. Fora do escopo, 403. O administrador revoga e gera outra quando precisar.

03

Mande a primeira chamada

Todo endpoint aceita e responde JSON, com erro em português. Um lead de teste percorre o caminho inteiro, do POST até o card no funil.

Endereço e autenticação

Mande a chave no cabeçalho Authorization. Plataformas que não deixam editar esse cabeçalho podem usar X-Api-Key com o mesmo valor.

cabeçalhos
# Endereço base
https://app.digiflow.systems

Authorization: Bearer df_sua_chave
Content-Type: application/json

Importar no Postman

Import → Link com o endereço abaixo traz os endpoints com campos, exemplos e limites; falta só a chave. O mesmo arquivo serve para Insomnia, Swagger Editor e geradores de cliente.

OpenAPI 3.1
https://app.digiflow.systems/api/openapi.json

Referência

Endpoints

Integre sistemas externos ao CRM Digiflow.

API para sistemas externos mandarem informação para dentro do CRM: cadastrar lead de um formulário próprio, avisar que algo aconteceu com um lead que já existe, e enviar pedidos de um ERP ou PDV.

Todo endpoint é autenticado por uma chave de API da conta, criada pelo administrador em Configurações → API dentro do CRM. A chave identifica a conta: não existe parâmetro de conta na URL nem no corpo, e uma chave nunca enxerga dados de outra conta.

Escopos. Cada chave faz só o que o administrador marcou ao criá-la: leads:write (cadastrar leads), eventos:write (avisar acontecimentos), pedidos:write (enviar pedidos), contatos:read, negocios:read e agenda:read (consultas). Chamar um endpoint sem o escopo devolve 403. A chave pode ter validade, e vencida devolve 401.

Campos do contato. Para contatos:read, o administrador escolhe campo a campo o que a chave enxerga. Dado sensível (data de nascimento, anotações, campos customizados) fica fora por padrão: peça só o que a integração precisa (princípio do mínimo necessário da LGPD). Campos não liberados simplesmente não vêm na resposta.

Leitura. Listas são paginadas (page a partir de 1, limit até 200, padrão 50) e respondem { data, page, limit, total, has_more }. Use updated_since para sincronizar só o que mudou desde a última chamada. Limite: 120 chamadas por minuto por chave.

POST/api/webhooks/forms

Cadastrar ou atualizar um lead

Recebe o envio de um formulário externo e cria o contato no CRM, ou atualiza se ele já existir. O contato é procurado pelo telefone (chave única por conta) e, quando não vem telefone, pelo e-mail: mandar o mesmo lead duas vezes não duplica cadastro.

Contato novo entra sozinho na primeira etapa do funil principal, recebe um responsável pela regra de distribuição da conta, gera aviso no sino e dispara os gatilhos de automação form_submitted e contact_created.

Origem: mande source quando souber. Se não mandar, a origem é deduzida dos parâmetros de rastreio (gclid vira Google Ads, fbclid vira Meta Ads, e assim por diante), o que costuma ser mais fiel do que o formulário adivinhar.

Limite: 30 chamadas por minuto por IP.

Corpo da requisição

Informe pelo menos telefone ou e-mail.

CampoTipoO que é
nametextoNome de quem preencheu
phonetextoTelefone em qualquer formato; o CRM normaliza para E.164. É a chave que evita duplicar.
emaile-mailUsado para deduplicar quando não vem telefone
sourcetexto (lista fechada)Origem do lead. Sem este campo, é deduzida do rastreio abaixo.meta_ads_facebookmeta_ads_instagramgoogle_adslinkedin_adstiktok_adswhatsappinstagramfacebooklinkedinsitegoogle_organicoindicacaoformmanualemail_inboundeventooutro
source_detailtextoDetalhe livre da origem: nome da campanha, do conjunto, do criativo.
websitetextoSite do contato ou da empresa dele. Fica gravado no cadastro.
custom_fieldsobjeto livreCampos extras que vão para a ficha do contato. Precisam existir em Configurações → Campos customizados para aparecerem na tela.
utm_sourcetextoParâmetro de rastreio da página
utm_mediumtextoParâmetro de rastreio da página
utm_campaigntextoVira o detalhe da origem quando source_detail não vem
gclidtextoIdentificador de clique do Google Ads
wbraidtextoUsado pelo Google no lugar do gclid quando o iOS bloqueia o rastreio
gbraidtextoIdem wbraid
fbclidtextoIdentificador de clique da Meta
igshidtextoIdentificador de clique do Instagram
ttclidtextoIdentificador de clique do TikTok
page_urltextoPágina onde o formulário estava
referrertextoPágina de onde a pessoa veio

Como chamar

cURL
curl -X POST https://app.digiflow.systems/api/webhooks/forms \
  -H "Authorization: Bearer df_sua_chave" \
  -H "Content-Type: application/json" \
  -d '{
  "name": "Maria Silva",
  "phone": "(16) 99999-9999"
}'
JSON · Com origem e campos próprios
{
  "name": "Maria Silva",
  "phone": "(16) 99999-9999",
  "email": "maria@email.com",
  "source": "google_ads",
  "source_detail": "Campanha Institucional | Conjunto SP | Criativo 3",
  "custom_fields": {
    "interesse": "Plano anual",
    "score": 8
  }
}
JSON · Sem informar a origem, deixando o CRM deduzir
{
  "name": "Maria Silva",
  "phone": "(16) 99999-9999",
  "gclid": "Cj0KCQjw...",
  "utm_campaign": "institucional-sp",
  "page_url": "https://site-do-cliente.com.br/orcamento"
}

Respostas

  • 201

    Lead criado ou atualizado.

    {
      "ok": true,
      "contact_id": "3f7c1a90-2b44-4f0e-9a1d-88c2b4e7d501"
    }
  • 400

    Corpo inválido: falta telefone e e-mail, telefone impossível de normalizar, ou origem fora da lista.

    {
      "error": "Informe pelo menos telefone ou e-mail"
    }
  • 401

    Chave ausente, inválida ou desativada.

    {
      "error": "API key inválida"
    }
  • 429

    Limite de chamadas por minuto estourado. O cabeçalho Retry-After diz quantos segundos esperar.

    {
      "error": "Muitas requisições"
    }
POST/api/webhooks/events

Avisar um acontecimento sobre um lead que já existe

Um sistema de fora avisa que algo aconteceu com um lead: terminou uma avaliação, assinou um documento, pagou, assistiu à aula. O que o CRM faz com isso é decisão da conta, montada em Automações: o gatilho Evento avisado por um sistema de fora casa pelo nome do evento e roda os passos escolhidos (mover de etapa, marcar tag, avisar alguém).

O nome do evento é combinado entre você e o cliente, e a comparação é exata, com maiúsculas e minúsculas contando. Se a automação espera avaliacao_concluida, mandar Avaliacao_Concluida não dispara nada.

Não cria contato de propósito. Quem cria lead é /api/webhooks/forms, que cuida de origem, deduplicação e distribuição de responsável. Evento sobre gente desconhecida volta 404 em vez de inventar meio cadastro.

Responde 200 mesmo quando nenhuma automação casa com o nome: do seu lado o aviso chegou, e o acontecimento fica registrado no histórico do contato de qualquer jeito.

Limite: 60 chamadas por minuto por IP.

Corpo da requisição

Informe o telefone ou o e-mail de quem o evento é.

CampoTipoO que é
eventobrigatóriotextoNome curto e estável do acontecimento. Letras, números, ponto, hífen e sublinhado.
phonetextoProcurado primeiro
emaile-mailUsado quando o telefone não acha ninguém
custom_fieldsobjeto livreO que o evento traz, somado à ficha do contato: resultado, nota, link do documento.

Como chamar

cURL
curl -X POST https://app.digiflow.systems/api/webhooks/events \
  -H "Authorization: Bearer df_sua_chave" \
  -H "Content-Type: application/json" \
  -d '{
  "event": "avaliacao_concluida",
  "phone": "(16) 99999-9999",
  "custom_fields": {
    "resultado": "Apto",
    "nota": 82,
    "link_laudo": "https://exemplo.com/laudo/123"
  }
}'

Respostas

  • 200

    Evento registrado. Automações que casam com o nome já foram disparadas.

    {
      "ok": true,
      "contact_id": "3f7c1a90-2b44-4f0e-9a1d-88c2b4e7d501",
      "event": "avaliacao_concluida"
    }
  • 400

    Corpo inválido: nome de evento fora do padrão, ou nem telefone nem e-mail.

    {
      "error": "Informe o telefone ou o e-mail de quem o evento é"
    }
  • 401

    Chave ausente, inválida ou desativada.

    {
      "error": "API key inválida"
    }
  • 404

    Contato não existe nesta conta. Cadastre o lead primeiro.

    {
      "error": "Contato não encontrado. Cadastre o lead primeiro em /api/webhooks/forms."
    }
  • 429

    Limite de chamadas por minuto estourado. O cabeçalho Retry-After diz quantos segundos esperar.

    {
      "error": "Muitas requisições"
    }
POST/api/webhooks/orders

Enviar pedidos ou totais do dia

Para ERP, PDV ou plataforma de pedido alimentar o painel de Restaurante do CRM. Mande orders com os pedidos um a um (o caminho recomendado: rende produto campeão, horário de pico e recorrência por telefone) ou daily com os totais fechados de cada dia, quando o sistema de origem não expõe o pedido individual. Os dois podem vir juntos.

source é o nome da loja ou da unidade e é criado sozinho na primeira chamada. Reenviar o mesmo external_id atualiza o pedido em vez de duplicar, então repetir uma janela de sincronização é seguro.

Limite: 240 chamadas por minuto por IP, com até 500 pedidos por chamada.

Corpo da requisição

Envie orders, daily, ou os dois.

CampoTipoO que é
sourceobrigatóriotextoNome da loja ou unidade, como vai aparecer no painel
orderslista de objetos
external_idobrigatóriotextoId do pedido no seu sistema. É por ele que o CRM evita duplicar.
totalobrigatórionúmeroValor total do pedido
statustexto (lista fechada)opendonecancelledPadrão: done
placed_atobrigatóriodata e hora (ISO 8601)Data e hora com fuso, no formato ISO 8601
discountnúmeroDesconto aplicado
delivery_feenúmeroTaxa de entrega cobrada
netnúmeroLíquido depois das taxas da plataforma
order_typetextoentrega, retirada, local
channeltextoiFood, WhatsApp, balcão
customer_nametextoNome de quem pediu
customer_phonetextoUsado para medir recorrência de cliente
itemslista de objetosItens do pedido: alimentam o produto campeão do painel
external_idtextoCódigo do item no seu sistema
nameobrigatóriotextoNome do item, como aparece no painel
categorytextoCategoria do cardápio
quantitynúmeroQuantidade pedidaPadrão: 1
unit_pricenúmeroPreço unitárioPadrão: 0
totalnúmeroTotal da linha; calculado quando não vem
dailylista de objetosTotais fechados por dia, para quando o pedido individual não está disponível
dateobrigatóriotextoAAAA-MM-DD
orders_countobrigatórionúmero inteiro
cancelled_countnúmero inteiroQuantos foram cancelados no dia
grossobrigatórionúmeroFaturamento bruto do dia
netnúmeroLíquido do dia, depois das taxas

Como chamar

cURL
curl -X POST https://app.digiflow.systems/api/webhooks/orders \
  -H "Authorization: Bearer df_sua_chave" \
  -H "Content-Type: application/json" \
  -d '{
  "source": "Loja Centro",
  "orders": [
    {
      "external_id": "PED-10452",
      "total": 89.9,
      "status": "done",
      "placed_at": "2026-09-11T19:42:00-03:00",
      "delivery_fee": 8,
      "order_type": "entrega",
      "channel": "WhatsApp",
      "customer_phone": "(16) 99999-9999",
      "items": [
        {
          "name": "Pizza Calabresa G",
          "category": "Pizzas",
          "quantity": 1,
          "unit_price": 69.9
        }
      ]
    }
  ]
}'

Respostas

  • 200

    Pedidos e totais recebidos.

    {
      "ok": true,
      "source_id": "9c2b...",
      "orders": 1,
      "daily": 0
    }
  • 400

    Corpo inválido, ou nem orders nem daily foram enviados.

    {
      "error": "Envie orders ou daily"
    }
  • 401

    Chave ausente, inválida ou desativada.

    {
      "error": "API key inválida"
    }
  • 409

    A fonte existe mas está pausada no CRM. O administrador reativa em Pedidos.

    {
      "error": "Fonte pausada no CRM"
    }
  • 429

    Limite de chamadas por minuto estourado. O cabeçalho Retry-After diz quantos segundos esperar.

    {
      "error": "Muitas requisições"
    }
GET/api/v1/contatos

Listar contatos

Lista os contatos da conta, do mais recente para o mais antigo por atualização. Só vêm os campos liberados na chave (escopo contatos:read); id, created_at e updated_at vêm sempre. Contato bloqueado como spam não aparece.

Para sincronizar, guarde o instante da última chamada e mande em updated_since.

Parâmetros

ParametroOndeTipoO que e
qquery stringtextoBusca por nome, telefone ou e-mail (contém)
tagquery stringtextoSó contatos com esta tag (nome exato, sem diferenciar maiúsculas)
updated_sincequery stringdata e hora (ISO 8601)Só o que mudou depois deste instante (ISO 8601)
pagequery stringnúmero inteiroPágina, a partir de 1Padrao: 1
limitquery stringnúmero inteiroItens por página (máximo 200)Padrao: 50

Como chamar

cURL
curl "https://app.digiflow.systems/api/v1/contatos?q=valor&tag=valor" \
  -H "Authorization: Bearer df_sua_chave"

Respostas

  • 200

    Página de contatos.

    {
      "data": [
        {
          "id": "3f1c...",
          "created_at": "2026-09-01T13:20:00Z",
          "updated_at": "2026-09-14T18:05:11Z",
          "name": "Maria Silva",
          "phone": "+5516999999999",
          "email": "maria@email.com",
          "company_name": "Padaria Central",
          "source": "google_ads",
          "source_detail": "Campanha Institucional",
          "tags": [
            "Cliente"
          ],
          "assigned_to": "Ana Martins"
        }
      ],
      "page": 1,
      "limit": 50,
      "total": 1,
      "has_more": false
    }
  • 401

    Chave ausente, inválida ou desativada.

    {
      "error": "API key inválida"
    }
  • 403

    A chave não tem o escopo contatos:read.

    {
      "error": "Esta chave não tem o escopo contatos:read. Peça ao administrador da conta para liberar."
    }
  • 429

    Limite de chamadas por minuto estourado. O cabeçalho Retry-After diz quantos segundos esperar.

    {
      "error": "Muitas requisições"
    }
GET/api/v1/contatos/{id}

Ver um contato

Um contato pelo id, com os campos liberados na chave (escopo contatos:read).

Parâmetros

ParametroOndeTipoO que e
idobrigatoriona URLuuidId do contato (uuid)

Como chamar

cURL
curl https://app.digiflow.systems/api/v1/contatos/SEU_ID \
  -H "Authorization: Bearer df_sua_chave"

Respostas

  • 200

    O contato.

    {
      "data": {
        "id": "3f1c...",
        "created_at": "2026-09-01T13:20:00Z",
        "updated_at": "2026-09-14T18:05:11Z",
        "name": "Maria Silva",
        "phone": "+5516999999999",
        "email": "maria@email.com",
        "company_name": "Padaria Central",
        "source": "google_ads",
        "source_detail": "Campanha Institucional",
        "tags": [
          "Cliente"
        ],
        "assigned_to": "Ana Martins"
      }
    }
  • 401

    Chave ausente, inválida ou desativada.

    {
      "error": "API key inválida"
    }
  • 403

    A chave não tem o escopo contatos:read.

    {
      "error": "Esta chave não tem o escopo contatos:read. Peça ao administrador da conta para liberar."
    }
  • 404

    Não existe contato com esse id nesta conta.

    {
      "error": "Contato não encontrado"
    }
  • 429

    Limite de chamadas por minuto estourado. O cabeçalho Retry-After diz quantos segundos esperar.

    {
      "error": "Muitas requisições"
    }
GET/api/v1/negocios

Listar negócios

Oportunidades (cards do funil) da conta, com funil, etapa, valor, situação e responsável (escopo negocios:read). O contato vem só como id e nome; o resto é do endpoint de contatos, que respeita os campos da chave. Negócio na lixeira não aparece.

Use /api/v1/funis para saber os ids de funil e etapa e filtrar.

Parâmetros

ParametroOndeTipoO que e
statusquery stringtexto (lista fechada)Situação do negócioopenwonlost
pipeline_idquery stringuuidSó de um funil (id de /api/v1/funis)
updated_sincequery stringdata e hora (ISO 8601)Só o que mudou depois deste instante (ISO 8601)
pagequery stringnúmero inteiroPágina, a partir de 1Padrao: 1
limitquery stringnúmero inteiroItens por página (máximo 200)Padrao: 50

Como chamar

cURL
curl "https://app.digiflow.systems/api/v1/negocios?status=open&pipeline_id=valor" \
  -H "Authorization: Bearer df_sua_chave"

Respostas

  • 200

    Página de negócios.

    {
      "data": [
        {
          "id": "8a20...",
          "title": "Plano anual",
          "status": "open",
          "value": 4800,
          "contact": {
            "id": "3f1c...",
            "name": "Maria Silva"
          },
          "pipeline": {
            "id": "b7e1...",
            "name": "Vendas"
          },
          "stage": {
            "id": "c9d2...",
            "name": "Proposta",
            "entered_at": "2026-09-12T14:00:00Z"
          },
          "assigned_to": "Ana Martins",
          "lost_reason": null,
          "won_at": null,
          "lost_at": null,
          "created_at": "2026-09-01T13:20:00Z",
          "updated_at": "2026-09-12T14:00:00Z"
        }
      ],
      "page": 1,
      "limit": 50,
      "total": 1,
      "has_more": false
    }
  • 401

    Chave ausente, inválida ou desativada.

    {
      "error": "API key inválida"
    }
  • 403

    A chave não tem o escopo negocios:read.

    {
      "error": "Esta chave não tem o escopo negocios:read. Peça ao administrador da conta para liberar."
    }
  • 429

    Limite de chamadas por minuto estourado. O cabeçalho Retry-After diz quantos segundos esperar.

    {
      "error": "Muitas requisições"
    }
GET/api/v1/funis

Listar funis e etapas

Os funis da conta com as etapas em ordem (escopo negocios:read). É o dicionário para interpretar os ids que vêm em /api/v1/negocios.

Como chamar

cURL
curl https://app.digiflow.systems/api/v1/funis \
  -H "Authorization: Bearer df_sua_chave"

Respostas

  • 200

    Funis com etapas.

    {
      "data": [
        {
          "id": "b7e1...",
          "name": "Vendas",
          "kind": "sales",
          "stages": [
            {
              "id": "c1..",
              "name": "Novo lead",
              "position": 0,
              "is_won": false,
              "is_lost": false,
              "role": null
            },
            {
              "id": "c9d2...",
              "name": "Proposta",
              "position": 3,
              "is_won": false,
              "is_lost": false,
              "role": null
            },
            {
              "id": "c5..",
              "name": "Ganhou",
              "position": 4,
              "is_won": true,
              "is_lost": false,
              "role": null
            }
          ]
        }
      ]
    }
  • 401

    Chave ausente, inválida ou desativada.

    {
      "error": "API key inválida"
    }
  • 403

    A chave não tem o escopo negocios:read.

    {
      "error": "Esta chave não tem o escopo negocios:read. Peça ao administrador da conta para liberar."
    }
  • 429

    Limite de chamadas por minuto estourado. O cabeçalho Retry-After diz quantos segundos esperar.

    {
      "error": "Muitas requisições"
    }
GET/api/v1/agenda

Listar compromissos

Compromissos da agenda da conta num intervalo (escopo agenda:read). Sem de/ate, devolve os próximos 30 dias.

Parâmetros

ParametroOndeTipoO que e
dequery stringdata e hora (ISO 8601)Início do intervalo (ISO 8601). Padrão: agora
atequery stringdata e hora (ISO 8601)Fim do intervalo (ISO 8601). Padrão: 30 dias depois de `de`
statusquery stringtexto (lista fechada)Situaçãoconfirmedcancelledcompletedno_show
member_idquery stringuuidSó de um profissional
pagequery stringnúmero inteiroPágina, a partir de 1Padrao: 1
limitquery stringnúmero inteiroItens por página (máximo 200)Padrao: 50

Como chamar

cURL
curl "https://app.digiflow.systems/api/v1/agenda?de=2026-09-01T00:00:00Z&ate=2026-09-01T00:00:00Z" \
  -H "Authorization: Bearer df_sua_chave"

Respostas

  • 200

    Página de compromissos, em ordem de horário.

    {
      "data": [
        {
          "id": "d4f0...",
          "title": "Reunião de proposta",
          "status": "confirmed",
          "starts_at": "2026-09-16T14:00:00-03:00",
          "ends_at": "2026-09-16T14:30:00-03:00",
          "member": {
            "id": "m1..",
            "name": "Ana Martins"
          },
          "contact": {
            "id": "3f1c...",
            "name": "Maria Silva"
          },
          "opportunity_id": "8a20...",
          "meet_link": "https://meet.google.com/abc-defg-hij",
          "created_at": "2026-09-10T10:00:00Z"
        }
      ],
      "page": 1,
      "limit": 50,
      "total": 1,
      "has_more": false
    }
  • 401

    Chave ausente, inválida ou desativada.

    {
      "error": "API key inválida"
    }
  • 403

    A chave não tem o escopo agenda:read.

    {
      "error": "Esta chave não tem o escopo agenda:read. Peça ao administrador da conta para liberar."
    }
  • 429

    Limite de chamadas por minuto estourado. O cabeçalho Retry-After diz quantos segundos esperar.

    {
      "error": "Muitas requisições"
    }

Limites e erros

  • Cada endpoint tem um limite por minuto, indicado na referência. Ao estourar, a resposta é 429 com o cabeçalho Retry-After dizendo quantos segundos esperar.
  • Todo erro volta como { "error": "..." }, em português. Quando a recusa é de validação, vem junto detalhes, com o campo que caiu.
  • Reenvio é idempotente. O lead é procurado pelo telefone e o pedido pelo external_id: repetir uma janela de sincronização atualiza, não duplica.
  • Chave revogada, vencida ou fora do escopo responde 401 ou 403 na hora: é erro permanente, repetir não muda o resultado.
  • As listas vêm paginadas, em { data, page, limit, total, has_more }, e updated_since traz só o que mudou desde a última sincronização.

O caminho de volta

Para o CRM avisar o seu sistema quando algo acontece, hoje o caminho é a automação: o administrador monta a regra em Automações e escolhe a ação Chamar webhook, com a URL e um segredo. Serve para lead novo, mudança de etapa, negócio ganho e o resto dos gatilhos da conta.

Em desenvolvimento

Assinatura de eventos, com HMAC e reenvio automático, para o CRM chamar o seu endpoint sem depender de uma automação montada à mão. Se a sua integração precisa disso, escreve pra gente: avisamos quando entrar, e a fila leva em conta quem pediu.

Precisa de um endpoint que ainda não existe?

Conta o que a sua integração precisa ler ou escrever. A gente responde se já dá, se está na fila ou se vale construir junto.

7 dias grátis, sem fidelidade. Implantação opcional com a nossa equipe.