Rate Limits

The API enforces rate limits to ensure fair usage and platform stability.

Rate Limit Overview

EndpointLimitWindow
Registration5 requests24 hours
Wallet operations30 requests1 minute
Trading (swap/transfer/bridge)30 requests1 minute
Portfolio60 requests1 minute
Token search100 requests1 minute
DEX data60 requests1 minute
RPC proxy100 requests1 minute
Token launch1 request24 hours
Fee claims1 request1 hour

Rate Limit Headers

All API responses include rate limit headers:

X-RateLimit-Limit: 30
X-RateLimit-Remaining: 25
X-RateLimit-Reset: 1699574400

Handling 429 Responses

When you exceed rate limits, the API returns HTTP 429:

import { RateLimitError } from '@loomlay/openclaw-wallet-sdk';
 
try {
  await wallet.trading.swap({ ... });
} catch (error) {
  if (error instanceof RateLimitError) {
    console.log('Rate limited. Retry after:', error.retryAfter, 'seconds');
  }
}

Exponential Backoff

Implement exponential backoff for robust retry logic:

async function withRetry<T>(
  fn: () => Promise<T>,
  maxAttempts = 5
): Promise<T> {
  let lastError: Error | undefined;
 
  for (let attempt = 0; attempt < maxAttempts; attempt++) {
    try {
      return await fn();
    } catch (error) {
      if (error instanceof RateLimitError) {
        // Use server-provided retry time, or calculate backoff
        const delay = error.retryAfter
          ? error.retryAfter * 1000
          : Math.min(1000 * Math.pow(2, attempt), 30000);
 
        console.log(`Rate limited. Retrying in ${delay}ms...`);
        await sleep(delay);
        lastError = error;
      } else {
        throw error;
      }
    }
  }
 
  throw lastError;
}
 
function sleep(ms: number): Promise<void> {
  return new Promise(resolve => setTimeout(resolve, ms));
}
 
// Usage
const result = await withRetry(() =>
  wallet.trading.swap({
    inputToken: 'SOL',
    outputToken: 'USDC',
    amount: '1',
  })
);

Built-in Retry

The SDK includes built-in retry for transient failures:

const wallet = new OpenClawWallet({
  apiKey: process.env.LOOMLAY_API_KEY!,
  maxRetries: 3,     // Retry up to 3 times
  retryDelay: 1000,  // Start with 1s delay
});

Built-in retry uses exponential backoff automatically. Each retry waits 2x longer than the previous.

WebSocket Limits

WebSocket connections have separate limits:

LimitValue
Subscriptions per client10
Max upstream connections20
Heartbeat interval30 seconds
const dexWs = wallet.createDexWebSocket();
 
// Maximum 10 subscriptions per connection
dexWs.subscribePair('SOL/USDC');
dexWs.subscribePair('ETH/USDC');
// ... up to 10 pairs

Best Practices

Batch When Possible

Instead of multiple individual calls:

// Less efficient: 3 API calls
const sol = await wallet.wallet.get();
const portfolio = await wallet.portfolio.get();
const status = await wallet.tokenize.status();

Use a single portfolio call when you need holdings:

// More efficient: 1 API call
const portfolio = await wallet.portfolio.get();
// Contains balances across all chains

Cache Responses

Cache data that doesn't change frequently:

let cachedPortfolio: PortfolioResult | null = null;
let cacheTime = 0;
const CACHE_TTL = 60000; // 1 minute
 
async function getPortfolio() {
  const now = Date.now();
 
  if (cachedPortfolio && now - cacheTime < CACHE_TTL) {
    return cachedPortfolio;
  }
 
  cachedPortfolio = await wallet.portfolio.get();
  cacheTime = now;
  return cachedPortfolio;
}

Use WebSockets for Real-time Data

For frequently updating data, use WebSockets instead of polling:

// Instead of polling
setInterval(async () => {
  const data = await wallet.dex.getPair('SOL/USDC'); // Uses rate limit
}, 1000);
 
// Use WebSocket
const dexWs = wallet.createDexWebSocket();
dexWs.subscribePair('SOL/USDC');
dexWs.on('update', (data) => {
  console.log('Real-time update:', data);
});

Spread Out Requests

If you need to make many requests, spread them out:

const tokens = ['SOL', 'ETH', 'USDC', 'BONK', 'WIF'];
const results = [];
 
for (const token of tokens) {
  const data = await wallet.dex.getToken(token);
  results.push(data);
 
  // Small delay between requests
  await sleep(100);
}

Registration Limits

Registration is strictly limited to prevent abuse. Each IP address can only register a limited number of accounts.

If you need additional API keys:

  1. Use the key management endpoints to create additional keys for your existing account
  2. Contact support for legitimate multi-account use cases
// Create additional keys for existing account
const newKey = await wallet.auth.createKey();
console.log('New key:', newKey.apiKey);
 
// List all keys
const keys = await wallet.auth.listKeys();
 
// Revoke a key
await wallet.auth.revokeKey({ keyId: 'key_to_revoke' });