Seu relatório de contas a receber puxa todo o histórico da Conta Azul numa chamada só, de 2019 até hoje? Funciona. Ou funcionava, até cair em timeout num dia aleatório e você ter que clicar em "Atualizar" de novo, rsrsrs.
A Conta Azul avisou os integradores: a partir de 10/11/2026, as buscas de contas a pagar e a receber passam a ter dois limites. Período máximo de 1 ano em todos os filtros de data e tamanho_pagina só com os valores da documentação. Fora disso, a API devolve erro 400, e a sua atualização para.
Neste passo a passo você vai ajustar a carga no Power BI (Power Query M) e em Python para buscar em janelas de 1 ano, paginar do jeito certo e, de quebra, montar uma sincronização incremental que pesa muito menos. Bora lá.
Requisitos
- API Conta Azul, módulo Financeiro
v1, servidorhttps://api-v2.contaazul.com - Aplicação cadastrada no Portal do Desenvolvedor da Conta Azul e um token de acesso válido (OAuth 2.0). Se ainda não tem, comece pelo artigo Conta Azul: como tratar o Extrato de Movimentações no Power BI
- Power BI Desktop (Power Query) ou Python 3 com a biblioteca
requests - Válido em: outubro/2026, conforme o comunicado da Conta Azul aos integradores, a especificação OpenAPI do Financeiro e o changelog oficial
O que muda em 10/11/2026
Os limites valem para quatro rotas:
GET /v1/financeiro/eventos-financeiros/contas-a-pagar/buscar
GET /v1/financeiro/eventos-financeiros/contas-a-receber/buscar
GET /v1/financeiro/contas-a-pagar
GET /v1/financeiro/contas-a-receber
As duas últimas são as rotas novas da mesma busca e seguem as mesmas regras.
| Parâmetro | Hoje | A partir de 10/11/2026 |
|---|---|---|
data_vencimento_de / _ate | Sem limite | Até 1 ano |
data_competencia_de / _ate | Sem limite | Até 1 ano |
data_pagamento_de / _ate | Sem limite | Até 1 ano |
data_criacao_de / _ate | Sem limite | Até 1 ano |
data_alteracao_de / _ate | Até 1 ano | Sem mudança |
tamanho_pagina | Qualquer valor | 10, 20, 50, 100, 200, 500 ou 1000 |
O filtro de vencimento (data_vencimento_de e data_vencimento_ate) continua obrigatório. O motivo, segundo a própria Conta Azul: buscas de vários anos com centenas de páginas pesam no banco, deixam a API lenta para todo mundo e muitas vezes terminam em timeout (erro 500). Com o limite, a resposta fica previsível. Se passar do limite, o erro 400 vem na hora, com uma mensagem dizendo o que ajustar.
a busca por POST nesses mesmos caminhos já deixou de existir em 19/10/2026. Se a sua integração ainda faz POST .../buscar, troque para GET, com os filtros na query string.
1 Quebre o período em janelas de 1 ano
A regra prática é a do próprio exemplo da Conta Azul: uma chamada por ano-calendário, de 01/01 a 31/12. Para buscar de 2024 a 2026:
?data_vencimento_de=2024-01-01&data_vencimento_ate=2024-12-31
?data_vencimento_de=2025-01-01&data_vencimento_ate=2025-12-31
?data_vencimento_de=2026-01-01&data_vencimento_ate=2026-12-31
Por que ano-calendário e não "hoje menos 365 dias"? Porque as janelas ficam fixas, fáceis de conferir e sem sobreposição. E 2024, que é bissexto, está no exemplo oficial.
conta a pagar e a receber tem vencimento no futuro. Não pare a carga em "hoje". Vá até o fim do ano que vem (ou até o horizonte que o seu fluxo de caixa usa), senão as parcelas futuras somem do relatório.
2 Use um tamanho de página válido e percorra as páginas
tamanho_pagina passa a aceitar só 10, 20, 50, 100, 200, 500 ou 1000. Se você usa outro valor (300, 5000...), troque pelo permitido mais próximo, até 1000. Para carga de BI, use 1000: menos chamadas por janela.
A resposta traz itens_totais, itens e totais. Com itens_totais você sabe quantas páginas existem e para de chamar na hora certa:
páginas = arredonda_para_cima(itens_totais / tamanho_pagina)
a documentação marca tamanho_pagina como obrigatório, e o comunicado diz que, sem ele, o padrão é 10. Envie sempre. Página de 10 itens multiplica as chamadas por 100.
3 No Power BI: consulta M com janelas e paginação
Abra o Power Query (Página Inicial > Transformar dados), crie uma Consulta Nula (Nova Fonte > Consulta Nula), abra o Editor Avançado e cole:
let
// Ajuste o período e o token (veja o artigo de token da Conta Azul)
Token = "SEU_TOKEN",
Inicio = #date(2024, 1, 1),
Fim = #date(Date.Year(DateTime.Date(DateTime.LocalNow())) + 1, 12, 31),
TamanhoPagina = 1000,
// 1. Uma janela por ano-calendário (máximo de 1 ano por busca)
Janelas = List.Transform(
{Date.Year(Inicio) .. Date.Year(Fim)},
each [
de = Date.ToText(List.Max({#date(_, 1, 1), Inicio}), "yyyy-MM-dd"),
ate = Date.ToText(List.Min({#date(_, 12, 31), Fim}), "yyyy-MM-dd")
]
),
// 2. Busca uma página de uma janela
BuscarPagina = (janela as record, pagina as number) as record =>
Json.Document(
Web.Contents(
"https://api-v2.contaazul.com",
[
RelativePath = "v1/financeiro/eventos-financeiros/contas-a-receber/buscar",
Query = [
pagina = Text.From(pagina),
tamanho_pagina = Text.From(TamanhoPagina),
data_vencimento_de = janela[de],
data_vencimento_ate = janela[ate]
],
Headers = [Authorization = "Bearer " & Token]
]
)
),
// 3. Todas as páginas de uma janela, usando itens_totais
BuscarJanela = (janela as record) as list =>
let
Primeira = BuscarPagina(janela, 1),
TotalPaginas = Number.RoundUp(Primeira[itens_totais] / TamanhoPagina),
Demais = List.Transform({2 .. TotalPaginas}, each BuscarPagina(janela, _)[itens])
in
List.Combine({Primeira[itens]} & Demais),
// 4. Junta todas as janelas numa tabela
Itens = List.Combine(List.Transform(Janelas, BuscarJanela)),
Tabela = Table.FromRecords(Itens, null, MissingField.UseNull)
in
Tabela
Conforme a especificação oficial da API; não executado aqui, porque exige o token da sua conta.
O que vale entender:
- URL base fixa +
RelativePath+Query: é isso que permite a atualização agendada no serviço do Power BI. Se você montar a URL inteira concatenando texto, o serviço reclama de fonte dinâmica e não atualiza. {2 .. TotalPaginas}: quando a janela tem uma página só (ou nenhuma), essa lista fica vazia, e a consulta não faz chamada extra.- Para contas a pagar, troque o
RelativePathparav1/financeiro/eventos-financeiros/contas-a-pagar/buscar. O resto é igual. - Cada item vem com
id,descricao,data_vencimento,status,total,pago,nao_pago,data_competencia,data_alteracao,categorias,centros_custoecliente(oufornecedor, em contas a pagar). Expanda as colunas que o seu relatório usa.
o token não fica no código em produção. Use o fluxo de token que você já tem (parâmetro ou consulta que gera o token) e só referencie aqui.
4 Em Python: carga em janelas com paginação
Para quem carrega um banco próprio (ou usa Pentaho/n8n e quer a lógica pronta), este script faz o mesmo e respeita o limite de requisições:
import datetime as dt
import time
import requests
BASE = "https://api-v2.contaazul.com"
TOKEN = "SEU_TOKEN"
CAMINHO = "/v1/financeiro/eventos-financeiros/contas-a-receber/buscar"
TAMANHOS_VALIDOS = (10, 20, 50, 100, 200, 500, 1000)
def janelas_anuais(inicio, fim):
"""Quebra o período em anos-calendário: 01/01 a 31/12, cortando nas pontas."""
for ano in range(inicio.year, fim.year + 1):
yield max(dt.date(ano, 1, 1), inicio), min(dt.date(ano, 12, 31), fim)
def buscar_janela(sessao, de, ate, tamanho_pagina=1000, filtros_extras=None):
"""Percorre todas as páginas de uma janela de vencimento."""
if tamanho_pagina not in TAMANHOS_VALIDOS:
raise ValueError(f"tamanho_pagina precisa ser um de {TAMANHOS_VALIDOS}")
pagina = 1
while True:
params = {
"pagina": pagina,
"tamanho_pagina": tamanho_pagina,
"data_vencimento_de": de.isoformat(),
"data_vencimento_ate": ate.isoformat(),
**(filtros_extras or {}),
}
resp = sessao.get(BASE + CAMINHO, params=params, timeout=60)
if resp.status_code == 429: # passou do limite de requisições: espera e repete
time.sleep(int(resp.headers.get("Retry-After", 5)))
continue
if resp.status_code == 400: # a API diz o que ajustar no corpo do erro
raise RuntimeError(f"400 na janela {de} a {ate}: {resp.text}")
resp.raise_for_status()
corpo = resp.json()
itens = corpo.get("itens", [])
yield from itens
if not itens or pagina * tamanho_pagina >= corpo.get("itens_totais", 0):
break
pagina += 1
time.sleep(0.15) # ~6 chamadas/s, abaixo do limite de 10/s
def carregar(inicio, fim, filtros_extras=None):
sessao = requests.Session()
sessao.headers["Authorization"] = f"Bearer {TOKEN}"
contas = []
for de, ate in janelas_anuais(inicio, fim):
contas.extend(buscar_janela(sessao, de, ate, filtros_extras=filtros_extras))
return contas
if __name__ == "__main__":
hoje = dt.date.today()
contas = carregar(dt.date(2024, 1, 1), dt.date(hoje.year + 1, 12, 31))
print(f"{len(contas)} contas a receber carregadas")
Este script foi executado contra o mock server oficial da documentação da Conta Azul. A resposta veio no formato documentado (itens_totais, itens, totais), e a paginação parou no lugar certo. Contra a API real, troque SEU_TOKEN pelo seu token.
Por que o time.sleep(0.15)? O limite da API é de 600 chamadas por minuto e até 10 por segundo por conta conectada. Passando disso, vem 429 Too Many Requests. Paginar 1000 em 1000 com uma pausa curta mantém você longe do limite.
5 Sincronize só o que mudou (carga incremental)
Depois da carga inicial, não baixe tudo de novo todo dia. Os filtros data_alteracao_de e data_alteracao_ate trazem criações, edições, baixas, estornos e cancelamentos. Como o vencimento continua obrigatório, combine a data de alteração com as mesmas janelas de 1 ano:
agora = dt.datetime.now()
ontem = agora - dt.timedelta(days=1)
hoje = dt.date.today()
mudancas = carregar(
dt.date(2024, 1, 1),
dt.date(hoje.year + 1, 12, 31),
filtros_extras={
"data_alteracao_de": ontem.strftime("%Y-%m-%dT%H:%M:%S"),
"data_alteracao_ate": agora.strftime("%Y-%m-%dT%H:%M:%S"),
},
)
# atualize no seu banco cada conta de `mudancas` pelo campo `id`
A documentação define a data de alteração em ISO 8601, no horário de São Paulo (GMT-3), e o exemplo oficial usa o formato 2025-10-20T07:00:00, sem fuso. É o formato do código acima. A janela de alteração também é limitada a 365 dias.
Este trecho segue a documentação; não foi executado contra a API real. O mock server da documentação é mais rígido que o exemplo oficial e só aceita a data com fuso (2025-10-20T07:00:00-03:00). Se a API real recusar o formato sem fuso, acrescente -03:00.
conta excluída não aparece na busca por alteração. Ela simplesmente para de vir. Para não manter registro fantasma, faça de tempos em tempos (por exemplo, uma vez por dia) uma varredura completa em janelas de 1 ano e apague o que não voltou:
ids_api = {conta["id"] for conta in carregar(dt.date(2024, 1, 1), dt.date(hoje.year + 1, 12, 31))}
excluidos = ids_no_seu_banco - ids_api # ids_no_seu_banco: conjunto de ids que você já tem
No Power BI em modo de importação, cada atualização recarrega a tabela inteira, então exclusão não é problema. A carga incremental e a varredura fazem diferença para quem guarda os dados num banco próprio.
Erros comuns
Erro 400 depois de 10/11/2026
A partir dessa data, período de busca maior que 1 ano ou tamanho_pagina fora da lista retornam 400. Os erros do Financeiro vêm no formato:
{"error": "<mensagem>"}
A Conta Azul ainda não publicou o texto exato dessa mensagem. Registre o corpo da resposta, como o script Python faz no RuntimeError, para saber qual parâmetro ajustar. Correção: confira se cada janela tem no máximo 1 ano e se tamanho_pagina é 10, 20, 50, 100, 200, 500 ou 1000.
Erro 500 ou timeout em busca longa
É exatamente o problema que motivou a mudança: períodos de vários anos com centenas de páginas. Correção: janelas de 1 ano, como no passo 1, já resolvem, mesmo antes de 10/11.
429 Too Many Requests
Você passou de 10 chamadas por segundo ou 600 por minuto. Correção: espere e repita (o script já faz isso) e mantenha uma pausa curta entre páginas.
Busca sem vencimento
data_vencimento_de e data_vencimento_ate são obrigatórios, inclusive na carga incremental por data de alteração. Correção: sempre envie as duas datas da janela.
POST em /buscar
A busca por POST deixou de existir em 19/10/2026. Correção: use GET no mesmo caminho, com os filtros como parâmetros da URL.
Dica bônus
Se você só precisa das contas em aberto para o fluxo de caixa, filtre por status além das janelas. Menos itens por janela, menos páginas, atualização mais rápida. Confira na documentação os valores aceitos de status antes de fixar no código.
Conclusão
Com janelas de 1 ano, tamanho_pagina=1000 e paginação por itens_totais, a sua carga continua funcionando depois de 10/11/2026 e ainda fica mais estável do que hoje. Para quem mantém banco próprio, a sincronização por data de alteração com a varredura de exclusões deixa a rotina diária bem mais leve, para você e para a API.
Agora é só adaptar para o seu projeto: contas a pagar, contas a receber, e o horizonte de datas do seu negócio. Qualquer dúvida, comenta aqui.
E se você quer dominar esse tipo de integração do começo: na Formação Chora API, as aulas usam consultas reais nos sistemas Conta Azul, Omie, Bling e Nibo.
Quer dominar integrações com o Conta Azul e outros ERPs?
Na Formação Chora API você aprende a puxar os dados direto do sistema por API e a atualizar o relatório sozinho. As aulas usam consultas reais em Conta Azul, Omie, Bling e Nibo.
Ver a Formação →Referências
- Financeiro (v1) — especificação OpenAPI — Conta Azul Developers, consultado em 28/10/2026
- Change Log — API Conta Azul — entradas de 05/03/2026 (limite de 365 dias em
data_alteracao) e 19/10/2026 (fim doPOST .../buscare novo formato de erro), consultado em 28/10/2026 - FAQ — Perguntas frequentes sobre a API da Conta Azul — limite de requisições, consultado em 28/10/2026
- Comunicado da Conta Azul aos integradores sobre limites nas buscas de contas a pagar e a receber (prazo 10/11/2026), recebido em outubro de 2026