Pular para o conteúdo

Erros e limites de requisição

Erros da aplicação retornam um objeto JSON compacto:

{ "error": { "code": "forbidden", "message": "scope `posts:write` not granted" } }
Status error.code Significado O que fazer
400 bad_request JSON malformado, ou title vazio. Corrija o payload.
401 unauthorized Authorization ausente ou não-Bearer, ou chave desconhecida/revogada. Envie uma chave ck_… válida.
403 forbidden A chave não tem o escopo exigido. Use uma chave com o escopo; o message diz qual é.
413 — Corpo da requisição acima de 4 MiB. Divida o conteúdo ou reduza-o.
415 — Content-Type ausente ou incorreto. Envie Content-Type: application/json.
422 unprocessable / — O corpo falhou na validação: blocks_json ausente, tipo de campo errado, ou uma chave criada antes de a publicação ser habilitada. Corrija o campo; se a mensagem pedir para recriar a chave, recrie.
429 rate_limited Acima do limite de requisição da chave para aquela rota. Espere antes de tentar de novo; respeite o Retry-After.
404 not_found O recurso não existe neste site. O recurso de outro tenant é indistinguível de um inexistente, de propósito. Confira o id; não tente de novo.
5xx upstream Erro transitório de upstream/servidor. Tente de novo com backoff.

Significados específicos de cada rota (204 na exclusão de mídia, 202 no envio de mídia, 304 numa leitura condicional, 422 num filtro de leads inválido) estão documentados em cada página de referência.

401:

{ "error": { "code": "unauthorized", "message": "missing Authorization header" } }

403:

{ "error": { "code": "forbidden", "message": "scope `posts:write` not granted" } }

422 (chave legada sem contexto de publicação):

{ "error": { "code": "unprocessable",
"message": "this api key was created before publishing was enabled; please re-create it in Configurações → Integrações API" } }

Não existe um limite só, mas quatro buckets, dimensionados pelo custo de cada rota. Uma chave paga todos os buckets que se aplicam à rota que está chamando, e o mais apertado morde primeiro.

Bucket Limite Aplica-se a
Escrita / geral 60 req/min por chave Todas as rotas, exceto as duas rotas públicas de leitura
Leitura pública 600 req/min por chave GET /v1/posts, GET /v1/posts/{reference}
Leitura pública por (chave, IP) 60 req/min As mesmas duas rotas, só chaves pk_
Leads 10 req/min por chave GET /v1/leads, GET /v1/leads/{id} e GET /v1/export?resource=leads, em camada além do bucket geral

Ler é dez vezes mais barato que escrever, de propósito: um bucket compartilhado deixaria uma grade incorporada movimentada consumir a cota de publicação do dono do site. O bucket de leads é mais apertado que todos porque leads são dados pessoais: o bastante para paginar uma caixa de entrada e puxar uma exportação periódica, não o bastante para raspar uma base de contatos.

Quando você excede um bucket, recebe 429 com um cabeçalho Retry-After (em segundos):

HTTP/1.1 429 Too Many Requests
Retry-After: 7
{ "error": { "code": "rate_limited", "message": "too many requests" } }

Orientação para o cliente:

  • Respeite o Retry-After: espere essa quantidade de segundos antes de tentar de novo.
  • Para trabalho em lote, prefira o POST /v1/import a um loop de POST /v1/posts: uma requisição em vez de centenas, e ele é idempotente por linha. Se você fizer loop, limite o ritmo a ≤ 1 requisição/segundo.
  • Nas leituras, devolva o ETag como If-None-Match. Um 304 é a consulta mais barata possível.
  • Uma requisição bloqueada por uma restrição da chave (IP, região, janela de horário) é recusada antes de o bucket ser cobrado, então um 403 não custa cota.
  • Precisa de um limite maior? Peça: os limites são por chave e podem ser aumentados.

429 e 5xx podem ser repetidos com segurança. Envie um cabeçalho Idempotency-Key no POST /v1/posts para que uma nova tentativa devolva a resposta original em vez de criar um post duplicado. Veja Idempotência. Uma requisição que deu erro não guarda nada em cache, então tentar de novo depois de um erro a executa novamente, como deve ser.