Rate Limits

Understand API rate limits, how they work, and best practices for staying within your quota. Rate limits help ensure fair usage and API stability for all users.

Rate Limits by Tier

Your API rate limits depend on your subscription tier. Here's a breakdown of the limits:

Tier Requests/Day Requests/Minute Concurrent Scans
Free 1,000 10 1
Pro 10,000 60 5
Business 100,000 300 20
Enterprise Unlimited Custom Unlimited

Need higher limits? Upgrade your plan or contact sales for enterprise options.

How Rate Limiting Works

The MySSL API uses a sliding window rate limiting algorithm. Here's how it works:

Per-Minute Limits

Burst rate limits are calculated using a 60-second sliding window. This prevents sudden bursts from overwhelming the API while allowing flexibility in request timing.

Daily Limits

Daily limits reset at midnight UTC. Your daily counter tracks all API requests across all your API keys combined.

Per-Key Tracking

While daily limits are shared across all keys, per-minute limits are tracked separately for each API key for better isolation.

Scan Concurrency

Concurrent scan limits apply to active scans running at the same time. Completed scans free up capacity for new requests.

Rate Limit Headers

Every API response includes headers to help you track your rate limit status:

Header Description
X-RateLimit-Limit Maximum requests allowed per minute
X-RateLimit-Remaining Number of requests remaining in current window
X-RateLimit-Reset Unix timestamp when the rate limit resets
X-Daily-Limit Maximum daily requests for your tier
X-Daily-Remaining Requests remaining today (resets at midnight UTC)

Example Response Headers

HTTP Response Headers
HTTP/1.1 200 OK
Content-Type: application/json
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 45
X-RateLimit-Reset: 1705071234
X-Daily-Limit: 10000
X-Daily-Remaining: 8523

Handling Rate Limit Errors

When you exceed your rate limit, the API returns a 429 Too Many Requests status code:

429 Response
{
  "error": "Rate limit exceeded",
  "message": "You have exceeded the rate limit. Please wait before making more requests.",
  "retry_after": 45,
  "limit_type": "per_minute"
}

Response Fields

Field Description
retry_after Seconds to wait before retrying
limit_type Which limit was exceeded: per_minute, daily, or concurrent

Retry-After Header

The Retry-After HTTP header is also included with 429 responses. Always respect this value to avoid further throttling.

Best Practices

Implement Exponential Backoff

When you receive a 429 error, use exponential backoff with jitter to retry requests:

Python
import time
import random
import requests

def make_request_with_retry(url, headers, max_retries=5):
    for attempt in range(max_retries):
        response = requests.get(url, headers=headers)

        if response.status_code == 429:
            retry_after = int(response.headers.get('Retry-After', 60))
            # Add jitter to prevent thundering herd
            jitter = random.uniform(0, retry_after * 0.1)
            wait_time = retry_after + jitter
            print(f"Rate limited. Waiting {wait_time:.1f}s...")
            time.sleep(wait_time)
            continue

        return response

    raise Exception("Max retries exceeded")

Monitor Rate Limit Headers

Track your rate limit usage proactively to avoid hitting limits:

JavaScript
async function makeRequest(url) {
    const response = await fetch(url, {
        headers: { 'Authorization': `Bearer ${API_KEY}` }
    });

    // Log rate limit status
    const remaining = response.headers.get('X-RateLimit-Remaining');
    const limit = response.headers.get('X-RateLimit-Limit');
    console.log(`Rate limit: ${remaining}/${limit} remaining`);

    // Slow down if approaching limit
    if (remaining < limit * 0.1) {
        console.warn('Approaching rate limit, slowing down...');
        await sleep(1000);
    }

    return response.json();
}

Batch Requests When Possible

Use pagination parameters to retrieve more data per request:

cURL
# Instead of making 100 requests for 100 domains...
curl "https://myssl.info/api/v1/domains?per_page=100"

# Get all scan results at once
curl "https://myssl.info/api/v1/domains/1/scans?per_page=50"

Cache Responses

Cache API responses when appropriate. SSL scan results don't change frequently, so caching for 5-15 minutes can significantly reduce your API usage. Use the last_scan timestamp to determine if you need fresh data.

Endpoint-Specific Limits

Some endpoints have additional limits due to their resource-intensive nature:

Endpoint Additional Limit Notes
POST /api/v1/scans Concurrent scan limit applies Scans take 30-120 seconds to complete
POST /api/v1/domains 10 domains/minute (Free tier) Higher tiers have higher limits
GET /api/v1/scans/:id/full 5 requests/minute Full scan results are large payloads

Monitoring Your Usage

Track your API usage in real-time from your dashboard:

Today's Requests

1,523

of 10,000

Active Scans

2

of 5 concurrent

Rate Limit Status

Healthy

45/60 remaining

Visit your Dashboard Settings to view detailed usage statistics and set up usage alerts.

Ready to Start Building?

Now that you understand rate limits, explore our API endpoints to start monitoring your SSL certificates.