Limits
In this guide, we will look at how rate limiting works in the Moon Banking API. We will cover the rate limit structure, how to monitor your usage, and best practices for handling rate limits in your application.
The Moon Banking API uses rate limiting to ensure fair usage and maintain optimal performance for all users. Understanding how rate limits work will help you build robust applications that handle API requests efficiently.
Except for customers with a custom rate limit, the Moon Banking API limits API requests to 100 requests per minute per API key to ensure fair usage and prevent abuse. You may request higher limits by contacting support.
Rate limit structure
The Moon Banking API implements a simple and predictable rate limiting system based on fixed time windows. All rate limits are applied per API key.
- Name
Requests per minute- Description
100 requests per minute per API key (may be increased upon request)
- Name
Time window- Description
Fixed clock minutes (not rolling windows)
- Name
Scope- Description
- Rate limits apply per API key
Fixed minute windows
Rate limits are based on fixed clock minutes rather than rolling time windows. This means:
- The rate limit counter resets at the start of each clock minute (e.g., 10:45:00, 10:46:00)
- If you make 100 requests at 10:45:59, you can immediately make 100 more at 10:46:00
Monitoring your rate limits
API responses include headers that tell you your current rate limit status. You should monitor these headers to avoid hitting rate limits.
- Name
X-Rate-Limit-Per-Minute- Description
The maximum number of requests allowed per minute (currently 100, but may be increased upon request)
- Name
X-Rate-Limit-Remaining-Per-Minute- Description
The number of requests remaining in the current minute
- Name
X-Rate-Limit-Reset-Per-Minute- Description
The ISO 8601 timestamp when the rate limit will reset
- Name
X-Rate-Limit-Retry-After- Description
The number of seconds until the next reset time for the per-minute rate limit. You should wait to retry until this number of seconds has passed. This header will only be present if you have exceeded the rate limit.
Example response headers
Response headers
HTTP/1.1 200 OK
X-Rate-Limit-Per-Minute: 100
X-Rate-Limit-Remaining-Per-Minute: 87
X-Rate-Limit-Reset-Per-Minute: 2025-01-05T15:47:00.000Z
Content-Type: application/json
When you exceed the limit
When you exceed your rate limit, the API will return a 429 Too Many Requests error. The response headers will include information about your rate limit status and when you can make requests again.
Error response
{
"success": false,
"message": "Rate limit exceeded. Please try again later.",
"code": "RATE_LIMIT_EXCEEDED",
"timestamp": "2025-01-05T15:46:37.482Z",
"version": "2025-07-11"
}
Best practices
Follow these best practices to avoid hitting rate limits and build a robust integration with the Moon Banking API.
Implement retry logic with exponential backoff
Always implement retry logic that respects the retryAfter value in rate limit errors. Use exponential backoff for repeated failures.
async function makeRequestWithRetry(requestFn, maxRetries = 3) {
try {
for (let attempt = 0; attempt <= maxRetries; attempt++) {
try {
return await requestFn();
} catch (error) {
if (error.code === 'RATE_LIMIT_EXCEEDED' && attempt < maxRetries) {
const retryAfter = error.data?.retryAfter || 1;
const backoff = Math.min(retryAfter * 1000 * 2 ** attempt, 60000);
await new Promise((resolve) => setTimeout(resolve, backoff));
continue;
}
throw error;
}
}
} catch (error) {
console.error('Request failed after retries:', error);
throw error;
}
}
Monitor rate limit headers
Always check the X-RateLimit-Remaining-PerMinute header and slow down your requests when you're getting close to the limit.
async function monitorRateLimit(response) {
const remaining = parseInt(
response.headers.get('X-RateLimit-Remaining-PerMinute'),
);
const resetTime = response.headers.get('X-RateLimit-Reset-PerMinute');
if (remaining < 10) {
console.warn(
`Rate limit warning: Only ${remaining} requests remaining until ${resetTime}`,
);
// Consider slowing down or queuing requests
}
return remaining;
}
Implement request queuing
For applications that need to make many requests, implement a queue system that respects rate limits and spreads requests evenly across each minute.
class RateLimitedQueue {
constructor(requestsPerMinute = 100) {
this.limit = requestsPerMinute;
this.queue = [];
this.processing = false;
}
async add(requestFn) {
return new Promise((resolve, reject) => {
this.queue.push({ requestFn, resolve, reject });
if (!this.processing) {
this.process();
}
});
}
async process() {
this.processing = true;
while (this.queue.length > 0) {
const { requestFn, resolve, reject } = this.queue.shift();
try {
const result = await requestFn();
resolve(result);
} catch (error) {
if (error.code === 'RATE_LIMIT_EXCEEDED') {
// Re-queue the request
this.queue.unshift({ requestFn, resolve, reject });
const retryAfter = error.data?.retryAfter || 30;
await new Promise((r) => setTimeout(r, retryAfter * 1000));
} else {
reject(error);
}
}
// Add small delay between requests to avoid bursting
await new Promise((r) => setTimeout(r, 600)); // ~100 requests per minute
}
this.processing = false;
}
}
// Usage
const queue = new RateLimitedQueue(100);
for (const id of countryIds) {
queue.add(() => client.countries.retrieve(id));
}
Cache responses when possible
Reduce the number of API requests by caching responses for data that doesn't change frequently.
const cache = new Map();
const CACHE_TTL = 5 * 60 * 1000; // 5 minutes
async function getCachedCountry(client, countryId) {
const cacheKey = `country:${countryId}`;
const cached = cache.get(cacheKey);
if (cached && Date.now() - cached.timestamp < CACHE_TTL) {
return cached.data;
}
const data = await client.countries.retrieve(countryId);
cache.set(cacheKey, { data, timestamp: Date.now() });
return data;
}
Rate limit increases
The current rate limit of 100 requests per minute is designed to accommodate most use cases. If your application requires higher rate limits, please contact support to discuss your needs.
When requesting a rate limit increase, please provide:
- Your use case and expected request volume