Skip to main content
Skip to Content

Rate Limits

Vantage applies rate limits to ensure fair usage and API stability. Most integrations stay well within these limits.

Limits

Limit TypeValueWindow
Requests100Per minute
Burst20Per second

These limits apply per API key.

Headers

Every response includes rate limit headers:

X-RateLimit-Limit: 100
X-RateLimit-Remaining: 95
X-RateLimit-Reset: 1705312800
HeaderMeaning
X-RateLimit-LimitMax requests per window
X-RateLimit-RemainingRequests left this window
X-RateLimit-ResetUnix timestamp when window resets

Exceeding Limits

When you exceed the limit, you’ll receive:

HTTP/1.1 429 Too Many Requests
Retry-After: 30
{
  "error": {
    "code": "rate_limit_exceeded",
    "message": "Rate limit exceeded. Retry after 30 seconds."
  }
}

Handling Rate Limits

Check Headers

Before each request, check remaining quota:

if (response.headers['x-ratelimit-remaining'] < 10) {
  // Slow down or wait
}

Implement Backoff

When you hit a limit, wait and retry:

async function fetchWithRetry(url, options, retries = 3) {
  for (let i = 0; i < retries; i++) {
    const response = await fetch(url, options);
 
    if (response.status === 429) {
      const retryAfter = response.headers.get('Retry-After') || 30;
      await sleep(retryAfter * 1000);
      continue;
    }
 
    return response;
  }
  throw new Error('Max retries exceeded');
}

Exponential Backoff

For repeated failures:

const delay = Math.min(1000 * Math.pow(2, attempt), 30000);
await sleep(delay);

Best Practices

Batch Operations

Instead of:

// Bad: 100 requests
for (const client of clients) {
  await createClient(client);
}

Use batch endpoints when available:

// Good: 1 request
await createClients(clients);

Cache Responses

Don’t fetch data you already have:

// Cache client data
const clientCache = new Map();
 
async function getClient(id) {
  if (clientCache.has(id)) {
    return clientCache.get(id);
  }
  const client = await fetchClient(id);
  clientCache.set(id, client);
  return client;
}

Use Webhooks

Instead of polling for changes:

// Bad: Poll every minute
setInterval(() => checkForNewInvoices(), 60000);

Subscribe to webhooks:

// Good: Receive push notifications
app.post('/webhooks/vantage', (req, res) => {
  const event = req.body;
  if (event.type === 'invoice.created') {
    handleNewInvoice(event.data);
  }
});

Higher Limits

Need more capacity? Contact us:

Email api@govantage.co with:

Monitoring Usage

Track your API usage in SettingsAPIUsage:

Set up alerts for unusual patterns.

Test vs Live

Test and live keys have the same rate limits. Test freely in development.

Next Steps