Skip to main content

Rate Limits

GhostSpeak API implements per-API-key rate limiting to ensure fair usage and system stability. Rate limits are based on your pricing tier and reset every hour.
Rate Limit Headers: Every API response includes headers showing your current rate limit status. See Rate Limit Headers below.

Pricing Tiers

GhostSpeak offers three B2B API tiers with different rate limits and features:

Starter Plan - $99/month

Perfect for small integrations and MVPs.Rate Limits:
  • 100 requests/hour per API key
  • 2,000 requests/month included
  • $0.05/request overage pricing
Features:
  • ✅ All API endpoints
  • ✅ Bearer token authentication
  • ✅ Up to 3 API keys
  • ✅ Community support (Discord)
  • ❌ No IP whitelisting
  • ❌ No webhook signatures
  • ❌ No SLA guarantee
Best For: Prototypes, personal projects, small startups

Rate Limit Headers

Every API response includes these headers to help you track usage:
X-RateLimit-Limit: 500
X-RateLimit-Remaining: 487
X-RateLimit-Reset: 1735689600
X-RateLimit-Tier: growth
HeaderDescriptionExample
X-RateLimit-LimitMaximum requests per hour for your tier500
X-RateLimit-RemainingRequests remaining in current window487
X-RateLimit-ResetUnix timestamp when limit resets1735689600
X-RateLimit-TierYour current pricing tiergrowth

Parsing Rate Limit Headers

const response = await fetch('https://api.ghostspeak.io/v1/agents/search?query=test', {
  headers: {
    'Authorization': `Bearer ${apiKey}`,
  },
});

const limit = parseInt(response.headers.get('X-RateLimit-Limit'));
const remaining = parseInt(response.headers.get('X-RateLimit-Remaining'));
const resetTimestamp = parseInt(response.headers.get('X-RateLimit-Reset'));
const tier = response.headers.get('X-RateLimit-Tier');

console.log(`${remaining}/${limit} requests remaining`);
console.log(`Resets at: ${new Date(resetTimestamp * 1000).toISOString()}`);

// Warn if approaching limit
if (remaining < limit * 0.1) {
  console.warn(`WARNING: Only ${remaining} requests remaining!`);
}

Rate Limit Exceeded Response

When you exceed your rate limit, the API returns a 429 Too Many Requests response:
{
  "error": {
    "code": "rate_limit_exceeded",
    "message": "API rate limit exceeded. Please wait before making more requests.",
    "statusCode": 429,
    "details": {
      "limit": 500,
      "remaining": 0,
      "resetAt": "2025-12-31T23:00:00Z",
      "retryAfter": 1800
    }
  }
}
Response Headers:
HTTP/1.1 429 Too Many Requests
X-RateLimit-Limit: 500
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1735689600
Retry-After: 1800
Retry-After Header: Always respect the Retry-After header (in seconds) before making additional requests. Ignoring this may result in temporary API key suspension.

Handling Rate Limits

Exponential Backoff

Implement exponential backoff when you hit rate limits:
async function fetchWithRetry(
  url: string,
  apiKey: string,
  maxRetries = 3
): Promise<Response> {
  let retries = 0;

  while (retries < maxRetries) {
    const response = await fetch(url, {
      headers: {
        'Authorization': `Bearer ${apiKey}`,
        'Content-Type': 'application/json',
      },
    });

    // Success
    if (response.ok) {
      return response;
    }

    // Rate limit exceeded
    if (response.status === 429) {
      const retryAfter = parseInt(response.headers.get('Retry-After') || '60');
      const backoffMs = Math.min(retryAfter * 1000, 60000); // Max 60s

      console.warn(`Rate limit hit. Retrying after ${backoffMs}ms...`);
      await new Promise(resolve => setTimeout(resolve, backoffMs));
      retries++;
      continue;
    }

    // Other error
    throw new Error(`API request failed: ${response.status} ${response.statusText}`);
  }

  throw new Error('Max retries exceeded');
}

// Usage
const response = await fetchWithRetry(
  'https://api.ghostspeak.io/v1/agents/search?query=test',
  process.env.GHOSTSPEAK_API_KEY!
);

Request Queuing

For high-volume applications, implement a request queue:
class RateLimitedQueue {
  private queue: Array<() => Promise<any>> = [];
  private processing = false;
  private requestsThisHour = 0;
  private hourlyLimit: number;

  constructor(hourlyLimit: number) {
    this.hourlyLimit = hourlyLimit;
    // Reset counter every hour
    setInterval(() => { this.requestsThisHour = 0; }, 3600000);
  }

  async enqueue<T>(request: () => Promise<T>): Promise<T> {
    return new Promise((resolve, reject) => {
      this.queue.push(async () => {
        try {
          const result = await request();
          resolve(result);
        } catch (error) {
          reject(error);
        }
      });

      this.processQueue();
    });
  }

  private async processQueue() {
    if (this.processing || this.queue.length === 0) return;
    if (this.requestsThisHour >= this.hourlyLimit) {
      console.warn('Hourly limit reached. Waiting for next hour...');
      return;
    }

    this.processing = true;
    const request = this.queue.shift();

    if (request) {
      this.requestsThisHour++;
      await request();
    }

    this.processing = false;
    this.processQueue(); // Process next item
  }
}

// Usage
const queue = new RateLimitedQueue(500); // Growth tier limit

const agent = await queue.enqueue(() =>
  fetch('https://api.ghostspeak.io/v1/agents/agent_123', {
    headers: { 'Authorization': `Bearer ${apiKey}` },
  }).then(r => r.json())
);

Overage Pricing

When you exceed your monthly included requests, overage charges apply automatically:
TierIncluded RequestsOverage Price
Starter2,000/month$0.05/request
Growth10,000/month$0.03/request
Scale50,000/month$0.02/request
EnterpriseCustomNegotiated

Overage Example

Growth Plan ($299/month, 10,000 included requests):
  • Month 1: 12,500 requests
    • Included: 10,000 requests (covered by subscription)
    • Overage: 2,500 requests × 0.03=0.03 = **75.00**
    • Total bill: $374.00
  • Month 2: 8,000 requests
    • Included: 8,000 requests (under limit)
    • Overage: $0.00
    • Total bill: $299.00
Overage Alerts: Set up billing alerts in your dashboard to get notified when you reach 80% and 100% of your included requests.

Monitoring Usage

Track your API usage in the API Usage Dashboard:
# Current Month Stats
Total Requests: 8,247 / 10,000 (82.47%)
Overage: $0.00
Projected End-of-Month: 9,500 requests (within limit)

# By API Key
key_abc123 (Production):    6,120 requests (74.2%)
key_def456 (Staging):       1,890 requests (22.9%)
key_ghi789 (Analytics):       237 requests (2.9%)

Tier Comparison

FeatureStarterGrowthScaleEnterprise
Price$99/mo$299/mo$999/moCustom
Hourly Limit100 req/hr500 req/hr2,000 req/hrCustom
Included Requests2,000/mo10,000/mo50,000/moCustom
Overage Price$0.05/req$0.03/req$0.02/reqNegotiated
API Keys310UnlimitedUnlimited
Webhook Signatures
IP Whitelisting
SLANone99.5%99.9%Custom
SupportDiscordEmail (24h)Email+Slack (4h)24/7 Phone

Upgrading Your Tier

To upgrade your pricing tier:
1

Visit Billing Settings

2

Select New Tier

Choose Starter, Growth, or Scale based on your usage needs
3

Confirm Upgrade

Review pricing and confirm the change
4

Automatic Prorating

Your first bill will be prorated based on remaining days in the billing cycle
Instant Upgrade: Rate limit increases take effect immediately after upgrading. No API key changes required.

Best Practices

Always check X-RateLimit-Remaining and X-RateLimit-Reset headers to avoid hitting limits unexpectedly.
Cache API responses locally to reduce redundant requests:
const cache = new Map<string, { data: any; expiresAt: number }>();

async function cachedFetch(url: string, apiKey: string, ttlMs = 60000) {
  const cached = cache.get(url);
  if (cached && Date.now() < cached.expiresAt) {
    return cached.data;
  }

  const response = await fetch(url, {
    headers: { 'Authorization': `Bearer ${apiKey}` },
  });
  const data = await response.json();

  cache.set(url, { data, expiresAt: Date.now() + ttlMs });
  return data;
}
When querying multiple resources, use bulk endpoints to reduce request count:
  • Instead of: 100 requests to /agents/:id
  • Use: 1 request to /agents/bulk with 100 IDs
Configure alerts at 80%, 90%, and 100% of your monthly limit to avoid unexpected overage charges.

FAQ

You’ll receive a 429 Too Many Requests response. Your rate limit resets at the top of every hour (e.g., 10:00, 11:00, 12:00).
No, rate limits are tied to pricing tiers. However, Enterprise customers can negotiate custom limits. Contact [email protected].
Rate limits apply per API key, not per organization. You can distribute load across multiple API keys within your tier’s key limit.
No, incoming webhook deliveries do not count toward your API rate limit. Only outbound API requests made by your application count.
Contact our sales team at [email protected] for Enterprise pricing with custom volume discounts.

Next Steps


Questions about pricing? Contact [email protected] or schedule a demo at ghostspeak.io/demo