Skip to main content

Overview

The PrometheX API uses BBR-based adaptive rate limiting (Bottleneck Bandwidth and Round-trip propagation time). Unlike fixed-window rate limiters, BBR dynamically adjusts limits based on server load and response times.

How It Works

AspectDetail
AlgorithmBBR adaptive rate limiting
ScopePer IP + per authenticated user
Error code110103 (PLEASE_WAIT)
HTTP status429 Too Many Requests
When the server detects excessive load from a client, it responds with:
{
  "code": 110103,
  "reason": "PLEASE_WAIT",
  "msg": "too many requests, please try again later",
  "data": null
}

Rate Limit Guidelines

While the exact limits are adaptive, these guidelines will keep you within safe bounds:
Endpoint TypeRecommended MaxNotes
Public reads (market list, detail)30 req/sCacheable — consider local caching
Authenticated reads (positions, portfolio)10 req/sPer user
Trading operations (buy, sell, claim)5 req/sPer user
SSE connections1 concurrentPer user
Bulk operations2 req/sRate-sensitive

Handling Rate Limits

Exponential Backoff

When you receive a 110103 error, retry with exponential backoff:
async function fetchWithRetry(url, options, maxRetries = 5) {
  for (let attempt = 0; attempt < maxRetries; attempt++) {
    const res = await fetch(url, options);
    const json = await res.json();

    if (json.code !== 110103) return json;

    // Exponential backoff: 1s, 2s, 4s, 8s, 16s
    const delay = Math.min(1000 * Math.pow(2, attempt), 30000);
    const jitter = Math.random() * 500;
    await new Promise(r => setTimeout(r, delay + jitter));
  }

  throw new Error('Rate limit exceeded after max retries');
}

Best Practices

Cache responses

Cache market listings and details locally. Most public data changes infrequently.

Use SSE

Instead of polling for updates, subscribe to SSE events for real-time data.

Batch requests

Fetch multiple items per page instead of making individual requests.

Add jitter

Add random jitter to retry delays to avoid thundering herd problems.

Do’s and Don’ts

DoDon’t
Cache public market dataPoll /get-markets every second
Use SSE for real-time pricesPoll /get-market-detail in a tight loop
Batch with pageSize=50Fetch one market at a time
Retry with exponential backoffRetry immediately without delay
Use a single SSE connectionOpen multiple SSE connections

Monitoring

If you’re building a high-frequency integration, monitor your error rates:
let rateLimitHits = 0;
let totalRequests = 0;

async function monitoredFetch(url, options) {
  totalRequests++;
  const res = await fetch(url, options);
  const json = await res.json();

  if (json.code === 110103) {
    rateLimitHits++;
    console.warn(`Rate limit hit rate: ${(rateLimitHits / totalRequests * 100).toFixed(1)}%`);
  }

  return json;
}
If you consistently hit rate limits and need higher throughput, contact the PrometheX team on Discord to discuss dedicated API access.