Skip to content

Rate Limits

LMIF uses rate limits to ensure fair usage and maintain service quality.

PlanRequests/minuteRequests/dayBatch Size
Sandbox601,000100
Basic30050,000100
Standard1,000500,000100
EnterpriseCustomCustomCustom

Every response includes rate limit headers:

X-RateLimit-Limit: 300
X-RateLimit-Remaining: 299
X-RateLimit-Reset: 1705312860
HeaderDescription
X-RateLimit-LimitMaximum requests per minute
X-RateLimit-RemainingRequests remaining in current window
X-RateLimit-ResetUnix timestamp when the limit resets

When you exceed the limit, you receive a 429 Too Many Requests response:

{
"error": {
"code": "RATE_LIMITED",
"message": "Rate limit exceeded",
"details": {
"limit": 300,
"remaining": 0,
"resetAt": "2024-01-15T10:01:00Z",
"retryAfter": 45
}
}
}
async function callWithRetry(fn: () => Promise<any>, maxRetries = 3) {
for (let attempt = 0; attempt < maxRetries; attempt++) {
try {
return await fn();
} catch (error) {
if (error.code === 'RATE_LIMITED') {
const retryAfter = error.details.retryAfter || 60;
console.log(`Rate limited. Retrying in ${retryAfter}s...`);
await sleep(retryAfter * 1000);
continue;
}
throw error;
}
}
throw new Error('Max retries exceeded');
}
// Usage
const result = await callWithRetry(() =>
lmif.identity.check({ name, imageUrl })
);

Monitor headers to avoid hitting limits:

class RateLimitedClient {
private remaining = Infinity;
private resetAt = 0;
async request(fn: () => Promise<Response>) {
// Wait if we're about to hit the limit
if (this.remaining <= 1 && Date.now() < this.resetAt) {
const waitTime = this.resetAt - Date.now();
await sleep(waitTime);
}
const response = await fn();
// Update from headers
this.remaining = parseInt(response.headers.get('X-RateLimit-Remaining') || '0');
this.resetAt = parseInt(response.headers.get('X-RateLimit-Reset') || '0') * 1000;
return response;
}
}

Some endpoints have additional limits:

EndpointAdditional Limit
POST /identity/check/batch100 items per request
POST /licenses/reportUsage100 reports per minute
POST /webhooks/test10 tests per hour

Instead of multiple single calls:

// Bad: 100 separate requests
for (const avatar of avatars) {
await lmif.identity.check({ name: avatar.name, imageUrl: avatar.imageUrl });
}
// Good: 1 batch request
await lmif.identity.checkBatch(
avatars.map((a) => ({ name: a.name, imageUrl: a.imageUrl }))
);

For high-volume applications:

import PQueue from 'p-queue';
const queue = new PQueue({
concurrency: 10,
interval: 1000,
intervalCap: 5, // Max 5 requests per second
});
async function checkIdentity(name: string, imageUrl: string) {
return queue.add(() => lmif.identity.check({ name, imageUrl }));
}

Cache identity check results:

import NodeCache from 'node-cache';
const cache = new NodeCache({ stdTTL: 3600 }); // 1 hour
async function cachedIdentityCheck(name: string, imageUrl: string) {
const cacheKey = `${name}:${imageUrl}`;
const cached = cache.get(cacheKey);
if (cached) {
return cached;
}
const result = await lmif.identity.check({ name, imageUrl });
cache.set(cacheKey, result);
return result;
}
async function callWithBackoff(fn: () => Promise<any>) {
const maxRetries = 5;
let delay = 1000;
for (let i = 0; i < maxRetries; i++) {
try {
return await fn();
} catch (error) {
if (error.code === 'RATE_LIMITED') {
// Use server's retryAfter if available
const wait = error.details?.retryAfter
? error.details.retryAfter * 1000
: delay;
await sleep(wait);
delay *= 2; // Exponential backoff
continue;
}
throw error;
}
}
throw new Error('Max retries exceeded');
}

Track your usage in the dashboard:

  1. Go to DashboardAPI Usage
  2. View requests per minute/day
  3. Set up alerts for approaching limits

If you need higher limits:

  1. Standard tier: Upgrade from Basic
  2. Enterprise tier: Contact sales for custom limits

Enterprise plans include:

  • Custom rate limits
  • Dedicated infrastructure
  • Priority support

Contact: enterprise@lookmaimfamous.com

The TypeScript SDK handles rate limits automatically:

const lmif = new LMIFClient({
apiKey: process.env.LMIF_API_KEY,
retry: {
maxRetries: 3,
retryDelay: 1000,
},
});
// Automatic retry on rate limit
const result = await lmif.identity.check({ name, imageUrl });

The SDK:

  • Automatically retries rate-limited requests
  • Uses exponential backoff
  • Respects retryAfter header
  • Logs retry attempts (configurable)