Códigos de erro da API pública

Gerado automaticamente a partir do catálogo de erros do servidor — sempre em sincronia com o que as rotas realmente emitem. Versões para máquina: errors.json e errors.md. Referência dos endpoints em /api-docs.

Envelope

Todo erro é um JSON com error (código estável), opcionalmente reason (subcódigo), message legível e campos auxiliares como retry_after, max_offset e details. Use error/reason na lógica de retry: message pode mudar sem aviso.

Limites de contenção

Deslocamento máximo de paginação: 1000 registros. Mais de 12 rejeições em 10 minutos acionam cooldown de 60s, dobrando até 900s.

EndpointReq/minLinhas/hora
/api/public/lots603000
/api/public/bids12010000
/api/public/index603000
/api/public/auctions/{auction_id}/metrics603000
/api/public/bids/leader1206000
/api/public/lots/{lot_id}/timer-resets6020000
/api/public/lots/{lot_id}/stream20600
/api/public/auctions/{auction_id}/stream20600
400

invalid_query

Parâmetros de consulta inválidos

Quando acontece: Algum filtro, cursor ou parâmetro de paginação não passou na validação Zod da rota.

O que fazer: Corrija os campos listados em `details.fieldErrors` e repita. Não faça retry automático: o erro é determinístico.

Endpoints: /api/public/lots, /api/public/bids, /api/public/index

HTTP/1.1 400 Bad Request
content-type: application/json; charset=utf-8
access-control-allow-origin: *
access-control-expose-headers: retry-after, x-ratelimit-limit, x-ratelimit-remaining, x-ratelimit-reset, x-ratelimit-scope, x-api-version, x-api-supported-versions, x-correlation-id
x-api-version: 1
x-api-supported-versions: 1
x-ratelimit-limit: 60
x-ratelimit-remaining: 0
x-ratelimit-reset: 1785312060
x-ratelimit-scope: distributed

{
  "error": "invalid_query",
  "details": {
    "formErrors": [],
    "fieldErrors": {
      "lot_id": [
        "Invalid uuid"
      ]
    }
  },
  "version": "1",
  "code": "invalid_query",
  "message": "Parâmetros de consulta inválidos"
}
HeaderDescrição
access-control-allow-originA API pública é aberta a qualquer origem, inclusive nas respostas de erro.
access-control-expose-headersLibera a leitura dos headers de cota por clientes cross-origin.
x-api-versionVersão do contrato usada para montar a resposta.
x-api-supported-versionsVersões que o servidor ainda aceita.
x-ratelimit-limitTeto da janela avaliada (requisições/minuto ou linhas/hora).
x-ratelimit-remainingSaldo restante; sempre 0 em respostas rejeitadas.
x-ratelimit-resetEpoch em segundos do reinício da janela.
x-ratelimit-scopeCamada que rejeitou: `distributed`/`local` (cota por minuto), `rows` (orçamento de linhas) ou `abuse` (cooldown).
  • `details` traz apenas nomes de campos e mensagens do Zod — nunca dados de usuários.
400

invalid_lot_id

Identificador de lote malformado

Quando acontece: O segmento `{lot_id}` da URL não é um UUID válido.

O que fazer: Use o `id` devolvido por `/api/public/lots`.

Endpoints: /api/public/lots/{lot_id}, /api/public/lots/{lot_id}/stream

HTTP/1.1 400 Bad Request
content-type: application/json; charset=utf-8
access-control-allow-origin: *
cache-control: no-store
x-api-version: 1
x-api-supported-versions: 1

{
  "error": "invalid_lot_id",
  "version": "1",
  "code": "invalid_lot_id",
  "message": "Identificador de lote malformado",
  "details": null
}
HeaderDescrição
access-control-allow-originA API pública é aberta a qualquer origem, inclusive nas respostas de erro.
cache-controlRespostas de erro nunca são cacheadas por navegadores ou CDNs.
x-api-versionVersão do contrato usada para montar a resposta.
x-api-supported-versionsVersões que o servidor ainda aceita.
400

invalid_auction_id

Identificador de leilão malformado

Quando acontece: O segmento `{auction_id}` da URL não é um UUID válido.

O que fazer: Use o `auction_id` devolvido por `/api/public/index` ou `/api/public/lots`.

Endpoints: /api/public/auctions/{auction_id}/metrics, /api/public/auctions/{auction_id}/stream

HTTP/1.1 400 Bad Request
content-type: application/json; charset=utf-8
access-control-allow-origin: *
cache-control: no-store
x-api-version: 1
x-api-supported-versions: 1

{
  "error": "invalid_auction_id",
  "version": "1",
  "code": "invalid_auction_id",
  "message": "Identificador de leilão malformado",
  "details": null
}
HeaderDescrição
access-control-allow-originA API pública é aberta a qualquer origem, inclusive nas respostas de erro.
cache-controlRespostas de erro nunca são cacheadas por navegadores ou CDNs.
x-api-versionVersão do contrato usada para montar a resposta.
x-api-supported-versionsVersões que o servidor ainda aceita.
400

invalid_since

Parâmetro `since` inválido

Quando acontece: O `?since=` do feed ou de `/api/public/lots` não é uma data ISO-8601 válida.

O que fazer: Envie um timestamp ISO-8601 (ex.: `2026-08-01T00:00:00Z`).

Endpoints: /api/public/lots, /api/public/bids, /api/public/feed.json, /api/public/feed.xml, /api/public/atom.xml

HTTP/1.1 400 Bad Request
content-type: application/json; charset=utf-8
access-control-allow-origin: *
cache-control: no-store

{
  "error": "invalid_since",
  "message": "Parâmetro `since` deve ser uma data ISO-8601.",
  "code": "invalid_since",
  "details": null
}
HeaderDescrição
access-control-allow-originA API pública é aberta a qualquer origem, inclusive nas respostas de erro.
cache-controlRespostas de erro nunca são cacheadas por navegadores ou CDNs.
400

invalid_validate_amount

Parâmetro `validate_amount` inválido

Quando acontece: `?validate_amount=` não é um número não negativo ou foi enviado sem `?lot_id=`.

O que fazer: Envie um número >= 0 junto de `lot_id` para validar contra o incremento mínimo do evento.

Endpoints: /api/public/bids

HTTP/1.1 400 Bad Request
content-type: application/json; charset=utf-8
access-control-allow-origin: *
cache-control: no-store

{
  "error": "invalid_validate_amount",
  "message": "Parâmetro `validate_amount` deve ser um número não negativo.",
  "code": "invalid_validate_amount",
  "details": null
}
HeaderDescrição
access-control-allow-originA API pública é aberta a qualquer origem, inclusive nas respostas de erro.
cache-controlRespostas de erro nunca são cacheadas por navegadores ou CDNs.
400

invalid_pagination

Paginação do feed fora dos limites

Quando acontece: `?page=`, `?per_page=` ou o alias `?limit=` do feed estão fora do intervalo aceito.

O que fazer: Respeite `max_per_page` devolvido no corpo e recomece pela primeira página.

Endpoints: /api/public/feed.json, /api/public/feed.xml, /api/public/atom.xml

HTTP/1.1 400 Bad Request
content-type: application/json; charset=utf-8
access-control-allow-origin: *
cache-control: no-store

{
  "error": "invalid_pagination",
  "message": "per_page deve estar entre 1 e 100.",
  "max_per_page": 100,
  "code": "invalid_pagination",
  "details": null
}
HeaderDescrição
access-control-allow-originA API pública é aberta a qualquer origem, inclusive nas respostas de erro.
cache-controlRespostas de erro nunca são cacheadas por navegadores ou CDNs.
400

invalid_include_deleted

Parâmetro `include_deleted` inválido

Quando acontece: `?include_deleted=` (ou `?include_only_deleted=`) veio com um valor fora do domínio booleano aceito.

O que fazer: Envie `1/0`, `true/false` ou `yes/no`. O erro é determinístico: não repita com o mesmo valor.

Endpoints: /api/public/bids, /api/public/bids/stream

HTTP/1.1 400 Bad Request
content-type: application/json; charset=utf-8
access-control-allow-origin: *
cache-control: no-store

{
  "error": "invalid_include_deleted",
  "message": "Parâmetro `include_deleted` aceita 1/0, true/false ou yes/no.",
  "code": "invalid_include_deleted",
  "details": null
}
HeaderDescrição
access-control-allow-originA API pública é aberta a qualquer origem, inclusive nas respostas de erro.
cache-controlRespostas de erro nunca são cacheadas por navegadores ou CDNs.
  • Em `/api/public/bids` a rejeição conta como violação na janela anti-abuso; no stream ela acontece antes do upgrade para `text/event-stream`.
400

invalid_deleted_limit

Parâmetro `deleted_limit` inválido

Quando acontece: `?deleted_limit=` não é um inteiro >= 1 (valor `0`, negativo, decimal ou não numérico).

O que fazer: Envie um inteiro entre 1 e o `per_page` máximo do endpoint. Valores acima do teto são reduzidos, não rejeitados.

Endpoints: /api/public/bids

HTTP/1.1 400 Bad Request
content-type: application/json; charset=utf-8
access-control-allow-origin: *
cache-control: no-store

{
  "error": "invalid_deleted_limit",
  "message": "Parâmetro `deleted_limit` deve ser um inteiro >= 1 (máximo 200).",
  "code": "invalid_deleted_limit",
  "details": null
}
HeaderDescrição
access-control-allow-originA API pública é aberta a qualquer origem, inclusive nas respostas de erro.
cache-controlRespostas de erro nunca são cacheadas por navegadores ou CDNs.
  • Só faz sentido junto de `include_deleted=1`; limita o tamanho do bloco `deleted[]`.
400

invalid_include_only_deleted

Parâmetro `include_only_deleted` inválido

Quando acontece: Valor fora do domínio booleano, uso sem `since` (modo incremental) ou combinado com `include_deleted=0`.

O que fazer: Envie `include_only_deleted=1` junto de `since` e sem desligar `include_deleted`. O corpo diz qual das três condições falhou.

Endpoints: /api/public/bids

HTTP/1.1 400 Bad Request
content-type: application/json; charset=utf-8
access-control-allow-origin: *
cache-control: no-store

{
  "error": "invalid_include_only_deleted",
  "message": "Parâmetro `include_only_deleted` exige `since` (modo incremental).",
  "code": "invalid_include_only_deleted",
  "details": null
}
HeaderDescrição
access-control-allow-originA API pública é aberta a qualquer origem, inclusive nas respostas de erro.
cache-controlRespostas de erro nunca são cacheadas por navegadores ou CDNs.
400

invalid_json

Corpo da requisição não é JSON válido

Quando acontece: O `POST` chegou com um corpo que não pôde ser desserializado como JSON.

O que fazer: Envie JSON válido com `content-type: application/json`.

Endpoints: /api/public/countdown-desync

HTTP/1.1 400 Bad Request
content-type: application/json; charset=utf-8
access-control-allow-origin: *
cache-control: no-store

{
  "error": "invalid_json",
  "code": "invalid_json",
  "message": "Corpo da requisição não é JSON válido",
  "details": null
}
HeaderDescrição
access-control-allow-originA API pública é aberta a qualquer origem, inclusive nas respostas de erro.
cache-controlRespostas de erro nunca são cacheadas por navegadores ou CDNs.
400

invalid_report

Relatório de desync malformado

Quando acontece: O corpo é JSON válido, mas não passou no schema do relatório de desync do countdown.

O que fazer: Corrija os campos listados em `issues` (caminhos do schema) e reenvie.

Endpoints: /api/public/countdown-desync

HTTP/1.1 400 Bad Request
content-type: application/json; charset=utf-8
access-control-allow-origin: *
cache-control: no-store

{
  "error": "invalid_report",
  "issues": [
    "lot_id",
    "client_ends_at"
  ],
  "code": "invalid_report",
  "message": "Relatório de desync malformado",
  "details": null
}
HeaderDescrição
access-control-allow-originA API pública é aberta a qualquer origem, inclusive nas respostas de erro.
cache-controlRespostas de erro nunca são cacheadas por navegadores ou CDNs.
400

invalid_range

Janela temporal impossível

Quando acontece: `?since=` é igual ou posterior a `?until=`: a janela nunca devolveria lance algum.

O que fazer: Corrija a janela para `since < until`. Uma lista vazia com esses parâmetros não significa fim do histórico.

Endpoints: /api/public/bids

HTTP/1.1 400 Bad Request
content-type: application/json; charset=utf-8
access-control-allow-origin: *
cache-control: no-store

{
  "error": "invalid_range",
  "message": "Parâmetro `since` deve ser anterior a `until`.",
  "code": "invalid_range",
  "details": null
}
HeaderDescrição
access-control-allow-originA API pública é aberta a qualquer origem, inclusive nas respostas de erro.
cache-controlRespostas de erro nunca são cacheadas por navegadores ou CDNs.
400

invalid_cursor

Cursor do feed inválido

Quando acontece: O `?cursor=` do feed não é um token devolvido pelo servidor (base64url com `updated`+`id`).

O que fazer: Reenvie exatamente o valor do header `X-Feed-Cursor` (ou `_arsenale.next_cursor` no JSON Feed). Omita `cursor` para recomeçar do início do delta.

Endpoints: /api/public/feed.json, /api/public/feed.xml, /api/public/atom.xml

HTTP/1.1 400 Bad Request
content-type: application/json; charset=utf-8
access-control-allow-origin: *
cache-control: no-store

{
  "error": "invalid_cursor",
  "message": "Parâmetro cursor inválido. Reenvie exatamente o valor recebido no header X-Feed-Cursor (ou omita para começar do início).",
  "code": "invalid_cursor",
  "details": null
}
HeaderDescrição
access-control-allow-originA API pública é aberta a qualquer origem, inclusive nas respostas de erro.
cache-controlRespostas de erro nunca são cacheadas por navegadores ou CDNs.
400

page_out_of_range

Paginação profunda bloqueada

Quando acontece: O deslocamento `(page - 1) * per_page` passou de 1000 registros — padrão típico de enumeração/varredura do catálogo.

O que fazer: Não pagine indefinidamente: use filtros (`auction_id`, `status`, `q`, `since`/`until`) ou o campo `next_cursor` para estreitar o resultado. Insistir soma violações e leva ao cooldown 429 `abuse_cooldown`.

Endpoints: /api/public/lots, /api/public/bids, /api/public/index

HTTP/1.1 400 Bad Request
content-type: application/json; charset=utf-8
access-control-allow-origin: *
access-control-expose-headers: retry-after, x-ratelimit-limit, x-ratelimit-remaining, x-ratelimit-reset, x-ratelimit-scope, x-api-version, x-api-supported-versions, x-correlation-id
cache-control: no-store
x-ratelimit-limit: 60
x-ratelimit-remaining: 0
x-ratelimit-reset: 1785312060
x-ratelimit-scope: distributed

{
  "error": "page_out_of_range",
  "message": "Paginação limitada a um deslocamento de 1000 registros. Use filtros (auction_id, status, q, since/until) para refinar a consulta.",
  "max_offset": 1000,
  "code": "page_out_of_range",
  "details": null
}
HeaderDescrição
access-control-allow-originA API pública é aberta a qualquer origem, inclusive nas respostas de erro.
access-control-expose-headersLibera a leitura dos headers de cota por clientes cross-origin.
cache-controlRespostas de erro nunca são cacheadas por navegadores ou CDNs.
x-ratelimit-limitTeto da janela avaliada (requisições/minuto ou linhas/hora).
x-ratelimit-remainingSaldo restante; sempre 0 em respostas rejeitadas.
x-ratelimit-resetEpoch em segundos do reinício da janela.
x-ratelimit-scopeCamada que rejeitou: `distributed`/`local` (cota por minuto), `rows` (orçamento de linhas) ou `abuse` (cooldown).
  • É 400 (e não 429) porque a requisição é inválida por si só — repetir com a mesma página nunca vai funcionar.
  • Cada ocorrência conta como violação na janela anti-abuso.
400

unsupported_version

Versão de contrato não suportada

Quando acontece: O header `x-api-version` (ou `?api_version=`) pediu uma versão que o servidor não serve mais.

O que fazer: Envie uma das versões listadas em `x-api-supported-versions` ou omita o parâmetro para receber a versão corrente.

Endpoints: *

HTTP/1.1 400 Bad Request
content-type: application/json; charset=utf-8
access-control-allow-origin: *
cache-control: no-store
x-api-version: 1
x-api-supported-versions: 1

{
  "error": "unsupported_version",
  "message": "Versão 0 não suportada. Versões disponíveis: 1.",
  "supported_versions": [
    "1"
  ],
  "code": "unsupported_version",
  "details": null
}
HeaderDescrição
access-control-allow-originA API pública é aberta a qualquer origem, inclusive nas respostas de erro.
cache-controlRespostas de erro nunca são cacheadas por navegadores ou CDNs.
x-api-versionVersão do contrato usada para montar a resposta.
x-api-supported-versionsVersões que o servidor ainda aceita.
404

lot_not_found

Lote inexistente ou não publicado

Quando acontece: O UUID é válido, mas o lote não existe na view pública (leilão em rascunho ou lote removido).

O que fazer: Trate como 404 definitivo; não faça retry.

Endpoints: /api/public/lots/{lot_id}, /api/public/lots/{lot_id}/stream

HTTP/1.1 404 Not Found
content-type: application/json; charset=utf-8
access-control-allow-origin: *
cache-control: no-store
x-api-version: 1
x-api-supported-versions: 1

{
  "error": "lot_not_found",
  "version": "1",
  "code": "lot_not_found",
  "message": "Lote inexistente ou não publicado",
  "details": null
}
HeaderDescrição
access-control-allow-originA API pública é aberta a qualquer origem, inclusive nas respostas de erro.
cache-controlRespostas de erro nunca são cacheadas por navegadores ou CDNs.
x-api-versionVersão do contrato usada para montar a resposta.
x-api-supported-versionsVersões que o servidor ainda aceita.
  • Lotes de leilões não publicados retornam 404, nunca 403, para não revelar existência.
404

auction_not_found

Leilão inexistente ou não publicado

Quando acontece: O UUID é válido, mas o leilão não está visível publicamente.

O que fazer: Trate como 404 definitivo; não faça retry.

Endpoints: /api/public/auctions/{auction_id}/metrics, /api/public/auctions/{auction_id}/stream

HTTP/1.1 404 Not Found
content-type: application/json; charset=utf-8
access-control-allow-origin: *
cache-control: no-store
x-api-version: 1
x-api-supported-versions: 1

{
  "error": "auction_not_found",
  "version": "1",
  "code": "auction_not_found",
  "message": "Leilão inexistente ou não publicado",
  "details": null
}
HeaderDescrição
access-control-allow-originA API pública é aberta a qualquer origem, inclusive nas respostas de erro.
cache-controlRespostas de erro nunca são cacheadas por navegadores ou CDNs.
x-api-versionVersão do contrato usada para montar a resposta.
x-api-supported-versionsVersões que o servidor ainda aceita.
404

lot_not_in_auction

Lote não pertence ao leilão pedido

Quando acontece: O stream recebeu `?auction_id=` e `?lot_id=` juntos, mas o lote não está entre os lotes públicos daquele leilão.

O que fazer: Confira o par leilão/lote em `/api/public/lots?auction_id=...` ou envie apenas um dos dois filtros. Não faça retry.

Endpoints: /api/public/bids/stream

HTTP/1.1 404 Not Found
content-type: application/json; charset=utf-8
access-control-allow-origin: *
cache-control: no-store

{
  "error": "lot_not_in_auction",
  "code": "lot_not_in_auction",
  "message": "Lote não pertence ao leilão pedido",
  "details": null
}
HeaderDescrição
access-control-allow-originA API pública é aberta a qualquer origem, inclusive nas respostas de erro.
cache-controlRespostas de erro nunca são cacheadas por navegadores ou CDNs.
  • A checagem acontece antes de abrir o `text/event-stream`: o cliente recebe JSON, não eventos SSE.
502

query_failed

Consulta às views públicas falhou

Quando acontece: O banco recusou ou abortou a consulta que monta a exportação (timeout, indisponibilidade momentânea ou filtro impossível de planejar).

O que fazer: Repita com backoff exponencial e, se persistir, estreite a janela (`since`/`until`) ou reduza o intervalo de valores exportado.

Endpoints: /api/public/bids/csv, /api/public/archive-realized/lots

HTTP/1.1 502 Bad Gateway
content-type: application/json; charset=utf-8
access-control-allow-origin: *
cache-control: no-store

{
  "error": "query_failed",
  "message": "canceling statement due to statement timeout",
  "code": "query_failed",
  "details": null
}
HeaderDescrição
access-control-allow-originA API pública é aberta a qualquer origem, inclusive nas respostas de erro.
cache-controlRespostas de erro nunca são cacheadas por navegadores ou CDNs.
  • É 502 (e não 500) porque a falha vem da dependência de dados, não do handler.
  • `message` repassa o erro do banco para diagnóstico; nunca contém dados de usuários.
429

rate_limited

Cota de requisições por minuto atingida

Quando acontece: O IP passou do teto de requisições/minuto do endpoint. Páginas grandes (`per_page > 50`) e clientes automatizados (User-Agent ausente ou de scraper) consomem 2 a 3 unidades por chamada.

O que fazer: Espere `retry_after` segundos (ou até `x-ratelimit-reset`) e repita com backoff. Não faça retry imediato: cada rejeição soma violação.

Endpoints: *

HTTP/1.1 429 Too Many Requests
content-type: application/json; charset=utf-8
access-control-allow-origin: *
access-control-expose-headers: retry-after, x-ratelimit-limit, x-ratelimit-remaining, x-ratelimit-reset, x-ratelimit-scope, x-api-version, x-api-supported-versions, x-correlation-id
cache-control: no-store
retry-after: 24
x-api-version: 1
x-api-supported-versions: 1
x-ratelimit-limit: 60
x-ratelimit-remaining: 0
x-ratelimit-reset: 1785312060
x-ratelimit-scope: distributed

{
  "error": "rate_limited",
  "message": "Limite de 60 requisições por minuto atingido. Tente novamente em 24s.",
  "retry_after": 24,
  "code": "rate_limited",
  "details": null
}
HeaderDescrição
access-control-allow-originA API pública é aberta a qualquer origem, inclusive nas respostas de erro.
access-control-expose-headersLibera a leitura dos headers de cota por clientes cross-origin.
cache-controlRespostas de erro nunca são cacheadas por navegadores ou CDNs.
retry-afterSegundos a esperar antes de repetir a chamada. Igual a `retry_after` no corpo.
x-api-versionVersão do contrato usada para montar a resposta.
x-api-supported-versionsVersões que o servidor ainda aceita.
x-ratelimit-limitTeto da janela avaliada (requisições/minuto ou linhas/hora).
x-ratelimit-remainingSaldo restante; sempre 0 em respostas rejeitadas.
x-ratelimit-resetEpoch em segundos do reinício da janela.
x-ratelimit-scopeCamada que rejeitou: `distributed`/`local` (cota por minuto), `rows` (orçamento de linhas) ou `abuse` (cooldown).
  • `x-ratelimit-scope` vem como `distributed` (contador no banco) ou `local` (fallback em memória do worker).
429

rate_limited:row_budget_exhausted

Orçamento de linhas por hora esgotado

Quando acontece: A soma de `per_page` das chamadas do IP na última hora ultrapassou o orçamento de linhas do endpoint, mesmo respeitando a cota por minuto.

O que fazer: Reduza `per_page`, use `since`/`next_cursor` para buscar só o que mudou, ou consuma o SSE em vez de fazer polling do catálogo inteiro. Volte após `retry_after` segundos.

Endpoints: /api/public/lots, /api/public/bids, /api/public/index

HTTP/1.1 429 Too Many Requests
content-type: application/json; charset=utf-8
access-control-allow-origin: *
access-control-expose-headers: retry-after, x-ratelimit-limit, x-ratelimit-remaining, x-ratelimit-reset, x-ratelimit-scope, x-api-version, x-api-supported-versions, x-correlation-id
cache-control: no-store
retry-after: 1800
x-api-version: 1
x-api-supported-versions: 1
x-ratelimit-limit: 10000
x-ratelimit-remaining: 0
x-ratelimit-reset: 1785312060
x-ratelimit-scope: rows

{
  "error": "rate_limited",
  "reason": "row_budget_exhausted",
  "message": "Orçamento de 10000 registros por hora atingido para este endpoint. Tente novamente em 1800s.",
  "retry_after": 1800,
  "code": "rate_limited",
  "details": null
}
HeaderDescrição
access-control-allow-originA API pública é aberta a qualquer origem, inclusive nas respostas de erro.
access-control-expose-headersLibera a leitura dos headers de cota por clientes cross-origin.
cache-controlRespostas de erro nunca são cacheadas por navegadores ou CDNs.
retry-afterSegundos a esperar antes de repetir a chamada. Igual a `retry_after` no corpo.
x-api-versionVersão do contrato usada para montar a resposta.
x-api-supported-versionsVersões que o servidor ainda aceita.
x-ratelimit-limitTeto da janela avaliada (requisições/minuto ou linhas/hora).
x-ratelimit-remainingSaldo restante; sempre 0 em respostas rejeitadas.
x-ratelimit-resetEpoch em segundos do reinício da janela.
x-ratelimit-scopeCamada que rejeitou: `distributed`/`local` (cota por minuto), `rows` (orçamento de linhas) ou `abuse` (cooldown).
  • A janela é de 1 hora deslizante, então `retry_after` pode chegar a milhares de segundos.
  • O orçamento é contado em linhas pedidas (`per_page`), não em linhas devolvidas.
  • O teto varia por endpoint: 10.000 linhas/hora em `/api/public/bids` (exemplo acima) e 3.000 em `/api/public/lots` e `/api/public/index`.
429

rate_limited:abuse_cooldown

Caixa de castigo (cooldown progressivo)

Quando acontece: O IP acumulou mais de 12 rejeições (cota, orçamento de linhas ou paginação profunda) em 10 minutos. Todas as chamadas seguintes são recusadas até o cooldown expirar.

O que fazer: Pare completamente as chamadas por `retry_after` segundos. Continuar tentando dobra o cooldown a cada nova violação.

Endpoints: *

HTTP/1.1 429 Too Many Requests
content-type: application/json; charset=utf-8
access-control-allow-origin: *
access-control-expose-headers: retry-after, x-ratelimit-limit, x-ratelimit-remaining, x-ratelimit-reset, x-ratelimit-scope, x-api-version, x-api-supported-versions, x-correlation-id
cache-control: no-store
retry-after: 120
x-api-version: 1
x-api-supported-versions: 1
x-ratelimit-limit: 60
x-ratelimit-remaining: 0
x-ratelimit-reset: 1785312060
x-ratelimit-scope: abuse

{
  "error": "rate_limited",
  "reason": "abuse_cooldown",
  "message": "Muitas requisições rejeitadas em lots. Aguarde 120s antes de tentar novamente.",
  "retry_after": 120,
  "code": "rate_limited",
  "details": null
}
HeaderDescrição
access-control-allow-originA API pública é aberta a qualquer origem, inclusive nas respostas de erro.
access-control-expose-headersLibera a leitura dos headers de cota por clientes cross-origin.
cache-controlRespostas de erro nunca são cacheadas por navegadores ou CDNs.
retry-afterSegundos a esperar antes de repetir a chamada. Igual a `retry_after` no corpo.
x-api-versionVersão do contrato usada para montar a resposta.
x-api-supported-versionsVersões que o servidor ainda aceita.
x-ratelimit-limitTeto da janela avaliada (requisições/minuto ou linhas/hora).
x-ratelimit-remainingSaldo restante; sempre 0 em respostas rejeitadas.
x-ratelimit-resetEpoch em segundos do reinício da janela.
x-ratelimit-scopeCamada que rejeitou: `distributed`/`local` (cota por minuto), `rows` (orçamento de linhas) ou `abuse` (cooldown).
  • Duração: 60s na primeira vez, dobrando a cada violação, com teto de 900s.
  • Vale para o IP inteiro, incluindo os streams SSE — a rejeição acontece antes do upgrade para `text/event-stream`.
500

internal_error

Falha ao consultar as views públicas

Quando acontece: Erro inesperado no banco ou no loader por trás do endpoint.

O que fazer: Repita com backoff exponencial; o erro costuma ser transitório.

Endpoints: *

HTTP/1.1 500 Internal Server Error
content-type: application/json; charset=utf-8
access-control-allow-origin: *
cache-control: no-store
x-api-version: 1
x-api-supported-versions: 1
x-ratelimit-limit: 60
x-ratelimit-remaining: 0
x-ratelimit-reset: 1785312060
x-ratelimit-scope: distributed

{
  "error": "internal_error",
  "message": "Falha ao consultar lots_public.",
  "code": "internal_error",
  "details": null
}
HeaderDescrição
access-control-allow-originA API pública é aberta a qualquer origem, inclusive nas respostas de erro.
cache-controlRespostas de erro nunca são cacheadas por navegadores ou CDNs.
x-api-versionVersão do contrato usada para montar a resposta.
x-api-supported-versionsVersões que o servidor ainda aceita.
x-ratelimit-limitTeto da janela avaliada (requisições/minuto ou linhas/hora).
x-ratelimit-remainingSaldo restante; sempre 0 em respostas rejeitadas.
x-ratelimit-resetEpoch em segundos do reinício da janela.
x-ratelimit-scopeCamada que rejeitou: `distributed`/`local` (cota por minuto), `rows` (orçamento de linhas) ou `abuse` (cooldown).
  • A mensagem é genérica de propósito: nenhum detalhe interno de SQL ou de usuário é exposto.
  • Correlacione pelo header `x-correlation-id` ao abrir um chamado.