Documentação da API do InicialApp
Tudo o que um programador precisa para ligar o InicialApp a um CRM, a um sistema de gestão, a um agente de IA ou a uma automação no n8n, no Make ou no Zapier.
Visão geral
O InicialApp tem três portas abertas. Cada escritório só enxerga e mexe no que é dele: a chave e os endereços já dizem de qual escritório é o pedido.
O seu programa lê e altera casos do InicialApp com uma chave.
O InicialApp avisa o seu endereço, na hora, quando algo acontece no caso.
Um endereço exclusivo que cria e atualiza caso com um JSON simples.
Endereço base da API: https://app.inicialapp.com.br/api/v1. Todas as respostas são JSON em UTF-8, com datas no formato ISO 8601.
Chave e autenticação
O dono ou o sócio do escritório cria a chave em Configurações › Conectores › Chaves de API. A chave começa com iap_ e aparece uma vez só. Se perder, revogue e crie outra.
Mande a chave no cabeçalho X-API-Key em todo pedido. Também vale Authorization: Bearer iap_....
curl https://app.inicialapp.com.br/api/v1/eu \
-H "X-API-Key: iap_SUA_CHAVE"
Cada chave só faz o que foi marcado ao criar:
| Permissão | Libera |
|---|---|
casos:ler | listar e ver casos |
casos:criar | criar caso |
casos:etapa | mudar a etapa do caso |
casos:editar | alterar dados do caso e campos personalizados |
tarefas:ler | listar tarefas |
Etapas e campos personalizados podem ser lidos por qualquer chave válida.
Limites e erros
Cada chave faz até 120 chamadas por minuto. O webhook de entrada recebe até 60 avisos por minuto por escritório. Acima disso a resposta é 429: espere o minuto virar e tente de novo. O limite existe para um robô com defeito, repetindo sem parar, não deixar o app lento para os outros escritórios.
| Código | Quando |
|---|---|
200 / 201 | deu certo (201 quando criou caso) |
400 | corpo inválido ou faltando campo, por exemplo etapa que não existe |
401 | chave ausente, errada ou revogada |
403 | a chave não tem a permissão, ou o escritório está suspenso |
404 | caso ou caminho não encontrado |
429 | passou do limite por minuto |
500 | falha nossa; tente de novo |
Todo erro volta com um campo erro explicando em português:
{ "erro": "esta chave não tem permissão para isso" }
GET/v1/eu
Confere a chave e mostra o escritório e as permissões.
{
"escritorio": "Escritório Exemplo",
"chave": "CRM",
"permissoes": ["casos:ler", "casos:criar"],
"limite_por_minuto": 120
}
GET/v1/etapas
As etapas do escritório, na ordem. Use exatamente estes nomes ao mudar etapa (maiúsculas e minúsculas não importam).
{
"etapas": [
{ "nome": "DOCUMENTOS ESSENCIAIS", "ordem": 1, "modulo": "documentos" },
{ "nome": "CUSTAS/GRATUIDADE", "ordem": 2, "modulo": "documentos" },
{ "nome": "PROTOCOLADO", "ordem": 10, "modulo": "tramitacao" }
]
}
GET/v1/campos
Os campos personalizados do escritório. Ao gravar, use o nome do campo (ou o id) como chave dentro de campos.
{
"campos": [
{ "id": "3f1c...", "nome": "Origem do lead", "tipo": "texto", "opcoes": [], "grupo": "Campos personalizados" }
]
}
GET/v1/casos
Permissão casos:ler. Mais recentes primeiro. Filtros opcionais:
| Parâmetro | O que faz |
|---|---|
etapa | só casos nesta etapa |
busca | parte do nome do cliente |
desde | só casos alterados depois desta data (ISO) |
limite | quantos por página, até 200 (padrão 50) |
pagina | página, começando em 1 |
curl "https://app.inicialapp.com.br/api/v1/casos?etapa=CUSTAS/GRATUIDADE&limite=20" \
-H "X-API-Key: iap_SUA_CHAVE"
{ "pagina": 1, "casos": [ { ...caso completo... } ] }
GET/v1/casos/{id}
Permissão casos:ler. No lugar do id do InicialApp, dá para usar o id do seu sistema com ref:, por exemplo /v1/casos/ref:crm-123.
{ "caso": { ...caso completo... } }
POST/v1/casos
Permissão casos:criar. Só nome é obrigatório. Com ref, mandar o mesmo caso duas vezes não duplica: a segunda resposta traz "ja_existia": true. Sem etapa, o caso entra na primeira etapa. Com cpf, o cliente já cadastrado no escritório é reaproveitado.
curl -X POST https://app.inicialapp.com.br/api/v1/casos \
-H "X-API-Key: iap_SUA_CHAVE" -H "Content-Type: application/json" \
-d '{
"nome": "Maria Souza",
"cpf": "000.000.000-00",
"telefone": "11999990000",
"email": "maria@email.com",
"link_conta": "https://instagram.com/maria",
"observacoes": "veio do CRM",
"ref": "crm-123",
"campos": { "Origem do lead": "Instagram" }
}'
Resposta 201. Campo personalizado com nome que não existe no escritório não trava o pedido: ele aparece em campos_ignorados.
{
"caso": { "id": "c4764ef4-...", "ref": "crm-123", "nome": "Maria Souza", "etapa": "DOCUMENTOS ESSENCIAIS", ... },
"campos_ignorados": []
}
POST/v1/casos/{id}/etapa
Permissão casos:etapa. Muda a etapa, grava o histórico do caso e dispara o evento caso.etapa_mudou.
curl -X POST https://app.inicialapp.com.br/api/v1/casos/ref:crm-123/etapa \
-H "X-API-Key: iap_SUA_CHAVE" -H "Content-Type: application/json" \
-d '{ "etapa": "CUSTAS/GRATUIDADE" }'
Etapa que não existe volta 400 com a lista das etapas aceitas.
PATCH/v1/casos/{id}
Permissão casos:editar. Mande só o que muda. Campos aceitos: link_conta, numero_processo, protocolo, observacoes, prioridade, tipo_caso e campos. Mandar campo vazio apaga o valor.
curl -X PATCH https://app.inicialapp.com.br/api/v1/casos/ref:crm-123 \
-H "X-API-Key: iap_SUA_CHAVE" -H "Content-Type: application/json" \
-d '{ "numero_processo": "1000000-00.2026.8.26.0100", "campos": { "Origem do lead": "Google" } }'
GET/v1/tarefas
Permissão tarefas:ler. Filtros: status (aberta ou concluida), caso_id, limite e pagina.
{
"tarefas": [
{ "id": 42, "caso_id": "c4764ef4-...", "cliente": "Maria Souza", "titulo": "Cobrar comprovante",
"etapa": "DOCUMENTOS ESSENCIAIS", "responsavel": "Ana", "status": "aberta", "prazo": "2026-11-12" }
]
}
O caso completo
A API e os webhooks devolvem o caso sempre no mesmo formato, com cliente, etapa, prazos, campos personalizados pelo nome e documentos do checklist:
{
"id": "c4764ef4-8c0c-4a7d-a7e0-d385d8661297",
"ref": "crm-123",
"nome": "Maria Souza",
"etapa": "CUSTAS/GRATUIDADE",
"tipo_caso": null,
"link_conta": "https://instagram.com/maria",
"numero_processo": null,
"protocolo": null,
"prioridade": null,
"data_inicio": "2026-11-05",
"fatal_essenciais": "2026-11-12",
"fatal_complementares": "2026-11-17",
"fatal_documento": "2026-11-17",
"fatal_inicial": null,
"observacoes": "veio do CRM",
"criado_em": "2026-11-05T17:00:14Z",
"atualizado_em": "2026-11-05T17:05:02Z",
"cliente": { "id": "ac6ca71e-...", "nome": "Maria Souza", "cpf": "00000000000", "email": "maria@email.com",
"telefone": "11999990000", "cidade": null, "uf": null },
"campos": { "Origem do lead": "Instagram" },
"documentos": [ { "item": "RG", "grupo": "essenciais", "recebido": true } ]
}
Webhooks de saída
Cadastre em Configurações › Conectores › Webhooks de saída: o endereço que recebe (precisa começar com https://), os eventos e, se quiser, as etapas. O InicialApp manda um POST com JSON a cada evento:
POST https://seu-endereco.com/inicialapp
Content-Type: application/json
X-InicialApp-Evento: caso.etapa_mudou
X-InicialApp-Entrega: 1287
X-InicialApp-Data: 1793898024
X-InicialApp-Assinatura: sha256=e0718579...
{
"id": "a8038d31-b437-46ea-b5ca-846a3594107f",
"evento": "caso.etapa_mudou",
"criado_em": "2026-11-05T17:00:15Z",
"dados": {
"de": "DOCUMENTOS ESSENCIAIS",
"para": "CUSTAS/GRATUIDADE",
"caso": { ...caso completo... }
}
}
O id é único por aviso: use para não processar o mesmo aviso duas vezes. No formato Discord ou Slack, o corpo é só uma frase curta para o canal ({"content": "..."} ou {"text": "..."}).
Eventos
| Evento | Quando sai | Além do caso, traz |
|---|---|---|
caso.criado | caso novo, pela tela, pela API ou pelo webhook de entrada | |
caso.etapa_mudou | a cada mudança de etapa; dá para filtrar por etapa | de, para |
caso.atualizado | mudou um dado do caso ou um campo personalizado | campo, valor (quando foi campo personalizado) |
documento.recebido | documento do checklist marcado como recebido | documento, grupo |
prazo.vencido | uma vez por prazo vencido (documentos, inicial ou tarefa); conferido a cada 15 minutos | prazo, data |
caso.protocolado | uma vez, quando o caso é protocolado | |
teste | quando alguém clica em Testar na tela | mensagem |
Sistema de gestão no fim do fluxo: crie um webhook só com caso.protocolado, ou com caso.etapa_mudou filtrado na etapa final. Quem usa ADVBOX não precisa disso: o cartão ADVBOX em Conectores cadastra cliente e processo sozinho.
Conferir a assinatura
Ao criar o webhook, a tela mostra uma vez o segredo (whsec_...). A assinatura é o HMAC SHA-256 do texto X-InicialApp-Data + "." + corpo bruto com esse segredo. Compare antes de confiar no aviso e recuse avisos com mais de 5 minutos.
// Node.js (Express com express.raw para ter o corpo bruto)
const crypto = require("crypto");
function avisoValido(req, segredo) {
const data = req.get("X-InicialApp-Data");
const esperado = "sha256=" + crypto.createHmac("sha256", segredo)
.update(data + "." + req.body.toString("utf8")).digest("hex");
const recebido = req.get("X-InicialApp-Assinatura") || "";
const recente = Math.abs(Date.now() / 1000 - Number(data)) < 300;
return recente && recebido.length === esperado.length &&
crypto.timingSafeEqual(Buffer.from(recebido), Buffer.from(esperado));
}
# Python
import hmac, hashlib, time
def aviso_valido(cabecalhos, corpo_bruto: bytes, segredo: str) -> bool:
data = cabecalhos["X-InicialApp-Data"]
esperado = "sha256=" + hmac.new(segredo.encode(), (data + ".").encode() + corpo_bruto, hashlib.sha256).hexdigest()
return abs(time.time() - int(data)) < 300 and hmac.compare_digest(esperado, cabecalhos.get("X-InicialApp-Assinatura", ""))
Repetição e histórico
Responda com qualquer código 2xx em até 10 segundos. Se não responder, ou responder erro, o InicialApp tenta de novo em 1 minuto, 5 minutos, 30 minutos, 2 horas e 12 horas. Depois da sexta tentativa, o aviso fica como não entregue. Tudo aparece em Webhooks de saída › Histórico de envios, com a resposta do seu endereço e o botão Reenviar.
Webhook de entrada
Gere o endereço em Configurações › Conectores › Webhook de entrada. Ele aparece uma vez e tem a forma https://app.inicialapp.com.br/api/entrada/ent_.... Não precisa de chave: o próprio endereço é o segredo. Se vazar, clique em Trocar endereço.
curl -X POST https://app.inicialapp.com.br/api/entrada/ent_SEU_ENDERECO \
-H "Content-Type: application/json" \
-d '{
"acao": "criar_caso",
"nome": "Maria Souza",
"cpf": "000.000.000-00",
"telefone": "11999990000",
"ref": "id-no-seu-crm",
"etapa": "DOCUMENTOS ESSENCIAIS",
"campos": { "Origem do lead": "Instagram" }
}'
| acao | O que faz |
|---|---|
criar_caso | cria o caso; com ref repetido, devolve o que já existe |
atualizar_caso | atualiza o caso achado por ref ou id, com os mesmos campos do PATCH |
mudar_etapa | muda a etapa do caso achado por ref ou id |
Sem acao, o InicialApp atualiza se achar o caso pelo ref e cria se não achar. Ele também entende os nomes que os CRMs costumam mandar: name, phone, lead.name, lead.phone, contact.name. Aceita JSON ou formulário (application/x-www-form-urlencoded). Para marcar de onde veio no histórico, acrescente ?origem=meu-crm no endereço.
ZapSign
Cole o mesmo endereço em ZapSign › Configurações › Webhooks e marque Documento assinado. Quando o contrato é assinado (doc_signed), o caso nasce com o nome, o e-mail e o telefone do primeiro signatário. Outros eventos do ZapSign são recebidos e ignorados.
MCP e Claude
Agentes de IA que falam MCP se ligam em https://app.inicialapp.com.br/api/mcp com a mesma chave da API, no cabeçalho X-API-Key. O agente só faz o que a chave permite.
Claude Code:
claude mcp add --transport http inicialapp https://app.inicialapp.com.br/api/mcp \
--header "X-API-Key: iap_SUA_CHAVE"
Claude no computador (Configurações › Desenvolvedor › Editar configuração):
{ "mcpServers": { "inicialapp": { "command": "npx",
"args": ["-y", "mcp-remote", "https://app.inicialapp.com.br/api/mcp", "--header", "X-API-Key:iap_SUA_CHAVE"] } } }
| Ferramenta | Faz |
|---|---|
listar_etapas | etapas do escritório |
listar_campos | campos personalizados |
listar_casos | casos, com filtros por etapa, nome e data |
ver_caso | o caso completo |
criar_caso | cria caso |
mudar_etapa | muda a etapa |
editar_caso | altera dados e campos personalizados |
listar_tarefas | tarefas |
Exemplos prontos
CRM com todos os campos
Webhook de saída com caso.criado, caso.etapa_mudou e caso.atualizado. No CRM, use dados.caso.etapa para mover o negócio e dados.caso.campos para preencher os campos dele. No sentido contrário, a automação do CRM chama o webhook de entrada com o mesmo ref.
Contrato assinado abre o caso
Endereço de entrada colado no ZapSign. Nenhuma linha de código.
Aviso no Discord
Webhook de saída no formato Discord, com o endereço do webhook do canal, e os eventos caso.criado, prazo.vencido e caso.protocolado.
Planilha do dia
No n8n, no Make ou no Zapier: um gatilho de webhook recebe caso.etapa_mudou e acrescenta uma linha na planilha com dados.caso.nome, dados.de, dados.para e criado_em.
Dúvida ou algo que a API ainda não faz? Fale com o suporte pelo app.