Referência da API
Cada rota da API v1, com os campos, os exemplos e o significado de cada resposta.
Esta página é gerada do contrato da API (openapi-v1.json), o mesmo arquivo que a API confere a cada mudança. Cada rota mostra para que serve, os campos do pedido, a resposta de sucesso e o que cada erro quer dizer.
Para começar do zero, leia antes a primeira chamada e a autenticação.
/api/v1/trial-balancesLista os balancetes importados, com competência, versão, status e quem importou. Filtre por companyId e por period (AAAA-MM, por exemplo 2026-08). Serve para conferir se o balancete que o ERP enviou chegou e foi liberado. Escopo: trial_balances:read.
A resposta vem em páginas: data traz as linhas e pagination diz a página, o tamanho, o total de linhas e o total de páginas. O padrão é 50 linhas por página, e o máximo é 100 (limit). Para ler tudo, repita a chamada com page=1, page=2 e assim por diante, até pagination.pages. Limite: 30 chamadas por minuto por rota.
Authorization: Bearer
Enviado em: header
Parâmetros da URL
Página, a partir de 1.
Linhas por página, de 1 a 100. Padrão 50.
Id da empresa no TOPO.
Competência, no formato AAAA-MM.
Corpo da resposta
application/json
application/json
application/json
application/json
application/json
curl -X GET "https://example.com/api/v1/trial-balances"{ "data": [ { "id": 318, "empresaId": 12, "empresaNome": "Transportes Exemplo Ltda", "competencia": "2026-08", "versao": 2, "status": "RELEASED", "importadoEm": "2026-09-03T14:12:05.000Z", "importadoPor": "Chave de API SAP balancete (a1B2c3D4e5F6g7H8)", "linhas": 474 } ], "pagination": { "page": 1, "limit": 50, "total": 132, "pages": 3 }}/api/v1/trial-balancesEnvia o balancete de uma competência em JSON, direto do ERP, sem planilha. Informe a empresa por companyId ou por cnpj, a competência em period (AAAA-MM) e as linhas em lineItems, até 20.000 por chamada. A resposta diz quantas linhas vieram, quantas entraram e por que as outras ficaram de fora; avisos não impedem a importação. Escopo: trial_balances:write. Limite: 30 chamadas por minuto.
O que acontece no TOPO: o balancete entra na competência da empresa com as mesmas validações da tela (plano de contas, natureza dos saldos, continuidade com o mês anterior) e fica pronto para o cliente liberar as conciliações. Reenviar o mesmo conteúdo não duplica nada: a resposta é 200 com reenvio: true. Conteúdo diferente na mesma competência cria uma versão nova.
Authorization: Bearer
Enviado em: header
Corpo do pedido
application/json
Tipos em TypeScript
Use o tipo request body em TypeScript.
Corpo da resposta
application/json
application/json
application/json
application/json
application/json
application/json
application/json
application/json
curl -X POST "https://example.com/api/v1/trial-balances" \ -H "Content-Type: application/json" \ -d '{ "companyId": 12, "cnpj": "12.345.678/0001-90", "period": "2026-09", "chartName": "Plano de Contas Divisão Logística", "lineItems": [ { "accountCode": "1.1.01.001", "accountName": "Caixa Geral", "previousBalance": 1000.5, "debit": 250, "credit": 100, "finalBalance": 1150.5 } ] }'{ "success": true, "data": { "reenvio": false, "trialBalanceId": 318, "enviadas": 474, "importadas": 207, "ignoradasForaDoPlano": 3, "ignoradasQueNaoConciliam": 264, "avisos": [ "Saldo anterior da conta 1.1.01 diferente do saldo final do mês anterior" ] }}/api/v1/trial-balances/arquivoEnvia o mesmo relatório que o usuário subiria na tela, no campo file de um formulário multipart, com cnpj ou companyId. Use quando o ERP já gera o arquivo e montar o JSON dá mais trabalho. Vale o mapeamento de colunas salvo para a empresa na tela de importação. Competência e plano de contas saem do arquivo quando não vêm no formulário. Escopo: trial_balances:write. Limite: 30 chamadas por minuto.
O que acontece no TOPO: o balancete entra na competência da empresa com as mesmas validações da tela (plano de contas, natureza dos saldos, continuidade com o mês anterior) e fica pronto para o cliente liberar as conciliações. Reenviar o mesmo conteúdo não duplica nada: a resposta é 200 com reenvio: true. Conteúdo diferente na mesma competência cria uma versão nova.
Authorization: Bearer
Enviado em: header
Corpo do pedido
multipart/form-data
Tipos em TypeScript
Use o tipo request body em TypeScript.
Corpo da resposta
application/json
application/json
application/json
application/json
application/json
application/json
application/json
application/json
curl -X POST "https://example.com/api/v1/trial-balances/arquivo" \ -F file="string"{ "success": true, "data": { "reenvio": false, "trialBalanceId": 318, "enviadas": 474, "importadas": 207, "ignoradasForaDoPlano": 3, "ignoradasQueNaoConciliam": 264, "avisos": [ "Saldo anterior da conta 1.1.01 diferente do saldo final do mês anterior" ] }}/api/v1/companiesLista as empresas do cliente da chave, com razão social, CNPJ e regime tributário. Use no começo da integração para descobrir o id de cada empresa, que as outras rotas pedem em companyId. Só lê: nada muda no TOPO. Escopo: companies:read.
A resposta vem em páginas: data traz as linhas e pagination diz a página, o tamanho, o total de linhas e o total de páginas. O padrão é 50 linhas por página, e o máximo é 100 (limit). Para ler tudo, repita a chamada com page=1, page=2 e assim por diante, até pagination.pages. Limite: 30 chamadas por minuto por rota.
Authorization: Bearer
Enviado em: header
Parâmetros da URL
Página, a partir de 1.
Linhas por página, de 1 a 100. Padrão 50.
Corpo da resposta
application/json
application/json
application/json
application/json
application/json
curl -X GET "https://example.com/api/v1/companies"{ "data": [ { "id": 12, "razaoSocial": "Transportes Exemplo Ltda", "nomeFantasia": "Exemplo Logística", "cnpj": "12345678000190", "regimeTributario": "REAL_PROFIT", "status": "ACTIVE", "empresaControladoraId": null } ], "pagination": { "page": 1, "limit": 50, "total": 132, "pages": 3 }}/api/v1/chart-of-accountsLista os planos de contas da empresa informada em companyId (obrigatório). Uma empresa pode ter mais de um plano ativo; o balancete diz qual usar. Use o id do plano para ler as contas em /api/v1/chart-of-accounts/{id}/accounts. Escopo: chart_of_accounts:read.
A resposta vem em páginas: data traz as linhas e pagination diz a página, o tamanho, o total de linhas e o total de páginas. O padrão é 50 linhas por página, e o máximo é 100 (limit). Para ler tudo, repita a chamada com page=1, page=2 e assim por diante, até pagination.pages. Limite: 30 chamadas por minuto por rota.
Authorization: Bearer
Enviado em: header
Parâmetros da URL
Página, a partir de 1.
Linhas por página, de 1 a 100. Padrão 50.
Id da empresa no TOPO.
Corpo da resposta
application/json
application/json
application/json
application/json
application/json
curl -X GET "https://example.com/api/v1/chart-of-accounts?companyId=0"{ "data": [ { "id": 4, "empresaId": 12, "nome": "Plano de Contas Divisão Logística", "vigenciaInicio": "2026-01-01", "vigenciaFim": null, "ativo": true, "versao": 1 } ], "pagination": { "page": 1, "limit": 50, "total": 132, "pages": 3 }}/api/v1/chart-of-accounts/{id}/accountsLista as contas do plano id, com código, código reduzido, natureza e se a conta entra na conciliação. Filtre por empresa com companyId. Útil para montar o de-para entre o plano do ERP e o do TOPO antes de enviar o balancete. Escopo: chart_of_accounts:read.
A resposta vem em páginas: data traz as linhas e pagination diz a página, o tamanho, o total de linhas e o total de páginas. O padrão é 50 linhas por página, e o máximo é 100 (limit). Para ler tudo, repita a chamada com page=1, page=2 e assim por diante, até pagination.pages. Limite: 30 chamadas por minuto por rota.
Authorization: Bearer
Enviado em: header
Parâmetros do caminho
Id do plano de contas, o id que GET /api/v1/chart-of-accounts devolve.
Parâmetros da URL
Página, a partir de 1.
Linhas por página, de 1 a 100. Padrão 50.
Id da empresa no TOPO.
Corpo da resposta
application/json
application/json
application/json
application/json
application/json
curl -X GET "https://example.com/api/v1/chart-of-accounts/0/accounts"{ "data": [ { "id": 881, "planoId": 4, "empresaId": 12, "codigo": "1.1.01.001", "codigoReduzido": "1001", "descricao": "Caixa Geral", "tipo": "ANALYTICAL", "natureza": "DEBIT", "classificacao": "Ativo Circulante", "departamento": "Financeiro", "setor": "Tesouraria", "exigeConciliacao": true } ], "pagination": { "page": 1, "limit": 50, "total": 132, "pages": 3 }}/api/v1/trial-balances/{id}/linesDevolve as linhas do balancete id: conta, saldo anterior, débito, crédito e saldo final. Pegue o id na lista de balancetes. É a rota que o Power BI usa para montar a tabela de saldos. Escopo: trial_balances:read.
A resposta vem em páginas: data traz as linhas e pagination diz a página, o tamanho, o total de linhas e o total de páginas. O padrão é 50 linhas por página, e o máximo é 100 (limit). Para ler tudo, repita a chamada com page=1, page=2 e assim por diante, até pagination.pages. Limite: 30 chamadas por minuto por rota.
Authorization: Bearer
Enviado em: header
Parâmetros do caminho
Id do balancete, o id que GET /api/v1/trial-balances devolve.
Parâmetros da URL
Página, a partir de 1.
Linhas por página, de 1 a 100. Padrão 50.
Corpo da resposta
application/json
application/json
application/json
application/json
application/json
curl -X GET "https://example.com/api/v1/trial-balances/0/lines"{ "data": [ { "balanceteId": 318, "empresaId": 12, "competencia": "2026-08", "contaCodigo": "1.1.01.001", "contaDescricao": "Caixa Geral", "saldoAnterior": 1000.5, "debito": 250, "credito": 100, "saldoFinal": 1150.5 } ], "pagination": { "page": 1, "limit": 50, "total": 132, "pages": 3 }}/api/v1/reconciliationsLista as conciliações com status, responsável atual, prazo, situação do prazo (SLA) e os saldos contábil, conciliado e a diferença. Filtre por companyId e period. O responsável é o mesmo nome da coluna Responsável da tela. Escopo: reconciliations:read.
A resposta vem em páginas: data traz as linhas e pagination diz a página, o tamanho, o total de linhas e o total de páginas. O padrão é 50 linhas por página, e o máximo é 100 (limit). Para ler tudo, repita a chamada com page=1, page=2 e assim por diante, até pagination.pages. Limite: 30 chamadas por minuto por rota.
Authorization: Bearer
Enviado em: header
Parâmetros da URL
Página, a partir de 1.
Linhas por página, de 1 a 100. Padrão 50.
Id da empresa no TOPO.
Competência, no formato AAAA-MM.
Corpo da resposta
application/json
application/json
application/json
application/json
application/json
curl -X GET "https://example.com/api/v1/reconciliations"{ "data": [ { "id": 5120, "empresaId": 12, "empresaNome": "Transportes Exemplo Ltda", "competencia": "2026-08", "contaId": 881, "contaCodigo": "1.1.01.001", "contaDescricao": "Caixa Geral", "status": "IN_ELABORATION", "responsavelNome": "Mariana Souza", "responsavelPapel": "Elaborador", "prazo": "2026-09-05T00:00:00.000Z", "slaStatus": "ON_TIME", "saldoContabil": 1150.5, "saldoConciliado": 1150.5, "diferenca": 0, "ajustes": 0 } ], "pagination": { "page": 1, "limit": 50, "total": 132, "pages": 3 }}/api/v1/graphqlOs mesmos dados da leitura REST numa chamada só: empresas, planosDeContas, contas, balancetes, linhasDoBalancete e conciliacoes, com os mesmos filtros e a mesma paginação. Envie um JSON com query e, se houver, variables, com o cabeçalho Content-Type: application/json. Não existe mutation: nada muda no TOPO.
Os erros seguem o formato GraphQL: a resposta traz errors, cada um com message em português e extensions.code. Códigos comuns: SO_LEITURA (mandou mutation), PROFUNDIDADE_EXCEDIDA e COMPLEXIDADE_EXCEDIDA (consulta grande demais: peça menos campos ou páginas menores) e CONTENT_TYPE_INVALIDO (status 415). Escopo: analytics:read. Limite: 30 chamadas por minuto.
Authorization: Bearer
Enviado em: header
Corpo do pedido
application/json
Tipos em TypeScript
Use o tipo request body em TypeScript.
Corpo da resposta
application/json
curl -X POST "https://example.com/api/v1/graphql" \ -H "Content-Type: application/json" \ -d '{ "query": "query Saldos($empresa: Int!, $competencia: String!) {\\n balancetes(companyId: $empresa, period: $competencia) {\\n data { id competencia status linhas }\\n }\\n}", "variables": { "empresa": 12, "competencia": "2026-08" } }'