Todos os posts
Referência da APIAPI da PolymarketDepuraçãoCLOB

Erros da API da Polymarket: todos os códigos, decifrados

As mensagens de erro da Polymarket são lacônicas, e as que quebram seu bot às 3 da manhã costumam ser justamente as que nem aparecem na documentação. Aqui está a referência completa — erros documentados, não documentados e o que fazer de fato com cada um.

12 min de leitura

Todo erro da API CLOB da Polymarket volta no mesmo formato — um objeto JSON com um único campo error —, o que é admiravelmente consistente e completamente inútil quando você está tentando entender por que sua ordem acabou de sumir.

{
  "error": "<message>"
}

Esta página os decifra. Ela cobre os erros documentados do CLOB, os códigos de status e suas causas reais e — a parte que você não vai encontrar na documentação oficial — os erros que as pessoas realmente encontram em produção e que a Polymarket nunca documentou.

Cada mensagem documentada também tem sua própria página, com causas e um veredito sobre nova tentativa, listadas no índice de erros da Polymarket.

Referência rápida de códigos de status

StatusSignificadoCausas comuns
400Bad RequestParâmetros inválidos, payload malformado, violação de regra de negócio
401UnauthorizedChave de API ausente ou inválida, assinatura HMAC incorreta, timestamp expirado
404Not FoundO mercado não existe, ordem não encontrada, ID de token não reconhecido
425Too EarlyO motor de casamento está reiniciando — tente de novo com backoff
429Too Many RequestsLimite de requisições excedido — faça backoff exponencial
500Internal Server ErrorErro inesperado no servidor — tente de novo com backoff
503Service UnavailableExchange pausada, ou bloqueada pelo modo somente cancelamento / somente post-only

A substituição de código de status que vai enganar você

A API CLOB reescreve os códigos de status com base no conteúdo da mensagem. Qualquer mensagem de erro que contenha "not found" retorna 404, qualquer uma que contenha "unauthorized" retorna 401 e qualquer uma que contenha "context canceled" retorna 400 — independentemente do código de status original. Se um código de status parece contradizer a mensagem, é por isso. Baseie o tratamento de erros no texto da mensagem, não no número.

401 — erros de autenticação

Unauthorized/Invalid api key

O erro da Polymarket mais pesquisado. Sua chave de API está ausente, expirada ou inválida. Na prática, quase nunca é uma chave realmente ruim — é uma destas coisas:

  1. Você está enviando só parte do conjunto de credenciais. A autenticação L2 da Polymarket precisa da chave, do secret e da passphrase juntos. Uma falha comum é preencher POLY_API_KEY e POLY_PASSPHRASE mas deixar o secret vazio — o cliente envia uma requisição bem formada, mas impossível de assinar.
  2. O relógio do seu sistema está desviado. A assinatura inclui um timestamp, e um relógio com mais de alguns segundos de diferença produz uma assinatura que o servidor rejeita como inválida. É a causa que as pessoas encontram por último, e é deprimentemente comum em VMs e contêineres.
  3. Você derivou a chave para uma carteira diferente daquela com que está operando. As chaves ficam vinculadas ao endereço do signer que as criou.
  4. Você está chamando um endpoint autenticado com headers L1 onde se espera L2, ou vice-versa.

Invalid L1 Request headers

Seus headers de autenticação L1 — o conjunto da assinatura EIP-712 — estão malformados, ou a assinatura não corresponde ao endereço que você diz ser. Verifique se está assinando com a mesma chave privada do endereço no header e se o seu domain separator corresponde à chain em que você está (Polygon, chain ID 137). Uma assinatura válida para o chain ID errado continua sendo uma assinatura válida — só que não para este servidor.

Could not create api key / Could not derive api key!

Estes são os erros por trás da busca “polymarket unable to generate api credentials”. Os dois são retornados pelos endpoints de autenticação quando a criação ou a derivação da chave falha. Could not derive api key! em GET /auth/derive-api-key geralmente significa que ainda não existe chave para aquele signer — derive retorna uma chave existente, não cria uma. Crie a chave primeiro com POST /auth/api-key e derive-a nas execuções seguintes.

O padrão derivar-depois-criar

Em vez de guardar as chaves, a maioria dos bots em produção tenta derive primeiro e recorre a create se falhar. Isso é idempotente entre reinicializações e evita acumular chaves órfãs — os endpoints de autenticação são limitados a 100 req / 10s, então você não quer criar uma chave a cada inicialização de qualquer forma.

400 — erros de rejeição de ordem

Eles são retornados quando uma ordem passa na validação de transporte, mas falha nas regras de negócio. Aparecem no corpo da resposta de POST /order e POST /orders.

Mensagem de erroO que significa
the order signer address has to be the address of the API KEYA chave que assina a ordem não é a chave que a ordem diz que a assinou. Você está misturando credenciais — geralmente uma chave antiga de uma carteira anterior.
the order owner has to be the owner of the API KEYO endereço maker na ordem não corresponde ao endereço a que a chave de API pertence.
order {id} is invalid. Price ({price}) breaks minimum tick size rule: {tick}Seu preço não está na grade de ticks do mercado. Chame GET /tick-size e arredonde para ela — não suponha 0.01.
order {id} is invalid. Size ({size}) lower than the minimum: {min}Tamanho da ordem abaixo do mínimo do mercado.
not enough balance / allowanceSaldo de pUSD insuficiente, ou você nunca concedeu allowance ao contrato da exchange. As duas coisas são necessárias.
invalid post-only order: order crosses bookSua ordem post-only tomaria liquidez imediatamente. Mude o preço para que ela fique no livro.
order couldn't be fully filled. FOK orders are fully filled or killed.A Fill-or-Kill encontrou liquidez insuficiente. A ordem inteira é rejeitada.
no orders found to match with FAK order.A Fill-and-Kill não encontrou nenhum casamento. É preciso pelo menos um.
invalid expirationO timestamp de expiração está no passado ou malformado.
order {id} is invalid. Duplicated.A mesma ordem foi enviada duas vezes.
order canceled in the CTF exchange contractA ordem foi cancelada on-chain.
'{address}' address bannedO endereço está banido de operar.
'{address}' address in closed only modeO endereço só pode fechar posições existentes.

O tick size é por mercado e muda

A rejeição silenciosa de ordem mais comum é a violação do tick size. O tick size varia entre mercados e pode ficar menor à medida que o mercado amadurece — um preço válido na semana passada pode não ser válido hoje. Busque GET /tick-size para cada mercado e arredonde para ele em vez de fixar uma grade no código.

Ordens em lote falham de outro jeito

Em POST /orders, as falhas de cada ordem voltam dentro do array da resposta 200, com campos errorMsg individuais — e não como um erro de nível superior. Um 200 não significa que todas as ordens do seu lote foram aceitas. Percorra o array e verifique cada entrada.

425 — Too Early

Um código de status incomum, que confunde as pessoas por ser tão pouco usado no resto da web. Na Polymarket, ele significa que o motor de casamento está reiniciando. Sua requisição chegou durante a janela em que a exchange está voltando.

Este é genuinamente transitório e genuinamente seguro para tentar de novo — é, possivelmente, o erro mais apropriado para nova tentativa da plataforma. Faça backoff e tente de novo; não o trate como falha e não gere alerta para uma ocorrência isolada.

503 — a exchange está em um modo restrito

A Polymarket pode colocar a exchange em modos restritos. Isso não são falhas do seu lado, e nenhuma quantidade de novas tentativas da mesma requisição vai ajudar até o modo ser suspenso.

MensagemO que você ainda pode fazer
Trading is currently disabled. Check polymarket.com for updatesNada. Nenhuma ordem é aceita, nem cancelamentos.
Trading is currently cancel-only. New orders are not accepted, but cancels are allowed.Cancelar ordens existentes. Você não pode abrir novas.
post-only mode: only post-only orders and cancels are allowedCancelar, ou enviar ordens com postOnly: true. Ordens que tomam liquidez são rejeitadas.

O modo post-only é o que vale tratar direito, porque ele diz exatamente quando voltar. A resposta inclui code: "post_only_mode" e retry_after_seconds, e o mesmo atraso é enviado no header Retry-After.

{
  "error": "post-only mode: only post-only orders and cancels are allowed",
  "code": "post_only_mode",
  "retry_after_seconds": 79
}

O modo somente cancelamento pode prender um bot de market making

Se o caminho de desligamento do seu bot recota antes de cancelar, o modo somente cancelamento vai rejeitar a nova cotação e seu bot pode entrar em loop em vez de zerar a posição. Trate o 503 cancelando primeiro e só depois decidindo se volta a entrar.

Erros que não estão na documentação

É aqui que vai a maior parte do tempo real de depuração. Os erros a seguir não aparecem na referência de códigos de erro da Polymarket porque nem vêm da aplicação CLOB — eles vêm da edge, da rede ou da sua biblioteca cliente. Saber qual camada produziu um erro diz onde procurar.

“The server was unable to process your request”

O erro da Polymarket mais pesquisado que não está na documentação. É uma mensagem da camada de edge, e não um erro da API CLOB — é o que você recebe quando a requisição nunca chegou à aplicação, ou nunca voltou dela de forma limpa. Na prática, as causas habituais são:

  • Uma requisição malformada que a edge rejeita antes do roteamento — um payload grande demais, um header inválido ou um método HTTP inválido para a rota.
  • Uma falha transitória upstream enquanto o serviço está sendo reimplantado ou sob carga.
  • Limitação de requisições prolongada. Como a Cloudflare limita colocando em fila em vez de rejeitar, um cliente muito acima do limite pode acabar com requisições que expiram na edge em vez de retornar um 429 limpo.

Trate como passível de nova tentativa com backoff, mas se for persistente em vez de ocasional, verifique primeiro sua taxa de requisições — veja a referência de limites de requisições — e depois o tamanho do seu payload.

403 Forbidden

Um 403 da Polymarket geralmente não é um problema de autenticação, e é isso que o torna confuso. Em geral é a edge bloqueando a requisição. Os gatilhos comuns são restrições geográficas nos endpoints de trading, faixas de IP de datacenters e VPNs sendo desafiadas e headers ausentes ou que não parecem de navegador em requisições que a edge espera que venham de um cliente.

Se um 403 aparece só a partir da sua VM na nuvem e não do seu notebook, é um problema de reputação de IP, não de código. Se aparece nos endpoints de trading mas não nos de dados de mercado, é geográfico.

Erros de SSL, TLS e certificado

“polymarket ssl error”, “polymarket certificate error” e “polymarket https error” são quase sempre do lado do cliente. Os certificados da Polymarket estão bem; algo entre você e eles não está. Verifique, nesta ordem: um bundle de CAs desatualizado (muito comum em imagens Docker antigas e ambientes Python congelados), um proxy corporativo que inspeciona TLS e substitui o certificado pelo seu próprio, e um relógio do sistema tão errado que os certificados parecem ainda não válidos ou expirados.

# 1. Does TLS work at all, outside your app's HTTP client?
curl -sS -o /dev/null -w "%{http_code} %{ssl_verify_result}\n" \
  https://clob.polymarket.com/ok

# 2. Is your CA bundle current? (Python)
python3 -c "import certifi, os; print(certifi.where()); print(os.path.getmtime(certifi.where()))"

# 3. Is your clock right? Certificate validation depends on it.
date -u

“Service not ready”

Uma mensagem de estado de inicialização: o serviço está no ar o suficiente para responder, mas não está pronto para atender. Na prática, trate-a como um 425 — faça backoff e tente de novo. Ela deve sumir em segundos, e não é algo que você consiga resolver do lado do cliente.

“Order manager not ready”

Uma mensagem de estado de inicialização do motor de casamento, parente próxima do 425 Too Early. O serviço está acessível, mas a camada de gerenciamento de ordens ainda não terminou de subir, então ela aceita sua conexão e recusa sua ordem. É transitória e segura para tentar de novo com backoff — mas trate-a como um sinal para parar de enviar por alguns segundos em vez de martelar, porque um reinício geralmente significa que o livro está prestes a mudar debaixo de você.

Se você a vê de forma persistente em vez de em rajadas, verifique o status da Polymarket antes de depurar seu próprio código — não há nada para corrigir do lado do cliente.

“Couldn't get a quote”

Geralmente significa que não há liquidez no livro do lado que você pediu para cotar, e não que algo está quebrado. Em mercados Up/Down rasos perto do vencimento, um dos lados costuma se esvaziar — ninguém vende Up a preço nenhum quando Up já é certo —, então uma requisição de cotação não retorna nada. Nossos próprios dados mostram que isso é comum: em uma amostra de mercados BTC de 5 minutos, 1,454 de 8,510 tinham o livro de asks vazio em um dos lados 60 segundos antes do vencimento.

Trate como “sem mercado”, e não como erro: pule a operação, não tente de novo em um loop apertado. Se você precisa saber com que frequência isso acontece em uma série que você opera, as páginas de dados de mercado mostram a liquidez por timeframe.

Exceções da biblioteca cliente

Erros como PolyApiException[status_code=None, error_message=request exception!] vêm do cliente Python, não do servidor. status_code=None é a pista: nenhuma resposta HTTP foi recebida, então isso é uma falha no nível da conexão — DNS, TLS, timeout ou um socket derrubado — aparecendo como exceção da biblioteca. Depure como um problema de rede, não de API. O mesmo raciocínio vale para BuilderApiKeyCreds invalid authorization 401 no cliente do relayer, que significa que as credenciais de builder passadas ao cliente não foram aceitas; derive-as de novo em vez de reutilizar um conjunto em cache.

Uma política de novas tentativas que trata tudo isso

A conclusão prática é que os erros da Polymarket caem em três grupos, e confundi-los é o que torna os bots frágeis: tentar de novo às cegas, tentar de novo após um atraso específico e nunca tentar de novo.

CategoriaCódigos / mensagensAção
Transitório425, 500, Service not ready, erros de conexãoTentar de novo com backoff exponencial + jitter
Limitado por taxa429Tentar de novo após Retry-After; se ausente, backoff com jitter
Restrito por modo503 post-onlyEsperar retry_after_seconds e tentar de novo
Restrito por modo503 cancel-only / disabledParar de abrir posições; cancelar se permitido; consultar devagar
Terminal400 de validação, 401, 404Não tentar de novo — corrigir a requisição ou as credenciais
type Decision =
  | { retry: true; delayMs: number }
  | { retry: false; reason: string };

function classify(status: number, body: { error?: string; code?: string; retry_after_seconds?: number }, attempt: number): Decision {
  const msg = (body.error ?? "").toLowerCase();
  const backoff = Math.min(2 ** attempt * 250, 8000);
  const jittered = Math.random() * backoff;

  // Never retry — the request itself is wrong.
  if (status === 401) return { retry: false, reason: "auth: check key, secret, passphrase and clock drift" };
  if (status === 404) return { retry: false, reason: "not found" };
  if (status === 400) return { retry: false, reason: `validation: ${body.error}` };

  // Mode-restricted — the server tells you when to come back.
  if (status === 503 && body.code === "post_only_mode") {
    return { retry: true, delayMs: (body.retry_after_seconds ?? 60) * 1000 };
  }
  if (status === 503) return { retry: false, reason: "exchange paused or cancel-only" };

  // Transient — safe to retry.
  if (status === 425 || status === 429 || status >= 500) return { retry: true, delayMs: jittered };
  if (msg.includes("service not ready")) return { retry: true, delayMs: jittered };

  return { retry: false, reason: `unhandled status ${status}` };
}

Registre a mensagem, gere alerta pela categoria

Alertas baseados em strings de erro cruas geram ruído, porque as mensagens da Polymarket incluem IDs de ordens e preços. Gere alertas pela categoria — um pico de 400 terminais significa que você lançou um bug; um pico de 429 significa que você precisa desacelerar; um pico de 425 significa que a Polymarket está reiniciando e você não deve fazer nada.

Erros que não se resolvem depurando

Algumas coisas que parecem erros simplesmente não são suportadas. A Polymarket não tem endpoint de livro de ofertas histórico, então não há nada para chamar errado. O livro de um mercado resolvido retorna 404 porque a Polymarket deixa de servi-lo quando o mercado é liquidado, mesmo que o seu ID de token esteja correto.

Se você está batendo nessas paredes, não está depurando uma integração — está sem uma fonte de dados. A PolyTest grava snapshots pontuais dos mercados cripto Up/Down da Polymarket enquanto estão ativos, com profundidade completa do livro de ofertas, então o histórico continua lá depois da resolução. Nossa própria referência de erros cobre os formatos de erro da API da PolyTest, que são propositalmente entediantes em comparação.

Perguntas frequentes

O que significa “Unauthorized/Invalid api key” na Polymarket?
Significa que sua chave de API está ausente, expirada ou inválida — mas, na prática, a causa costuma ser uma de quatro coisas: você está enviando um conjunto de credenciais incompleto (a chave, o secret e a passphrase são todos obrigatórios), o relógio do seu sistema desviou o bastante para invalidar a assinatura da requisição, você derivou a chave para uma carteira diferente daquela com que está operando ou está enviando headers L1 onde se esperam headers L2.
O que é o erro 425 da Polymarket?
HTTP 425 Too Early significa que o motor de casamento da Polymarket está reiniciando e sua requisição chegou durante essa janela. É transitório e seguro para tentar de novo com backoff exponencial. Um 425 isolado não merece alerta.
Por que a Polymarket diz “The server was unable to process your request”?
É uma mensagem da camada de edge, e não um erro documentado da API CLOB, o que significa que a requisição nunca chegou à aplicação ou nunca voltou dela de forma limpa. As causas habituais são uma requisição malformada rejeitada antes do roteamento, uma falha transitória upstream ou limitação de requisições prolongada — como a Polymarket limita colocando em fila em vez de rejeitar, um cliente muito acima do limite pode ver timeouts na edge em vez de 429 limpos.
Por que estou recebendo um 403 da API da Polymarket?
Um 403 da Polymarket geralmente é a edge bloqueando a requisição, e não uma falha de autenticação. Os gatilhos comuns são restrições geográficas nos endpoints de trading, faixas de IP de datacenters ou VPNs sendo desafiadas e a ausência de headers parecidos com os de navegador. Se acontece a partir de uma VM na nuvem mas não do seu notebook, é reputação de IP; se acontece nos endpoints de trading mas não nos de dados de mercado, é geográfico.
Como resolvo “the order signer address has to be the address of the API KEY”?
A chave que assina sua ordem não corresponde à chave que a ordem diz ter usado. Isso significa que você está misturando credenciais — normalmente uma chave de API antiga em cache de uma carteira anterior. Derive de novo suas credenciais de API para a carteira com que você realmente está operando e garanta que o endereço maker na ordem corresponda ao endereço dono da chave.
O que significa “order manager not ready” na Polymarket?
É uma mensagem de estado de inicialização do motor de casamento — o serviço está acessível, mas a camada de gerenciamento de ordens ainda não terminou de subir, então ela aceita a conexão e recusa a ordem. É transitória e parente próxima do HTTP 425 Too Early. Tente de novo com backoff, mas pause os envios por alguns segundos em vez de martelar, porque um reinício geralmente significa que o livro está prestes a se mover. Ocorrências persistentes são um problema do lado da Polymarket, não um bug do cliente.
Por que a Polymarket diz que não conseguiu obter uma cotação?
Quase sempre porque não há liquidez no livro do lado que você pediu para cotar, e não porque algo está quebrado. Em mercados Up/Down rasos perto do vencimento, um dos lados costuma se esvaziar — ninguém oferta Up quando Up já é certo. Em uma amostra de mercados BTC de 5 minutos, 1,454 de 8,510 tinham o livro de asks vazio em um dos lados 60 segundos antes do vencimento. Trate como “sem mercado” e pule a operação em vez de tentar de novo em loop.
Devo tentar de novo automaticamente os erros da API da Polymarket?
Só alguns. Tente de novo os 425, 429, os da série 500 e os erros de conexão com backoff exponencial mais jitter. Tente de novo o 503 do modo post-only depois do valor retry_after_seconds que a resposta informa. Nunca tente de novo os erros 400 de validação, os 401 de autenticação ou os 404 — eles exigem corrigir a requisição ou as credenciais, e tentar de novo só queima orçamento de limite de requisições.

Tenha os dados históricos que a Polymarket não guarda

A PolyTest registra os mercados cripto Up/Down da Polymarket enquanto estão ativos — mais de 240M de snapshots com 8 níveis de profundidade do livro de ofertas, timestamps abaixo de um segundo e mercados resolvidos preservados. Comece com um teste grátis de 3 dias.

Continue lendo