Rate Limiting

UniMsg implementa rate limiting per garantire stabilità e disponibilità del servizio per tutti gli utenti.

Limiti per Piano

Piano Richieste/Minuto Richieste/Ora Invii/Secondo
Starter 60 1.000 1
Pro 300 10.000 10
Business 1.000 50.000 50
Enterprise Custom Custom Custom

Headers di Rate Limit

Ogni risposta API include headers con informazioni sui limiti:

HTTP/1.1 200 OK
X-RateLimit-Limit: 300
X-RateLimit-Remaining: 298
X-RateLimit-Reset: 1705325660
Header Descrizione
X-RateLimit-Limit Numero massimo di richieste nel periodo
X-RateLimit-Remaining Richieste rimanenti nel periodo corrente
X-RateLimit-Reset Timestamp Unix del reset del contatore

Risposta Rate Limited

Quando superi il limite, riceverai:

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

{
    "success": false,
    "error": {
        "code": "RATE_LIMITED",
        "message": "Rate limit exceeded. Please retry after 45 seconds."
    }
}

Gestione Rate Limiting

Strategia Base

async function makeRequest(endpoint, data) {
    const response = await fetch(endpoint, {
        method: 'POST',
        headers: {
            'Authorization': `Bearer ${token}`,
            'Content-Type': 'application/json'
        },
        body: JSON.stringify(data)
    });

    // Check rate limit headers
    const remaining = response.headers.get('X-RateLimit-Remaining');
    const resetTime = response.headers.get('X-RateLimit-Reset');

    if (response.status === 429) {
        const retryAfter = response.headers.get('Retry-After') || 60;
        console.log(`Rate limited. Retrying after ${retryAfter}s`);
        await sleep(retryAfter * 1000);
        return makeRequest(endpoint, data); // Retry
    }

    // Preemptive slow down if running low
    if (remaining < 10) {
        const waitTime = (resetTime * 1000 - Date.now()) / remaining;
        await sleep(waitTime);
    }

    return response.json();
}

Token Bucket Implementation

class RateLimiter {
    constructor(limit, windowMs) {
        this.limit = limit;
        this.windowMs = windowMs;
        this.tokens = limit;
        this.lastRefill = Date.now();
    }

    async acquire() {
        this.refill();

        if (this.tokens > 0) {
            this.tokens--;
            return true;
        }

        // Wait for next token
        const waitTime = this.windowMs / this.limit;
        await sleep(waitTime);
        return this.acquire();
    }

    refill() {
        const now = Date.now();
        const elapsed = now - this.lastRefill;
        const tokensToAdd = (elapsed / this.windowMs) * this.limit;

        this.tokens = Math.min(this.limit, this.tokens + tokensToAdd);
        this.lastRefill = now;
    }
}

// Usage
const limiter = new RateLimiter(300, 60000); // 300/minute

async function sendMessage(data) {
    await limiter.acquire();
    return api.sms.send(data);
}

Best Practices

Endpoint-Specific Limits

Alcuni endpoint hanno limiti aggiuntivi:

Endpoint Limite Specifico
POST /oauth/token 10/minuto per IP
POST /v1/*/bulk Max 1000 destinatari per richiesta
GET /v1/messages Max 100 risultati per pagina
Enterprise: Contatta il supporto per limiti personalizzati in base alle tue esigenze.