Visão geral
A API do Qubitx CRM permite que outro sistema leia os Contatos, as Empresas e as Oportunidades de uma empresa cliente. É o caminho para levar os dados do CRM ao Power BI, a uma planilha, ao sistema de uma consultoria ou ao ERP da empresa.
- Só leitura. A API não cria, não altera e não apaga nada no CRM.
- Uma empresa por chave. Cada chave enxerga apenas os dados da empresa para a qual foi criada.
- JSON sobre HTTPS. Todas as respostas são JSON em UTF-8, com nomes de campos em português.
Endereço base de todas as chamadas:
https://crm.qubitxsolutions.com.br/api/v1
Autenticação
Cada chamada leva a chave de API no cabeçalho Authorization:
Authorization: Bearer qbx_live_SUA_CHAVE
- Como conseguir uma chave: a equipe Qubitx cria a chave a pedido da empresa cliente, que a repassa a quem vai integrar. A chave aparece uma única vez, no momento em que é criada.
- Guarde como uma senha. Não coloque a chave em endereço (URL), planilha compartilhada, código público ou e-mail aberto. A chave na URL é recusada.
- Revogação: a empresa cliente pode pedir a revogação a qualquer momento. A chave revogada para de funcionar na hora.
- Chave ausente, errada ou revogada recebe a mesma resposta
401.
Paginação
As listas vêm em páginas. Use os parâmetros na URL:
| Parâmetro | Padrão | Descrição |
|---|---|---|
pagina | 1 | Número da página, a partir de 1. |
por_pagina | 100 | Registros por página, de 1 a 500. |
alterado_desde | — | Só registros criados ou alterados a partir desta data e hora (ISO 8601, ex. 2026-10-01T00:00:00-03:00). |
Toda resposta de lista tem este formato:
{
"dados": [ ... ],
"paginacao": {
"pagina": 1,
"por_pagina": 100,
"total": 1721,
"total_paginas": 18,
"proxima_pagina": 2
}
}
Quando proxima_pagina vier null, você chegou à última página. Os registros vêm em ordem de alteração, do mais antigo para o mais recente.
Leitura incremental
Para não baixar a base inteira a cada atualização:
- Na primeira carga, leia todas as páginas.
- Guarde o maior valor de
atualizado_emque você recebeu. - Nas próximas cargas, envie esse valor em
alterado_desde. Vêm só os registros novos ou alterados.
Mudanças em telefone, e-mail, tag, empresa ligada ou campo personalizado também contam como alteração do registro. Registros excluídos não aparecem na leitura incremental: faça uma carga completa de tempos em tempos (por exemplo, uma vez por semana) para retirá-los da sua base.
Contatos
GET /api/v1/contatos
| Campo | Tipo | Descrição |
|---|---|---|
id | texto (UUID) | Identificador do contato. |
nome, cargo, cidade, uf | texto | Dados cadastrais. |
data_nascimento | data | Formato AAAA-MM-DD. |
origem, status | texto | Como o contato chegou e situação cadastral. |
aceita_marketing, aceita_newsletter | sim/não | Consentimentos do contato. |
vendedor_responsavel | objeto | id e nome do vendedor responsável. |
telefones | lista | telefone (com DDI, só números), principal, aceita_whatsapp_marketing. O principal vem primeiro. |
emails | lista | email, principal, aceita_newsletter. |
tags | lista de textos | Nomes das tags do contato. |
empresas | lista | id e nome das empresas ligadas. |
campos_personalizados | objeto | Nome do campo e valor, como cadastrados pela empresa. |
criado_em, atualizado_em | data e hora | ISO 8601. |
{
"id": "6f1c2a90-3b5e-4c1d-9a7e-2d8f0b1c4e55",
"nome": "Marina Costa",
"cargo": "Síndica",
"cidade": "Niterói",
"uf": "RJ",
"data_nascimento": null,
"origem": "WhatsApp",
"status": null,
"aceita_marketing": true,
"aceita_newsletter": true,
"vendedor_responsavel": { "id": "0a21…", "nome": "Ana Souza" },
"telefones": [{ "telefone": "5521990001000", "principal": true, "aceita_whatsapp_marketing": true }],
"emails": [{ "email": "marina@exemplo.com.br", "principal": true, "aceita_newsletter": true }],
"tags": ["Aquecimento solar"],
"empresas": [{ "id": "bae4…", "nome": "Condomínio Mar Azul" }],
"campos_personalizados": { "Tamanho da piscina": "8x4" },
"criado_em": "2026-09-12T10:41:00-03:00",
"atualizado_em": "2026-10-06T16:02:11-03:00"
}
Empresas
GET /api/v1/empresas
| Campo | Tipo | Descrição |
|---|---|---|
id | texto (UUID) | Identificador da empresa. |
nome, cnpj, segmento | texto | Dados cadastrais. |
endereco, bairro, cep, cidade, uf | texto | Endereço. |
site, email | texto | Contato da empresa. |
telefones, emails | lista | Com principal; telefone sem DDI, só números. |
campos_personalizados | objeto | Nome do campo e valor. |
criado_em, atualizado_em | data e hora | ISO 8601. |
Oportunidades
GET /api/v1/oportunidades
| Campo | Tipo | Descrição |
|---|---|---|
id | texto (UUID) | Identificador da oportunidade (negociação). |
contato | objeto | id e nome do contato. Use o id para ligar com a lista de Contatos. |
funil, etapa | objeto | id e nome do funil e da etapa atual. |
vendedor_responsavel | objeto | id e nome. |
valor | número | Valor da venda em reais. |
resultado | texto | aberta, ganha, perdida ou descartada. |
data_fechamento | data e hora | Quando foi ganha, perdida ou descartada. |
na_etapa_desde | data e hora | Desde quando está na etapa atual. |
motivo_perda, motivo_descarte | texto | Motivo, quando houver. |
temperatura | objeto | faixa (quente, morno, frio) e nota de 0 a 100. |
tags | lista de textos | Tags da oportunidade. |
utm | objeto | source, medium, campaign, content, term do anúncio de origem. |
campos_personalizados | objeto | Nome do campo e valor. |
criado_em, atualizado_em | data e hora | ISO 8601. |
{
"id": "0344…",
"contato": { "id": "6f1c…", "nome": "Marina Costa" },
"funil": { "id": "5dda…", "nome": "Vendas" },
"etapa": { "id": "76cf…", "nome": "Cotação Enviada" },
"vendedor_responsavel": { "id": "0a21…", "nome": "Ana Souza" },
"valor": 5800,
"resultado": "aberta",
"data_fechamento": null,
"na_etapa_desde": "2026-10-03T09:27:00-03:00",
"motivo_perda": null,
"motivo_descarte": null,
"temperatura": { "faixa": "quente", "nota": 88 },
"tags": ["Instalação inclusa"],
"utm": { "source": "meta", "medium": "whatsapp", "campaign": "verao-2027", "content": null, "term": null },
"campos_personalizados": {},
"criado_em": "2026-09-29T10:38:00-03:00",
"atualizado_em": "2026-10-06T09:58:40-03:00"
}
Erros e limites
Os erros vêm sempre no mesmo formato:
{ "erro": { "codigo": "parametro_invalido", "mensagem": "\"por_pagina\" precisa ser um número inteiro de 1 a 500." } }
| Status | Código | Quando acontece |
|---|---|---|
| 400 | parametro_invalido | Parâmetro da URL fora do formato. |
| 401 | nao_autorizado | Chave ausente, errada ou revogada. |
| 405 | — | Método diferente de GET. A API é só de leitura. |
| 429 | limite_excedido | Mais de 120 chamadas por minuto com a mesma chave. Espere os segundos indicados no cabeçalho Retry-After. |
| 500 | erro_interno | Falha do nosso lado. Tente de novo em alguns minutos. |
Muitas tentativas seguidas com chave errada a partir do mesmo endereço IP são bloqueadas por 1 minuto.
Exemplo: terminal (curl)
curl -H "Authorization: Bearer qbx_live_SUA_CHAVE" \
"https://crm.qubitxsolutions.com.br/api/v1/oportunidades?por_pagina=500&pagina=1"
Exemplo: Power BI
No Power BI Desktop: Obter dados → Consulta nula, abra o Editor avançado e cole o código abaixo, trocando a chave. Ele lê todas as páginas e monta a tabela. Repita trocando oportunidades por contatos ou empresas.
let
Chave = "qbx_live_SUA_CHAVE",
Recurso = "oportunidades",
LerPagina = (n as number) =>
Json.Document(Web.Contents("https://crm.qubitxsolutions.com.br", [
RelativePath = "api/v1/" & Recurso,
Query = [pagina = Number.ToText(n), por_pagina = "500"],
Headers = [Authorization = "Bearer " & Chave]
])),
Primeira = LerPagina(1),
TotalPaginas = Primeira[paginacao][total_paginas],
Paginas = List.Transform({1..TotalPaginas}, each if _ = 1 then Primeira else LerPagina(_)),
Registros = List.Combine(List.Transform(Paginas, each _[dados])),
Tabela = Table.FromRecords(Registros)
in
Tabela
Quando o Power BI perguntar como acessar o endereço, escolha Anônimo: a chave já vai no cabeçalho. Campos que são listas ou objetos (telefones, etapa, vendedor) aparecem como colunas expansíveis.
Exemplo: Python
import requests
CHAVE = "qbx_live_SUA_CHAVE"
URL = "https://crm.qubitxsolutions.com.br/api/v1/contatos"
registros, pagina = [], 1
while pagina:
r = requests.get(URL, headers={"Authorization": f"Bearer {CHAVE}"},
params={"pagina": pagina, "por_pagina": 500}, timeout=60)
r.raise_for_status()
corpo = r.json()
registros += corpo["dados"]
pagina = corpo["paginacao"]["proxima_pagina"]
print(len(registros), "contatos")
Segurança e dados pessoais
- Todas as chamadas são registradas: data, hora, dados lidos, resultado e endereço IP. A empresa cliente pode pedir esse registro.
- A chave dá acesso a dados pessoais de contatos (nome, telefone, e-mail). Quem recebe a chave passa a tratar esses dados em nome da empresa cliente e deve seguir a LGPD e a nossa Política de Privacidade.
- A API não entrega o conteúdo das conversas do WhatsApp.
- Suspeita de vazamento da chave? Peça a revogação imediata em tech@qubitxsolutions.com.br.