NotiGrid

Rate Limits

API request limits and quotas

Rate Limits

NotiGrid enforces rate limits to ensure fair usage and system stability. Understanding these limits helps you build reliable integrations.

Overview

Rate limits restrict:

  • API requests per minute - How many API calls you can make
  • Notifications per hour - How many notifications you can send
  • Concurrent requests - Simultaneous active requests

Current Limits

By Plan

PlanAPI Requests/minNotifications/hourConcurrentBurst
Free1001,0005120
Starter1,00010,000101,200
Pro10,000100,0005012,000
EnterpriseCustomCustomCustomCustom

Rate Limit Headers

Every API response includes rate limit information:

X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 847
X-RateLimit-Reset: 1642435200
X-RateLimit-Resource: notifications

Headers:

  • X-RateLimit-Limit - Maximum requests allowed in window
  • X-RateLimit-Remaining - Requests remaining in current window
  • X-RateLimit-Reset - Unix timestamp when limit resets
  • X-RateLimit-Resource - Resource type being limited

Rate Limit Response

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

{
  "error": {
    "code": "rate_limit_exceeded",
    "message": "API rate limit exceeded",
    "retry_after": 45
  }
}

The Retry-After header indicates seconds until you can retry:

HTTP/1.1 429 Too Many Requests
Retry-After: 45
X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1642435200

Handling Rate Limits

Exponential Backoff

Implement exponential backoff for retries:

async function sendWithRetry(notification, maxRetries = 3) {
  for (let attempt = 0; attempt < maxRetries; attempt++) {
    try {
      return await sendNotification(notification);
    } catch (error) {
      if (error.status === 429) {
        const retryAfter = error.headers['retry-after'] || Math.pow(2, attempt);
        await sleep(retryAfter * 1000);
        continue;
      }
      throw error;
    }
  }
  throw new Error('Max retries exceeded');
}

function sleep(ms) {
  return new Promise(resolve => setTimeout(resolve, ms));
}

Python Example

import time
import requests

def send_with_retry(notification, max_retries=3):
    for attempt in range(max_retries):
        try:
            response = requests.post(
                'https://api.notigrid.com/v1/notifications',
                json=notification,
                headers={'Authorization': f'Bearer {API_KEY}'}
            )
            response.raise_for_status()
            return response.json()
        except requests.exceptions.HTTPError as e:
            if e.response.status_code == 429:
                retry_after = int(e.response.headers.get('Retry-After', 2 ** attempt))
                time.sleep(retry_after)
                continue
            raise
    raise Exception('Max retries exceeded')

Burst Limits

Burst limits allow short-term spikes above your rate limit:

  • Burst window: 10 seconds
  • Burst allowance: 20% above rate limit

Example: If your limit is 1,000/min, you can send up to 1,200 in a 10-second burst.

Concurrency Limits

Maximum simultaneous API requests:

const pLimit = require('p-limit');

// Limit to 10 concurrent requests
const limit = pLimit(10);

const promises = notifications.map(notification =>
  limit(() => sendNotification(notification))
);

await Promise.all(promises);

Per-Resource Limits

Different endpoints have different limits:

Notification Sending

POST /v1/notifications
Rate limit: Based on plan tier

Template Management

GET /v1/templates
Rate limit: 1,000/min (all plans)

POST /v1/templates
Rate limit: 100/min (all plans)

Analytics & Logs

GET /v1/logs
Rate limit: 500/min (all plans)

Best Practices

1. Monitor Rate Limit Headers

Check headers after each request:

function checkRateLimit(response) {
  const remaining = response.headers['x-ratelimit-remaining'];
  const reset = response.headers['x-ratelimit-reset'];

  if (remaining < 10) {
    console.warn(`Rate limit low: ${remaining} requests remaining`);
    // Slow down requests
  }
}

2. Use Batch Operations

Send multiple notifications in one request:

POST /v1/notifications/batch
{
  "notifications": [
    { "to": "user1@example.com", "template": "welcome" },
    { "to": "user2@example.com", "template": "welcome" },
    { "to": "user3@example.com", "template": "welcome" }
  ]
}

Batch endpoints have higher limits (10,000 notifications per request).

3. Implement Queueing

Use a queue to smooth out traffic:

const Queue = require('bull');

const notificationQueue = new Queue('notifications');

// Add to queue
notificationQueue.add({
  to: 'user@example.com',
  template: 'welcome'
});

// Process queue with rate limiting
notificationQueue.process(async (job) => {
  await sendNotification(job.data);
});

4. Cache Responses

Cache frequently accessed data to reduce API calls:

const cache = new Map();

async function getTemplate(name) {
  if (cache.has(name)) {
    return cache.get(name);
  }

  const template = await fetchTemplate(name);
  cache.set(name, template);

  // Expire after 5 minutes
  setTimeout(() => cache.delete(name), 5 * 60 * 1000);

  return template;
}

5. Spread Requests

Distribute requests evenly:

// Bad: Send all at once
for (const user of users) {
  await sendNotification(user);
}

// Good: Space out requests
for (const user of users) {
  await sendNotification(user);
  await sleep(100); // 10 requests/second
}

Monitoring

Dashboard

View real-time rate limit usage:

  1. Go to Dashboard → Analytics
  2. Select API Usage
  3. View current usage and trends

Alerts

Set up alerts for high usage:

  1. Go to Settings → Alerts
  2. Click Add Alert
  3. Configure:
  4. Save

You'll receive an email when approaching limits.

Increasing Limits

Upgrade Plan

Higher plans have higher limits. Compare plans at notigrid.com/pricing.

Request Increase

Contact sales for custom limits:

Temporary Increase

Need a temporary boost for a campaign?

  1. Go to Settings → Billing
  2. Click Request Temporary Increase
  3. Specify:
    • Duration needed
    • Expected traffic
    • Campaign details
  4. Submit request

Approval within 24 hours.

Rate Limit Calculator

Estimate your needs:

Hourly notification volume: 10,000 notifications/hour Notifications per minute: 10,000 / 60 = ~167/min With 20% safety margin: 167 * 1.2 = 200/min Recommended plan: Starter (1,000/min)

Error Handling

Complete error handling example:

class RateLimitError extends Error {
  constructor(retryAfter) {
    super('Rate limit exceeded');
    this.retryAfter = retryAfter;
  }
}

async function sendNotification(data) {
  try {
    const response = await fetch('https://api.notigrid.com/v1/notifications', {
      method: 'POST',
      headers: {
        'Authorization': `Bearer ${API_KEY}`,
        'Content-Type': 'application/json'
      },
      body: JSON.stringify(data)
    });

    if (response.status === 429) {
      const retryAfter = response.headers.get('Retry-After');
      throw new RateLimitError(parseInt(retryAfter));
    }

    if (!response.ok) {
      throw new Error(`HTTP ${response.status}: ${await response.text()}`);
    }

    return await response.json();
  } catch (error) {
    if (error instanceof RateLimitError) {
      console.log(`Rate limited. Retry after ${error.retryAfter}s`);
      await sleep(error.retryAfter * 1000);
      return sendNotification(data); // Retry
    }
    throw error;
  }
}

FAQs

Q: Do rate limits reset at a fixed time? A: No, limits use a sliding window. If you hit the limit at 10:30, it resets at 10:31.

Q: Are failed requests counted against limits? A: Yes, all requests count, including errors.

Q: Can I check my limits programmatically? A: Yes, use GET /v1/account/limits to retrieve current limits and usage.

Q: What happens if I consistently exceed limits? A: Your account may be temporarily restricted. Contact support if you need higher limits.

Q: Are webhook deliveries rate limited? A: No, webhooks you receive are not counted. Only outgoing API requests.

Support

Questions about rate limits?