Pular para o conteúdo

Códigos HTTP, 120/min, paginação, idempotência

Aula 5 de 66 minConhecerAtualizada em 2026-10-04

Vídeo em produção

A gravação desta aula está no lote de produção. O objetivo, o exercício e a documentação já valem. Duração-alvo: 6 min.

Objetivo: Diagnosticar `429` com `Retry-After`

Selo de estado: Preview (teto atual do produto) · Curso ACD-250 — Integrações e consumo externo · Aula 5 de 6 · Atualizado em 2026-10-04.

Objetivo#

Ao final desta aula você vai diagnosticar 429 com Retry-After — e distinguir, pelo código HTTP, o que é seu erro, o que é teto de requisição, o que é dinheiro e o que é indisponibilidade proposital.

Vídeo#

Identificador no manifesto: acd-250-05-erros-rate-limit-idempotencia · duração-alvo 6 min · tela do produto: /connect.

Roteiro de gravação (5 capítulos):

#Minutagem-alvoCapítuloTela do produto
10:00–0:30Abertura: título + selo. Um formato de erro para tudo: { "error": "mensagem em português" }./connect
20:30–2:15O catálogo de códigos lido em voz alta, em quatro famílias: você · credencial · dinheiro · plataforma./connect
32:15–3:45Rate limit: 120/min por chave, 240/min por workspace; 429 com Retry-After. E o 503 fail-closed do limitador./connect
43:45–5:00Paginação (1.000 por página, 1.000.000 de profundidade) e idempotência: a API é somente leitura, logo repetir não muda nada./excel
55:00–6:00Webhooks são Roadmap: como reagir a mudanças hoje. Erros comuns e encerramento./connect

Conteúdo#

Esta é a aula dos contratos transversais — o que vale para todas as rotas /api/v1/**, independentemente da superfície. É aula de conhecimento porque não há nada para configurar: o que existe aqui é a capacidade de ler uma resposta de erro e saber o que fazer.

Começa com uma boa notícia: há um formato de erro para tudo.

json
{ "error": "Mensagem explicando o que aconteceu." }

Sempre JSON, sempre com mensagem em português, sempre com o código HTTP correspondente. As respostas — de sucesso e de erro — carregam X-Ingestia-Access-Scope: workspace, lembrete de que a credencial lê o workspace inteiro; o OData acrescenta OData-Version: 4.0.

O catálogo, em quatro famílias

CódigoSignificadoFamíliaCausas típicas
200 · 204OK · sem conteúdo—leitura bem-sucedida · pré-flight OPTIONS (CORS)
400requisição inválidavocêJSON malformado, sql ausente, $skiptoken inválido, paginação além do teto
401não autenticadocredencialchave ausente, inválida ou revogada
403proibidocredencialpapel ou escopo insuficiente, SQL não-SELECT, referência fora do workspace ou fora dos marts
404não encontradovocêEntitySet OData inexistente (também protege contra enumeração)
402pagamento necessáriodinheiroworkspace inadimplente ou suspenso — extração paga bloqueada
429muitas requisiçõestetoestourou o rate limit — traz Retry-After
501não implementadovocêoperação OData fora do subset suportado
502erro no datalakeplataformafalha ao executar a consulta no BigQuery
503indisponívelplataformadatalake não provisionado, nuvem própria caída, ou limitador indisponível — traz Retry-After

Ler por família acelera o diagnóstico: 400/404/501 você corrige na sua requisição; 401/403 você corrige na credencial (Aula 2); 402 é a regra do dinheiro; 429/503 você espera, não insiste.

Rate limit: 120/min, e o 503 que protege o seu bolso

Os limites são por janela de 1 minuto, aplicados por chave e por workspace — assim uma chave vazada não fura o teto do workspace:

BucketPor chavePor workspace
Leitura (OData, tables)120/min240/min
SQL livre (query)60/min120/min

Estourou? 429 com Retry-After: 60. O comportamento correto do cliente é simples e quase sempre feito errado: leia o Retry-After e espere o que ele diz, em vez de tentar de novo imediatamente. Reduzir paralelismo resolve mais do que repetir.

Agora a parte contraintuitiva e a mais importante desta aula. Se o serviço de rate limit ficar indisponível, a API nega com 503 em vez de liberar sem teto. Chama-se fail-closed, e a razão é econômica: as rotas /api/v1 executam BigQuery pago. Liberar sem limitador seria arriscar fatura ilimitada em nome da disponibilidade. O produto escolhe recusar.

Aviso

429 e 503 não são a mesma coisa 429 diz "você passou do seu teto" — é seu, e você controla reduzindo o ritmo. 503 com Retry-After diz "a plataforma não pode garantir o teto agora" — não é seu, e insistir não melhora. Ambos pedem a mesma reação imediata: respeitar o Retry-After.

Um detalhe que tranquiliza: os buckets da API são separados do BI nativo. Consumo externo pesado via Power BI não degrada o BI dentro do produto.

Paginação

Duas formas, porque são duas superfícies:

  • OData (Preview, Aula 3): server-driven, páginas de até 1.000 linhas com @odata.nextLink; siga o link exatamente (ele carrega um $skiptoken opaco — token adulterado responde 400). Prefer: odata.maxpagesize=N reduz a página (teto 1.000) e a resposta confirma com Preference-Applied. Profundidade máxima: 1.000.000 de linhas por consulta; acima, 400 orientando a filtrar.
  • REST (/api/v1/tables/{dataset}/{table}, fora de GA, Aula 6): limit (padrão 100, máximo 1000) e offset, com nextOffset na resposta — null no fim.

E a regra de custo que vale para as duas: LIMIT, OFFSET e paginação não reduzem bytes lidos no BigQuery. Para pagar menos, filtre e agregue.

Idempotência: a resposta curta é "a API é somente leitura"

Não existe endpoint de escrita no ingestia.io. Toda rota é GET — ou POST apenas para enviar um SELECT. Logo, as chamadas são idempotentes por natureza: repetir não altera estado. Não há cabeçalho Idempotency-Key, e não é esquecimento: sem escrita, ele não tem o que proteger. Um mecanismo de idempotência só faria sentido junto de uma futura API de escrita, que é Roadmap.

Como bônus, consultas idênticas (mesma versão do workspace) servem do cache com custo R$ 0, e a invalidação por pipeline garante que nunca se serve dado velho.

Webhooks: não existem hoje

Não há API pública de assinatura de webhooks — eventos do workspace enviados ao seu endpoint. Está no Roadmap. Para reagir a mudanças de dados hoje, há dois caminhos legítimos: consulta periódica do feed OData (a atualização incremental do Power BI é exatamente isso) ou as assinaturas e alertas do próprio produto, conforme o plano. Os endpoints de webhook que existem na plataforma são entradas internas de cobrança e marketing, não uma API para desenvolvedores.

Exemplo: a Aurora Varejo às 6h

O servidor de integração da Aurora dispara 40 atualizações de Power BI em paralelo às 6h. Na terceira, começam a chover 429 com Retry-After: 60. O time lê o cabeçalho e descobre o óbvio: 40 refreshes paralelos, cada um paginando várias páginas, passam fácil de 120 chamadas no minuto com a mesma chave. A correção tem duas partes: escalonar os refreshes ao longo de 15 minutos e filtrar por janela de data para que cada um faça menos páginas. Semanas depois aparece um 503 com Retry-After num horário aleatório — o limitador estava indisponível, e a API negou de propósito para não rodar consulta cobrável sem teto. A resposta certa foi esperar, não repetir em laço.

SuperfícieEstadoQuando usar
Contratos transversais (formato de erro, paginação, rate limit fail-closed)Previewvalem para toda rota /api/v1 — é o que esta aula ensina a ler
Rate limit de leitura 120/min por chavePreviewdimensione o seu cliente por ele; respeite o Retry-After
Cabeçalho Idempotency-Keynão existedesnecessário: a API é somente leitura
Assinatura de webhooks · API de escritaRoadmapnão construa — use consulta periódica do OData ou alertas do produto

Erros comuns

SintomaCausa provávelO que fazer
429 em rajadamuitas chamadas na mesma janela de 1 minrespeite o Retry-After; reduza paralelismo e escalone horários
Laço de repetição imediata depois de 429cliente ignorando o Retry-Afterespere o tempo indicado — repetir só prolonga o bloqueio
503 com Retry-After interpretado como buglimitador indisponível → negar é o desenhoaguarde e repita; confirme o provisionamento do datalake
402workspace inadimplente ou suspensoregularize o pagamento no app
400 na paginaçãopassou de 1.000.000 de linhas, ou $skiptoken adulteradofiltre os dados; siga o @odata.nextLink
Esperar Idempotency-Key ou webhookambos não existem (escrita e webhooks são Roadmap)a API é somente leitura; reaja por consulta periódica
Esperar SLA de disponibilidade da APIPreview é sem SLA; uptime e latência não são medidosnão prometa número a terceiro

Estado

Os contratos desta aula — formato de erro único, catálogo de códigos, paginação e rate limit fail-closed — são Preview e cobertos por teste automatizado. O que não existe: SLA, número de uptime, latência ou throughput como garantia; RPO/RTO como promessa; Idempotency-Key; API de escrita; assinatura de webhooks (Roadmap). O valor em x-ingestia-cost-brl é projeção. E lembre do estado das superfícies: OData = Preview, API REST de consulta = fora de GA (Aula 6).

Faça você mesmo#

Esta aula é de conhecimento: não há exercício operacional. Leia, assista e responda à checagem rápida.

Para fixar sem operar nada, faça o exercício de mesa: pegue os sete códigos da tabela de erros comuns e, para cada um, escreva numa linha de quem é o problema (seu, da credencial, do dinheiro ou da plataforma) e qual é a primeira ação. Depois dimensione no papel quantas chamadas por minuto a sua integração faria no pior horário, e compare com 120/min por chave. Em nenhum momento tente provocar 429 de propósito contra a rota /api/v1/query — ela está fora de GA e não deve receber tráfego seu (Aula 6).

Checagem rápida#

Três perguntas no final da aula, corrigidas no servidor. A aula só conta como concluída depois da checagem.

Documentação relacionada#

Capacidades ensinadas#

(conceitual — sem capacidade específica da matriz) — o selo exibido na aula é sempre o estado mais conservador entre as capacidades citadas; nada aqui é "GA".

Carregando seu progresso…