For the complete documentation index, see llms.txt. This page is also available as Markdown.

Limites de requisições

Quanto custa uma requisição, o que significam os cabeçalhos de limite de requisições, quais orçamentos são independentes entre si e o que acontece quando você excede cada um.

A Exchange não orça seu tráfego em requisições por segundo. Ela orça em peso por segundo. Cada requisição recebe um custo: a maioria custa uma unidade e algumas custam mais. Um cliente que controla seu ritmo contando requisições é recusado enquanto seu próprio contador ainda parece saudável. Essa é a surpresa de integração mais comum com esta API.

Esta página explica o modelo: quanto as coisas custam, quais orçamentos são separados e como ler os cabeçalhos. A definição normativa é o contrato OpenAPI, publicado em nexus-xyz/nexus-exchange-api e servido em /openapi.json. A seção "Rate limits" da descrição da API é a dona da semântica dos cabeçalhos, e cada operação traz seu próprio custo legível por máquina. Onde esta página e o contrato divergirem, o contrato está certo.

Quanto custa uma requisição

Seu orçamento é um token bucket que se recarrega continuamente na taxa por segundo do seu nível, com capacidade de exatamente um segundo de tokens. Essa capacidade tem duas consequências. A taxa sustentada e a tolerância de burst são o mesmo número, então não existe uma reserva de vários segundos para acumular ficando ocioso. E remaining nunca pode exceder limit.

A maioria das requisições custa 1. As exceções:

Custo
Aplica-se a

5

GET /account/activity, GET /account/portfolio-history, GET /account/summary, GET /fills, GET /orders/history, GET /positions/pnl, GET /stats/referrals

1 + floor(order_count / 40)

POST /orders/batch

1

todas as outras operações que o contrato documenta

Cada custo também vale para o equivalente em /api/v1 da operação, quando ele existe.

As leituras pesadas consolidam ou varrem um grande buffer por conta (execuções, histórico de ordens, a série temporal do portfólio, o feed de atividade mesclado), se desdobram pelas posições abertas ou agregam contagens de indicações de toda a plataforma a partir do backend de contas. O custo de um envio em lote cresce com o tamanho dele, então até 40 ordens custam o mesmo que uma.

Assim, um chamador Pro com limit: 20 tem 20 leituras de ticker por segundo, ou 4 leituras de /fills, do mesmo orçamento no mesmo nível. Controle o ritmo pelo peso, não pela contagem de requisições.

Duas propriedades de segurança limitam o pior caso. A cobrança de uma única requisição tem teto de um segundo de tokens, então um lote grande demais nunca fica permanentemente impossível de atender. Ele consome o segundo inteiro assim que o bucket se recarrega e passa, em vez de ficar em loop para sempre numa nova tentativa que nunca conseguiria pagar. E um corpo de lote que o servidor não consegue interpretar é cobrado pela unidade base em vez de ser recusado por causa do peso.

Em vez de fixar a tabela acima no código, leia o custo no contrato: operações que custam mais de uma unidade trazem x-nexus-rate-limit-weight, e aquelas cujo custo depende do corpo também trazem x-nexus-rate-limit-weight-formula. Para uma operação que o contrato documenta, a ausência do marcador significa peso 1. Essa é a forma contra a qual construir um limitador do lado do cliente.

A ressalva importa. O contrato lista as operações suportadas, e a regra vale para todas elas, mas não diz nada sobre outros caminhos que por acaso respondam. Uma rota que o contrato não lista não traz marcador, não é coberta pela regra e pode ser cobrada de forma diferente do que sua ausência sugere. Construa contra as operações que o contrato documenta, não contra caminhos encontrados por sondagem. São essas operações que os pesos, e esta página, descrevem.

Quatro orçamentos, não um

Há quatro classes de recurso independentes. Gastar uma não gasta as outras, e cada uma recusa à sua maneira:

Classe
Abrange
Cobrado de

Requisições

Toda operação REST que não seja uma escrita de ordem

Seus buckets de requisições por chave e por titular

Ações de negociação

POST e PATCH sob /orders, marcados com x-nexus-rate-limit-class: trading

Um bucket de ordens dedicado, com o mesmo tamanho por segundo do bucket de requisições

Cancelamentos

DELETE sob /orders, também marcado com x-nexus-rate-limit-class: trading

Um bucket de cancelamento separado, novamente com o mesmo tamanho por segundo

Plano de controle do WebSocket

Conexões, assinaturas e frames de entrada do cliente

Tetos por nível. Veja Tetos do WebSocket

Uma escrita de ordem é cobrada do bucket de negociação em vez do bucket de requisições, não além dele. Por causa dessa divisão, um burst de polling não consegue sufocar o envio das suas ordens, e o fluxo de ordens não consegue sufocar suas leituras. Segue-se que um x-ratelimit-remaining saudável na sua última leitura não diz nada sobre a sua folga para enviar ordens. São reservas diferentes, então leia a reserva da qual você está prestes a gastar. GET /account/rate-limit informa cada orçamento separadamente em buckets, e buckets.order responde se você pode enviar uma ordem.

Cancelamentos nunca compartilham um token com envios

Cancelar é a única ação separada da negociação em um orçamento próprio. Um DELETE nos endpoints de ordens (cancelar uma, cancelar tudo ou cancelar por mercado) é cobrado do bucket de cancelamento em vez do bucket de ordens, então uma chave que gastou toda a sua cota de envio enviando ordens ainda tem uma cota cheia e intacta para retirá-las.

Essa é a única assimetria deliberada do modelo. O envio pode esperar, e a redução de risco não pode. Um limitador que recusa seu cancelamento enquanto uma posição anda contra você transforma um controle de uso justo em prejuízo. Por isso a regra é incondicional. Esgotar o envio nunca pode recusar um cancelamento, porque os dois nunca consomem o mesmo token.

Para um cliente, isso significa:

  • Nunca deduza sua folga de cancelamento a partir de um 429 de envio. Um bucket order vazio não diz nada sobre o cancel. Um cliente que recua em todas as chamadas de ordens após uma única recusa de envio limitou justamente a chamada que ainda deveria estar fazendo.

  • Um bucket separado não é um atalho. Cancelamentos são medidos na mesma taxa por segundo do nível que todo o resto, então um loop de cancelamentos ainda pode receber um 429. Ele traz bucket: cancel, a única recusa que significa que seu canal de cancelamento está saturado. Respeite retry-after nesse caso.

Edições são cobradas como envio, não como cancelamento. PATCH não diz se uma edição reduz ou aumenta a exposição, e uma edição que aumenta o tamanho é um envio em qualquer leitura. Então a garantia acima se aplica apenas ao método que sempre reduz risco. Se você precisa da garantia, cancele.

POST /orders/preview também é uma ação de negociação, o que é fácil de passar despercebido. É uma escrita sob /orders e custa uma unidade da classe de negociação, o mesmo que enviar uma ordem. Pré-visualizar antes de cada ordem, portanto, reduz pela metade sua taxa efetiva de envio. Reserve duas cobranças da classe de negociação por ordem enviada dessa forma, ou pule a pré-visualização quando já souber o dimensionamento.

Um chamador que apresenta uma chave HMAC passa por um bucket por chave e depois pelo bucket por titular do seu nível, e o teto efetivo é o que limitar primeiro. GET /account/rate-limit informa esse mínimo, e consultá-lo é gratuito. É a única operação que não consome tokens, então controlar seu próprio ritmo não pode limitar você.

Se você acabou de ser promovido, observe que o teto próprio de uma chave é registrado quando a chave é criada (o padrão está na tabela de níveis abaixo), e uma mudança de nível não o reescreve. Uma conta Market Maker que ainda usa uma chave criada no padrão pode, portanto, ficar presa ao número da chave em vez do número do nível. Leia /account/rate-limit após uma promoção em vez de presumir o valor do nível, e crie uma chave nova se o mínimo informado não for o esperado.

Lendo os cabeçalhos

  • Em toda resposta autenticada: x-ratelimit-limit e x-ratelimit-remaining.

  • Somente em um 429, também: x-ratelimit-reset (segundos unix) e retry-after (segundos, nunca abaixo de 1).

Não espere os dois últimos em uma resposta de sucesso. Um cliente que lê x-ratelimit-reset de um 2xx não lê nada.

remaining e retry-after usam unidades diferentes, de propósito. remaining conta requisições de custo unitário, então x-ratelimit-remaining: 10 significa dez requisições de peso 1 ou duas pesadas. retry-after é derivado do custo ponderado da requisição que foi recusada. Um limitador que lê remaining como "requisições do tipo que estou prestes a enviar" vai enviar demais em endpoints pesados e provocar seus próprios 429.

Uma recusa é um HTTP 429 com este corpo:

Ramifique pelo code e depois pelo bucket. Ele é um de key, owner, order, cancel, ip ou login e, para os quatro primeiros, é a chave a consultar em buckets de GET /account/rate-limit. ip e login nunca aparecem ali. Ambos medem uma conexão em vez de uma conta, e login é recusado antes mesmo de uma conta ser estabelecida. O mesmo valor é enviado no cabeçalho x-ratelimit-bucket, então um proxy ou wrapper de novas tentativas pode lê-lo sem interpretar o corpo. A message nomeia qual reserva se esgotou (Rate limit exceeded, API key rate limit exceeded, Order placement rate limit exceeded ou IP rate limit exceeded). Ela é um diagnóstico. Seu texto não é estável, então não faça correspondência com ele no código.

Diferente das recusas 403 por jurisdição, um 429 pode ser repetido: respeite retry-after e recue. Controlar o ritmo por x-ratelimit-remaining é melhor do que descobrir o teto batendo nele.

O GET /account/rate-limit gratuito informa o mesmo estado sem gastar um token. Os campos de nível superior cobrem a classe de requisições, e buckets cobre todos os orçamentos:

buckets é indexado pelos mesmos rótulos que um 429 usa, tanto no campo bucket quanto no cabeçalho x-ratelimit-bucket. Assim, uma recusa aponta direto para o estado que a causou: buckets[error.bucket]. Construa seu limitador em torno dessa consulta. key aparece apenas quando um bucket por chave limita você, e nem ip nem login aparecem nunca, porque ambos medem uma conexão em vez de uma conta.

Os campos de nível superior limit, remaining e reset_at_ms são a classe de requisições, sem mudanças, então nada que os lê precisa mudar. Eles não respondem "posso enviar uma ordem". buckets.order responde. Em uma chave que acabou de chegar ao teto de envio cotando, os dois divergem completamente: remaining: 20 ao lado de buckets.order.remaining: 0.

Dois detalhes a tratar quando você usa tanto este endpoint quanto os cabeçalhos. reset_at_ms está em milissegundos, enquanto o cabeçalho x-ratelimit-reset está em segundos unix. E o nome do nível vem em minúsculas aqui (pro), mas não no corpo do 429 (Pro), então compare sem diferenciar maiúsculas de minúsculas em vez de comparar com um literal.

Os três campos numéricos são null para um chamador Unlimited, que é agrupado em buckets por IP em vez de por conta. buckets volta como {}, porque nenhum orçamento no escopo da conta mede esse chamador.

Níveis e tetos atuais

Os níveis são multiplicadores sobre um único modelo, não modelos diferentes. Pro é o padrão para toda conta. Um administrador atribui MarketMaker. Solicite-o pelo seu contato na Nexus e veja o Guia para market makers. Unlimited existe para chaves de gateway que multiplexam muitos usuários e nunca é atribuído a uma conta de negociação.

Nível
Requisições
Ações de negociação
Conexões WS
Assinaturas WS
Frames de entrada WS

Pro

20/s

20/s

5

50

10/s

MarketMaker

2.000/s

2.000/s

100

1.000

50/s

Unlimited

por IP, 50/s

por IP, 50/s, o mesmo bucket das leituras

isento

isento

isento

Por IP do cliente, em todos os níveis
Teto

Leituras de dados de mercado não autenticadas

50/s

POST /auth/login, em uma reserva própria

5/s

Conexões WebSocket, verificadas no upgrade

5

Uma nova chave de API é criada com teto próprio de 20/s.

Os tetos por IP se aplicam independentemente do nível, todos antes de você ter uma credencial. POST /auth/login é medido de forma muito mais rígida do que as leituras, em uma reserva própria. Uma tentativa de login custa um ecrecover sobre uma assinatura EIP-191, e qualquer pessoa que alcance o endpoint pode fazer o servidor pagar esse custo. O limite não é uma defesa contra adivinhação de segredo, já que a mensagem assinada é uma constante fixa e não há nada para descobrir por força bruta. É uma defesa de custo. Tráfego cujo IP de cliente não pode ser resolvido também não é admitido sem limitação. Leituras compartilham um bucket e logins compartilham um segundo, separado, então uma enxurrada que remove seu x-forwarded-for não consegue esgotar a reserva da qual o resto do tráfego não resolvível depende. Uma origem não resolvível recebe um teto compartilhado em vez de nenhum teto. O tamanho dele é definido por implantação, então ele não aparece na tabela acima.

Uma recusa de login traz bucket: login, que é a única recusa que significa que o próprio portão de login está saturado. É um teto por IP, então você o compartilha com todos atrás do seu NAT ou proxy de saída, e ele não diz nada sobre a sua conta. Ainda não há conta.

Os cancelamentos têm seu próprio orçamento na taxa de Ações de negociação. A tabela não dá a eles uma coluna própria porque os dois números são iguais por construção.

Unlimited tem isenções mais estreitas do que o nome sugere. Suas escritas de ordens e seus cancelamentos não estão isentos de limite de requisições. Eles pulam tanto o bucket de negociação dedicado quanto o bucket de cancelamento e são cobrados do mesmo bucket por IP de suas leituras. Então nem a independência de classes acima nem a garantia de cancelamento valem ali, e o próprio polling de um gateway pode sufocar seu fluxo de ordens, justamente no nível cujo perfil de tráfego é o menos previsível. Os tetos de WS dos quais ele é isento são os por conta. O limite de conexões por IP abaixo continua valendo.

Esses números são padrões atuais, não um contrato congelado. Eles são gerados a partir da extensão x-nexus-rate-limits do contrato, que um teste mantém igual ao que o serviço aplica, e vão mudar à medida que o sistema de níveis for finalizado. Leia /account/rate-limit em vez de fixá-los no código.

Tetos do WebSocket

Os tetos do WebSocket são uma classe de recurso própria, independente do orçamento de requisições REST e do orçamento de ações de negociação. Esgotar um não afeta os outros.

Conexões têm teto por conta de acordo com o nível (a coluna Conexões WS acima). Um limite por IP separado (a tabela por IP) se aplica primeiro, no momento do upgrade, e vale em todos os níveis, incluindo Unlimited, então um único endereço de origem não consegue alcançar sozinho o valor por conta. Uma conexão recusada ali recebe um HTTP 429 (ws_conn_limit_exceeded) na requisição de upgrade em vez de um frame de fechamento. O token de stream de uso único é gasto de qualquer forma, então crie um novo antes de reconectar.

Assinaturas têm teto no mesmo número duas vezes: por conexão e somando todas as conexões de uma conta. Abrir mais sockets, portanto, não compra mais assinaturas. Assinar de novo uma chave (channel, market) que você já tem a substitui no lugar e é gratuito. Exceder o teto retorna um frame error (subscription_limit_exceeded) em vez de um código de status, porque não há respostas HTTP depois que o socket está aberto.

Frames de entrada (suas assinaturas, cancelamentos de assinatura e pings) são limitados à taxa sustentada por nível, com um burst de 2× tolerado acima dela, para que uma tempestade de reconexão e reassinatura não seja penalizada. Além disso, o servidor descarta frames acima do limite e envia um aviso error por janela de contabilização em vez de um por frame, para que uma enxurrada de entrada não se transforme em uma de saída. Uma enxurrada sustentada, isto é, frames descartados suficientes dentro de uma janela, fecha a conexão com o código 1008 (violação de política). O servidor não aplica um frame descartado e não avisa você. Se você não vir um ack subscribed, reenvie a assinatura depois de recuar em vez de presumir que ela teve efeito.

Os orçamentos são por rede

Cada rede é sua própria implantação, então cada rede tem seus próprios buckets. Gastar na testnet não reduz a folga na mainnet quando a mainnet for lançada, e o inverso também não. As credenciais também não atravessam redes. Uma chave fica vinculada à rede que a criou. Veja Redes.

Onde a aplicação dos limites acontece hoje

Uma limitação atual é visível de fora, e ela funciona a seu favor, não contra você.

O processo do gateway mantém o estado do limitador em memória, não em um armazenamento compartilhado. Duas coisas decorrem disso. Primeiro, ele não é durável. Uma nova implantação zera seus buckets, e uma promoção de nível pode voltar brevemente ao nível base até ser reaplicada. Segundo, quando o gateway de uma rede roda mais de uma réplica, cada uma mantém seus próprios buckets, então o teto agregado que um cliente observa pode ser maior do que o valor por segundo publicado, dependendo de onde suas conexões caem.

Não projete contando com essa folga. Trate o número publicado como o teto a que você tem direito e controle seu ritmo por ele. O excedente vem de onde a aplicação dos limites está hoje, não é distribuído de forma uniforme e desaparece quando os contadores forem para um armazenamento compartilhado. Um cliente construído para o valor publicado continua funcionando quando isso chegar. Um ajustado ao agregado observado vai começar a ver 429.

Seu signatário consegue acompanhar?

O cliente assina cada requisição autenticada antes de ela sair, então o signatário impõe um teto próprio abaixo dos orçamentos acima. Verifique esse teto antes de escolher um SDK. Ele depende muito mais do esquema e da biblioteca de criptografia do que da linguagem.

A Exchange aceita dois esquemas de assinatura de requisições (veja Autenticação e Agentes):

  • HMAC (hmacAuth). HMAC-SHA256 sobre a string canônica de cinco campos, com a chave sendo o segredo de API decodificado de hex. Um MAC simétrico leva microssegundos em qualquer linguagem.

  • Chave de agente (agentAuth). ECDSA secp256k1 sobre o keccak256 da string canônica de seis campos, low-S, enviada como r||s||v de 65 bytes. É uma assinatura de curva elíptica, então seu custo depende de a biblioteca subjacente ser código nativo ou código interpretado puro.

Medido pelo próprio caminho de assinatura de cada SDK, com um corpo fixo de POST /api/v1/orders, em uma thread. É a mesma chamada que o cliente faz em toda requisição, incluindo montar a string canônica, calcular o hash do corpo e codificar o resultado em hex, mas sem I/O de rede:

SDK
Esquema
Criptografia subjacente
p50
p95
Assinaturas/s
p50 em 5 execuções

Rust (nexus-exchange-rs)

HMAC

hmac + sha2

0,9 µs

0,9 µs

~1.080.000

0,88–0,96 µs

Rust (nexus-exchange-rs)

Chave de agente

k256

79 µs

91 µs

~12.500

74–79 µs

TypeScript (nexus-exchange-ts)

HMAC

Web Crypto (assíncrono)

27 µs

43 µs

~29.000

24–35 µs

TypeScript (nexus-exchange-ts)

Chave de agente

@noble/curves

319 µs

470 µs

~2.900

293–645 µs

Python (nexus-exchange-py)

HMAC

hmac da stdlib

2,1 µs

2,2 µs

~460.000

1,96–2,25 µs

Python, instalação padrão

Chave de agente

backend puro Python do eth-keys

3,5 ms

4,2 ms

~280

3,43–4,11 ms

Python + coincurve

Chave de agente

libsecp256k1 via coincurve

97 µs

110 µs

~10.000

96–116 µs

A CLI assina pelo crate Rust, então herda as linhas do Rust em vez de ter números próprios.

No nível Pro, nenhum SDK e nenhum esquema é limitado pelo signatário. 20 requisições por segundo deixam 50 ms por assinatura. A linha mais lenta, assinatura com chave de agente em uma instalação padrão do Python, usa 3,5 ms disso, então consegue assinar cerca de quatorze vezes a taxa Pro em um núcleo. Mesmo um chamador saturando os três buckets Pro ao mesmo tempo (requisições, ações de negociação e cancelamentos, 60 requisições assinadas por segundo) gasta cerca de um quinto de um núcleo assinando. O signatário de chave de agente do TypeScript tem mais de cem vezes essa folga, e o HMAC é praticamente gratuito em todos os SDKs.

No nível MarketMaker, o esquema e a biblioteca começam a importar. Suas 2.000 ações de negociação por segundo, mais 2.000 cancelamentos separados, deixam 0,25–0,5 ms por assinatura em uma thread.

  • Python com chave de agente: uma instalação padrão assina cerca de 280 por segundo, aproximadamente um sétimo do teto de negociação. Instale o coincurve (pip install coincurve) no mesmo ambiente e o AgentSigner passa a rodar sobre a libsecp256k1, a cerca de 10.000 por segundo, sem mudança no seu código. O SDK não escolhe um backend de curva por conta própria; o eth-keys usa o coincurve sempre que consegue importá-lo, a menos que a variável de ambiente ECC_BACKEND_CLASS indique um backend diferente. O bench de Python imprime o backend que mediu, que é a forma mais rápida de confirmar que a troca funcionou. Ou assine com HMAC, que nunca é a restrição.

  • TypeScript com chave de agente: cerca de 2.900 por segundo supera o teto de negociação em um núcleo, mas não negociação e cancelamentos juntos. Um cliente que roda ambos na taxa máxima deve assinar com HMAC ou distribuir a assinatura entre worker threads.

  • Rust e a CLI: folgados em qualquer um dos esquemas.

Por requisição, a assinatura acrescenta 0,3 ms no TypeScript e 3,5 ms em uma instalação padrão do Python com chave de agente. Isso é uma pequena fração de uma ida e volta do cliente medida em dezenas de milissegundos, mas perceptível no caminho do Python. É mais um motivo para instalar o coincurve se você negocia a partir do Python com uma chave de agente.

Como isso se compara aos números publicados pela Paradex

A Paradex publica uma tabela parecida: cerca de 5.000 assinaturas por segundo em Rust, 1.430 em Go, 50 em TypeScript e 8 em Python ou Java. Lidos ao pé da letra, os 20 ms por assinatura do TypeScript limitam uma thread a 50 assinaturas por segundo. Isso cobre um único orçamento de 20/s, mas só a assinatura usaria 40% do núcleo, e fica abaixo dos 60/s que um chamador Pro pode gastar somando requisições, ações de negociação e cancelamentos. Esses números não se transferem. A Paradex assina ordens com uma chave StarkNet, uma curva diferente e um hash diferente de ambos os esquemas aqui, e seus números não foram medidos no hardware abaixo, então uma proporção entre as duas tabelas é, no máximo, indicativa. O padrão se transfere. Um signatário de curva elíptica em código interpretado puro é o caso lento, e bindings nativos fecham a maior parte da diferença. A diferença aqui é que o caso lento (Python com seu fallback puro Python, cerca de 280 por segundo) ainda é mais de dez vezes mais rápido do que o nível Pro precisa.

Metodologia

  • Hardware. Apple M2, 8 núcleos (4 de desempenho, 4 de eficiência), 8 GB, macOS 26.5 (build 25F84), na tomada e com o Modo de Pouca Energia desativado. O macOS não consegue fixar um processo em um núcleo, e a máquina não estava ociosa de outra forma (média de carga 4–14 durante as execuções), então leia a coluna p95 e a variação como limites superiores.

  • Runtimes. Rust 1.97 (perfil release), Node.js 22.23, Python 3.14 para as linhas de HMAC e de chave de agente padrão. A linha do coincurve roda em Python 3.13, porque o coincurve ainda não publica wheel para Python 3.14. A linha de chave de agente padrão mede o mesmo em 3.13 (3,5 ms), então o interpretador não explica a diferença.

  • Fixture. Idêntica nos três SDKs: POST, caminho /api/v1/orders, query vazia, um corpo de ordem limite de 155 bytes, um timestamp fixo. O signatário de agente emite um nonce novo a cada iteração, como faz em uma escrita real. Ambos os esquemas produzem assinaturas idênticas byte a byte entre os SDKs para essa fixture.

  • Procedimento. Dois segundos de aquecimento, depois cada assinatura é cronometrada individualmente (Rust 20.000, TypeScript 5.000, Python 3.000 ou 5.000) e p50 e p95 são extraídos das amostras. Assinaturas por segundo é o número de amostras dividido pelo tempo de relógio do loop cronometrado. Cada benchmark rodou cinco vezes, intercalado com os outros. A tabela mostra a execução mediana e a faixa de p50 nas cinco. O bench de Rust também roda o criterion, cuja estimativa de média coincidiu com o loop cronometrado (76–85 µs para a chave de agente).

  • Rode de novo. Cada SDK traz seu bench: cargo bench --bench signing no nexus-exchange-rs, pnpm bench no nexus-exchange-ts e python bench/signing_bench.py no nexus-exchange-py. O bench de Python imprime qual backend do eth-keys ele mediu.

Projetando para os limites

  • Use lotes em vez de loops. POST /orders/batch cobra 1 + floor(n / 40), então 40 ordens em uma requisição custam um quadragésimo de 40 envios avulsos.

  • Use stream em vez de polling. Dados do livro de ofertas e de negociações pelo WebSocket não custam nada do seu orçamento de requisições e chegam antes: o frame de assinatura é um frame de entrada, e o stream que vem depois é gratuito.

  • Orce as leituras pesadas pelo custo real. /fills, /orders/history, /account/summary e /account/portfolio-history custam 5 cada. Consultar as quatro a cada segundo custa 20/s, que é o orçamento inteiro de um chamador Pro.

  • Prefira uma leitura coerente. GET /account/state retorna o resumo e todas as posições abertas juntos. É mais barato do que duas chamadas e livre da condição de corrida entre elas (veja Portfólio e estado da conta).

  • Faça cache do que não muda. Os metadados de mercado de GET /markets não precisam ser buscados de novo a cada ciclo.

  • Controle o ritmo pelos cabeçalhos e por /account/rate-limit. Consultar esse endpoint é gratuito. Tentar de novo às cegas depois de um 429 não é.

Relacionados

Status: prévia de desenvolvimento na testnet. A mainnet não foi lançada. Todo teto nesta página é configuração atual, não um contrato congelado. Leia /account/rate-limit em produção em vez de fixar um número no código, e fixe uma versão publicada da especificação para que os pesos por operação contra os quais você constrói permaneçam fixos. O estado do limitador ainda não é durável entre reinicializações do gateway. Credenciais e saldos da testnet não têm valor no mundo real.

Atualizado