xYago APIv1

Límites de peticiones

Cada API key tiene un límite de peticiones por minuto. Si lo superas recibes 429 rate_limited y debes esperar los segundos que indica Retry-After.

Límites

Cabeceras

Las peticiones autenticadas que llegan a la comprobación del límite incluyen:

CabeceraSignificado
X-RateLimit-LimitPeticiones permitidas por minuto.
X-RateLimit-RemainingPeticiones que quedan en la ventana actual.
X-RateLimit-ResetMomento (epoch Unix, segundos) en que empieza la siguiente ventana.
Retry-AfterSolo en 429: segundos que hay que esperar.
HTTP/1.1 429 Too Many Requests
Retry-After: 17
X-RateLimit-Limit: 300
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1772463660
X-Request-Id: req_0c1d2e3f4a5b6c7d

{"error": {"code": "rate_limited", "message": "Rate limit exceeded. Retry after the indicated number of seconds."}}

Reintentar correctamente

Python

import random
import time


def request_with_retries(session, method, url, max_attempts=5, **kwargs):
    for attempt in range(1, max_attempts + 1):
        response = session.request(method, url, timeout=30, **kwargs)
        if response.status_code == 429:
            delay = int(response.headers.get("Retry-After", "1"))
        elif response.status_code in (500, 502, 503):
            delay = min(2 ** attempt, 30) + random.random()
        else:
            return response
        if attempt == max_attempts:
            return response
        time.sleep(delay)

JavaScript

const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));

async function fetchWithRetries(url, options = {}, maxAttempts = 5) {
  for (let attempt = 1; ; attempt++) {
    const response = await fetch(url, options);
    let delay;
    if (response.status === 429) delay = Number(response.headers.get("Retry-After") || 1) * 1000;
    else if ([500, 502, 503].includes(response.status)) delay = Math.min(2 ** attempt, 30) * 1000 + Math.random() * 1000;
    else return response;
    if (attempt === maxAttempts) return response;
    await sleep(delay);
  }
}

C#

static async Task<HttpResponseMessage> SendWithRetriesAsync(
    HttpClient http, Func<HttpRequestMessage> build, int maxAttempts = 5)
{
    for (var attempt = 1; ; attempt++)
    {
        var response = await http.SendAsync(build());
        TimeSpan delay;
        if ((int)response.StatusCode == 429)
            delay = response.Headers.RetryAfter?.Delta ?? TimeSpan.FromSeconds(1);
        else if ((int)response.StatusCode is 500 or 502 or 503)
            delay = TimeSpan.FromSeconds(Math.Min(Math.Pow(2, attempt), 30) + Random.Shared.NextDouble());
        else
            return response;
        if (attempt == maxAttempts) return response;
        await Task.Delay(delay);
    }
}

Con Polly (.NET) puedes expresar lo mismo con una política de reintentos que lea Retry-After. No reintentes errores 4xx distintos de 429.

Además del límite por API key, POST /messages y Verify tienen topes propios por remitente y teléfono (ver Mensajes y Verify); también responden 429 rate_limited con Retry-After. Si esos topes no se pueden comprobar, los envíos (POST /messages, POST /verify/start) responden 503 limits_unavailable; POST /verify/check no se bloquea.