Referência da API
A API /v1 recebe o PDF, informa a situação e entrega o resultado liberado. Toda chamada usa HTTPS e envia Authorization: Bearer com uma chave de API. Respostas e erros são JSON; erros sempre no formato {"error": "<código>"}.
Esta página é gerada do contrato OpenAPI 3.1, o mesmo servido em /v1/openapi.json.
URL base
https://finstat.com.br
https://finstat.com.br/v1{
"error": "unauthorized"
}Enviar documento
POST/v1/documents
Envia o PDF bruto de um balanço/DRE. A resposta 202 traz o id e a situação inicial (queued). O resultado fica disponível na liberação, depois da conferência humana quando ela é necessária: acompanhe pelo webhook ou por Consultar documento.
Mesma Idempotency-Key e mesma entrada devolvem o mesmo id, sem criar outro documento nem nova cobrança. Veja Enviar documento.
Escopo: documents:write
Parâmetros de consulta
cnpjstringobrigatório- CNPJ da empresa do documento, 14 caracteres sem pontuação (dígitos ou letras maiúsculas; aceita o CNPJ alfanumérico).
14 caracteres · formato
^[A-Z0-9]{12}[0-9]{2}$ period_endstring (date)obrigatório- Data de encerramento do período,
AAAA-MM-DD. entityenum- Entidade das demonstrações:
Individual(padrão),Controladora,ConsolidadoouCombinado.valores:
Individual,Controladora,Consolidado,Combinado· padrão:"Individual"
Cabeçalhos
AuthorizationstringobrigatórioBearer fst_..., chave com o escopodocuments:write.Idempotency-Keystringobrigatório- Obrigatório. 1 a 128 caracteres, único na sua empresa. Derive do seu registro (por exemplo, o id do lote) e repita a mesma chave em toda nova tentativa.
1 a 128 caracteres
Corpo
application/pdf
O PDF bruto, com Content-Type: application/pdf, até 25 MiB e 100 páginas. Sem multipart nem base64.
Respostas
- 202Documento aceito (ou o mesmo de antes, se repetido com a mesma chave).
- 401
unauthorized: chave ausente, inválida, revogada, expirada ou sem o escopo - 409
version_conflict:Idempotency-Keyjá usada com outra entrada. - 413
pdf_too_largeoubody_too_large. - 422
pdf_and_idempotency_key_required,invalid_pdfouinvalid_request. - 429
too_many_requests: sua chave já tem dois envios em andamento; vem comRetry-After. Repita com a mesmaIdempotency-Key. - 4XXOutro erro do cliente, no mesmo formato.
- 500
internal_error: repita com a mesmaIdempotency-Key. - 503
capacity_busy: espereRetry-Aftere repita.
curl "https://finstat.com.br/v1/documents?cnpj=00000000000191&period_end=2025-12-31&entity=Individual" \
-H "Authorization: Bearer $FINSTAT_API_KEY" \
-H "Idempotency-Key: lote-2025-12-0042" \
-H "Content-Type: application/pdf" \
--data-binary @balanco.pdfimport { Finstat } from "finstat";
const finstat = new Finstat(process.env.FINSTAT_API_KEY!);
import { readFile } from "node:fs/promises";
const document = await finstat.documents.submit(
{
file: await readFile("balanco.pdf"),
cnpj: "00000000000191",
periodEnd: "2025-12-31",
entity: "Individual",
},
// Opcional: sem ela, o SDK deriva a chave do conteúdo do PDF.
{ idempotencyKey: "lote-2025-12-0042" },
);
console.log(document.id, document.status); // "queued"import os
from pathlib import Path
import httpx
response = httpx.post(
"https://finstat.com.br/v1/documents",
params={
"cnpj": "00000000000191",
"period_end": "2025-12-31",
"entity": "Individual",
},
headers={
"Authorization": f"Bearer {os.environ['FINSTAT_API_KEY']}",
"Idempotency-Key": "lote-2025-12-0042",
"Content-Type": "application/pdf",
},
content=Path("balanco.pdf").read_bytes(),
timeout=60,
)
response.raise_for_status()
print(response.json()){
"id": "00000000-0000-4000-8000-000000000001",
"status": "queued",
"reason": null,
"pages": 0,
"processing_seconds": 0,
"engine_version": "",
"model_version": ""
}Consultar documento
GET/v1/documents/{job_id}
Devolve a situação do documento, o motivo (reason), as páginas, o tempo de processamento e as versões. Pode ser repetida à vontade; prefira o webhook para não consultar em laço curto.
Escopo: documents:read
Parâmetros de caminho
job_idstringobrigatório- Id do documento, devolvido no envio (
id).
Cabeçalhos
AuthorizationstringobrigatórioBearer fst_..., chave com o escopodocuments:read.
Respostas
- 200Situação atual do documento.
- 401
unauthorized: chave ausente, inválida, revogada, expirada ou sem o escopo - 404
not_found: documento inexistente ou de outra empresa. - 4XXOutro erro do cliente, no mesmo formato.
- 500
internal_error: repita com a mesmaIdempotency-Key. - 503
capacity_busy: espereRetry-Aftere repita.
curl "https://finstat.com.br/v1/documents/00000000-0000-4000-8000-000000000001" \
-H "Authorization: Bearer $FINSTAT_API_KEY"import { Finstat } from "finstat";
const finstat = new Finstat(process.env.FINSTAT_API_KEY!);
const document = await finstat.documents.retrieve("00000000-0000-4000-8000-000000000001");
console.log(document.status, document.reason);import os
import httpx
response = httpx.get(
"https://finstat.com.br/v1/documents/00000000-0000-4000-8000-000000000001",
headers={
"Authorization": f"Bearer {os.environ['FINSTAT_API_KEY']}",
},
timeout=60,
)
response.raise_for_status()
print(response.json()){
"id": "00000000-0000-4000-8000-000000000001",
"status": "review",
"reason": null,
"pages": 12,
"processing_seconds": 41.5,
"engine_version": "1.0.0",
"model_version": "1.0.0"
}Buscar resultado
GET/v1/documents/{job_id}/result
Devolve o histórico liberado só deste documento. Antes da liberação responde 409 not_completed. Formato em Resultado e histórico.
Escopo: documents:read
Parâmetros de caminho
job_idstringobrigatório- Id do documento, devolvido no envio (
id).
Cabeçalhos
AuthorizationstringobrigatórioBearer fst_..., chave com o escopodocuments:read.
Respostas
- 200Histórico liberado do documento.
- 401
unauthorized: chave ausente, inválida, revogada, expirada ou sem o escopo - 404
not_found: documento inexistente ou de outra empresa. - 409
not_completed: resultado antes da liberação. - 4XXOutro erro do cliente, no mesmo formato.
- 500
internal_error: repita com a mesmaIdempotency-Key. - 503
capacity_busy: espereRetry-Aftere repita.
curl "https://finstat.com.br/v1/documents/00000000-0000-4000-8000-000000000001/result" \
-H "Authorization: Bearer $FINSTAT_API_KEY"import { Finstat } from "finstat";
const finstat = new Finstat(process.env.FINSTAT_API_KEY!);
import { FinstatNotReadyError } from "finstat";
try {
const history = await finstat.documents.result("00000000-0000-4000-8000-000000000001");
for (const [period, entries] of Object.entries(history)) {
console.log(period, entries.length);
}
} catch (error) {
if (!(error instanceof FinstatNotReadyError)) throw error;
// Ainda em conferência: espere o webhook "completed".
}import os
import httpx
response = httpx.get(
"https://finstat.com.br/v1/documents/00000000-0000-4000-8000-000000000001/result",
headers={
"Authorization": f"Bearer {os.environ['FINSTAT_API_KEY']}",
},
timeout=60,
)
response.raise_for_status()
print(response.json()){
"Individual - 31/12/2025 - ": [
{
"termo_total": "ac - caixa e equivalentes",
"valor": "152340.75",
"moeda": "BRL",
"escala": "1",
"tipo": "balanco",
"section": "ac",
"subsection": "",
"data": "31/12/2025",
"data_ano": "2025",
"data_init": "",
"page": 2,
"bbox_left": 0.62,
"bbox_top": 0.214,
"bbox_width": 0.12,
"bbox_height": 0.015,
"x": 0.62,
"y": 0.214,
"conf": 1,
"tipo_balanco": "Individual",
"consolidado": false,
"empresa": "Empresa Exemplo Ltda",
"cnpj": "00000000000191",
"id": "00000000-0000-4000-8000-000000000001-0",
"unique_id": "00000000-0000-4000-8000-000000000001-0",
"parent": "",
"is_total": 0,
"formula": "",
"tempo": "",
"over_threshold_h": 0,
"over_threshold_v": 0
},
{
"termo_total": "dre - receita bruta",
"valor": "1250000.00",
"moeda": "BRL",
"escala": "1",
"tipo": "dre",
"section": "dre",
"subsection": "",
"data": "31/12/2025",
"data_ano": "2025",
"data_init": "",
"page": 4,
"bbox_left": 0.62,
"bbox_top": 0.188,
"bbox_width": 0.12,
"bbox_height": 0.015,
"x": 0.62,
"y": 0.188,
"conf": 1,
"tipo_balanco": "Individual",
"consolidado": false,
"empresa": "Empresa Exemplo Ltda",
"cnpj": "00000000000191",
"id": "00000000-0000-4000-8000-000000000001-1",
"unique_id": "00000000-0000-4000-8000-000000000001-1",
"parent": "",
"is_total": 0,
"formula": "",
"tempo": "",
"over_threshold_h": 0,
"over_threshold_v": 0
}
]
}Consultar histórico do CNPJ
GET/v1/history/{cnpj}
Junta os documentos liberados deste CNPJ na sua empresa, por entidade e data. Responde {} quando não há liberação. Durante uma nova conferência, continua com a última versão liberada.
Escopo: documents:read
Parâmetros de caminho
cnpjstringobrigatório- CNPJ, 14 caracteres sem pontuação.
Cabeçalhos
AuthorizationstringobrigatórioBearer fst_..., chave com o escopodocuments:read.
Respostas
- 200Histórico liberado do CNPJ (
{}quando não há). - 401
unauthorized: chave ausente, inválida, revogada, expirada ou sem o escopo - 4XXOutro erro do cliente, no mesmo formato.
- 500
internal_error: repita com a mesmaIdempotency-Key. - 503
capacity_busy: espereRetry-Aftere repita.
curl "https://finstat.com.br/v1/history/00000000000191" \
-H "Authorization: Bearer $FINSTAT_API_KEY"import { Finstat } from "finstat";
const finstat = new Finstat(process.env.FINSTAT_API_KEY!);
const history = await finstat.history.retrieve("00000000000191");import os
import httpx
response = httpx.get(
"https://finstat.com.br/v1/history/00000000000191",
headers={
"Authorization": f"Bearer {os.environ['FINSTAT_API_KEY']}",
},
timeout=60,
)
response.raise_for_status()
print(response.json()){
"Individual - 31/12/2025 - ": [
{
"termo_total": "ac - caixa e equivalentes",
"valor": "152340.75",
"moeda": "BRL",
"escala": "1",
"tipo": "balanco",
"section": "ac",
"subsection": "",
"data": "31/12/2025",
"data_ano": "2025",
"data_init": "",
"page": 2,
"bbox_left": 0.62,
"bbox_top": 0.214,
"bbox_width": 0.12,
"bbox_height": 0.015,
"x": 0.62,
"y": 0.214,
"conf": 1,
"tipo_balanco": "Individual",
"consolidado": false,
"empresa": "Empresa Exemplo Ltda",
"cnpj": "00000000000191",
"id": "00000000-0000-4000-8000-000000000001-0",
"unique_id": "00000000-0000-4000-8000-000000000001-0",
"parent": "",
"is_total": 0,
"formula": "",
"tempo": "",
"over_threshold_h": 0,
"over_threshold_v": 0
},
{
"termo_total": "dre - receita bruta",
"valor": "1250000.00",
"moeda": "BRL",
"escala": "1",
"tipo": "dre",
"section": "dre",
"subsection": "",
"data": "31/12/2025",
"data_ano": "2025",
"data_init": "",
"page": 4,
"bbox_left": 0.62,
"bbox_top": 0.188,
"bbox_width": 0.12,
"bbox_height": 0.015,
"x": 0.62,
"y": 0.188,
"conf": 1,
"tipo_balanco": "Individual",
"consolidado": false,
"empresa": "Empresa Exemplo Ltda",
"cnpj": "00000000000191",
"id": "00000000-0000-4000-8000-000000000001-1",
"unique_id": "00000000-0000-4000-8000-000000000001-1",
"parent": "",
"is_total": 0,
"formula": "",
"tempo": "",
"over_threshold_h": 0,
"over_threshold_v": 0
}
]
}Objetos
DocumentStatus
Resposta do envio e da consulta de documento.
idstringobrigatório- Id do documento.
statusJobStatusobrigatório- Situação:
queued,processing,review,completed,rejectedouerror. reasonstring | nullobrigatório- Motivo da situação, quando houver;
nullcaso contrário. Veja Situações. pagesintegerobrigatório- Páginas do PDF (
0antes do processamento). processing_secondsnumberobrigatório- Tempo de processamento, em segundos.
engine_versionstring- Versão de processamento que gerou a extração (vazia antes dela).
model_versionstring- Versão complementar de processamento (vazia antes dela).
HistoryEntry
Uma linha do histórico. O histórico (History) é um objeto cuja chave junta entidade e data (Individual - 31/12/2025 - ) e cujo valor é uma lista de HistoryEntry.
tempostring- Reservado; hoje vazio.
confnumber1indica conferência humana. Não é probabilidade.datastringobrigatório- Data do período,
dd/mm/aaaa. data_anostringobrigatório- Ano do período.
termo_totalstringobrigatório- A conta, um dos termos (
TermoTotal). valorstringobrigatório- String decimal com duas casas, em reais. Não converta para float.
pageintegerobrigatório- Página do PDF onde está o valor, começando em 1.
idstringobrigatório- Id da linha: o id do documento seguido de
-e um número. subsectionstring- Reservado; hoje vazio.
tipostringobrigatóriobalancooudre.sectionstringobrigatório- Grupo do termo: o prefixo de
termo_total(ac,pc,dre...). moedastring- Moeda,
BRL. escalastring- Escala do valor;
1indica quevalorjá está em reais. empresastringobrigatório- Nome da empresa.
cnpjstringobrigatório- CNPJ informado no envio.
consolidadobooleanobrigatóriotruequando a entidade éConsolidado.tipo_balancoenumobrigatório- Entidade:
Individual,Controladora,ConsolidadoouCombinado. ynumberobrigatório- Igual a
bbox_top(compatibilidade). xnumberobrigatório- Igual a
bbox_left(compatibilidade). unique_idstringobrigatório- Igual a
id(compatibilidade). parentstring- Reservado; hoje vazio.
is_totalinteger- Reservado; hoje
0. over_threshold_hinteger- Reservado; hoje
0. over_threshold_vinteger- Reservado; hoje
0. bbox_leftnumberobrigatório- Borda esquerda do valor, em fração da largura da página (0 a 1).
bbox_topnumberobrigatório- Borda superior do valor, em fração da altura da página (0 a 1).
bbox_heightnumberobrigatório- Altura do valor, em fração da altura da página.
bbox_widthnumberobrigatório- Largura do valor, em fração da largura da página.
data_initstring- Reservado; hoje vazio.
formulastring- Reservado; hoje vazio.
ApiError
Corpo de todo erro da API.
errorstringobrigatório- Código estável do erro. Nunca ecoa o que você enviou. Veja Erros.