Tutorial
Cómo solucionar los errores de límite de velocidad (429) de HiAPI: causas y solución
Cuando la pasarela de HiAPI devuelve HTTP 429 Too Many Requests, significa que la clave de API que estás usando superó en poco tiempo la frecuencia de solicitudes o el límite de concurrencia permitidos en https://api.hiapi.ai/v1/tasks (o en el endpoint de sondeo GET /v1/tasks/{taskId}). El cuerpo de la respuesta sigue el sobre de error unificado de HiAPI — {"error":{"type":"hiapi_error","code":"...","request_id":"..."}} — junto con un código de estado 429. Resolverlo casi nunca requiere enviar un correo al servicio de atención al cliente, sino añadir en el cliente una pequeña lógica de «reintento + limitación de velocidad». Este artículo explica qué es este error, por qué se activa y los pasos concretos para hacerlo desaparecer.
Aspecto de un 429 de HiAPI
Una solicitud típica a nivel de red se ve más o menos así:
> POST /v1/tasks HTTP/1.1
> Host: api.hiapi.ai
> Authorization: Bearer hi-sk-...
> Content-Type: application/json
< HTTP/1.1 429 Too Many Requests
< Content-Type: application/json
<
{"error":{"type":"hiapi_error","code":"rate_limit_exceeded","request_id":"req_..."}}
Dos puntos clave:
- El código de estado es
429, no401/403.401indica que la clave es incorrecta o falta;429indica que la clave es correcta, pero estás enviando demasiado rápido. No confundas ambos casos. - El cuerpo de la respuesta es un JSON dentro del sobre
hiapi_error. Algunos clientes HTTP solo exponen el código de estado por defecto; si tu código reintenta silenciosamente sin registrar logs, perderás pistas de diagnóstico comorequest_id.
Si llamas a modelos como GPT Image 2, Nano-Banana, flux, Seedance, Wan o HappyHorse, todos se ejecutan en el mismo endpoint de tareas asíncronas, por lo que comparten el mismo cómputo de velocidad por dimensión de clave.
Causas comunes (ordenadas por probabilidad)
Según nuestra experiencia, de mayor a menor, son aproximadamente:
- Fan-out en ráfaga con una sola clave. Recorres un lote de prompts, llamas concurrentemente a
POST /v1/taskspara cada uno y no estableces un límite de concurrencia. Incluso una decena de creaciones de tareas concurrentes bastan para alcanzar el límite en una cuenta nueva. - Sondeo agresivo de
GET /v1/tasks/{taskId}. Un bucle apretado comowhile True: poll(); sleep(0.2)cuenta como volumen de solicitudes igual que la creación de tareas. El sondeo de fracciones de segundo es la causa número uno de «solo creé una tarea y aun así recibo 429». - Límite de concurrencia a nivel de cuenta. Los modelos pesados —vídeo (
seedance-2.0,wan2.7-video/*,happyhorse-1.0) y las variantes de imagen@pro— computan contra límites de tareas concurrentes más estrictos. Enviar muchos de estos a la vez provoca 429 aunque tu frecuencia por minuto no sea alta. - Una clave compartida entre varios entornos. dev, staging y prod usan la misma
HIAPI_API_KEY, por lo que los volúmenes se suman. Cada entorno por separado está bien, pero juntos empujan la clave por encima del límite. - Cuota del plan agotada. La cuota gratuita o un plan de pago casi agotado a veces se manifiesta como 429 en lugar de un error de facturación, especialmente durante promociones.
Sobre los umbrales concretos: el número de solicitudes por minuto y el límite de concurrencia de HiAPI dependen del nivel de tu cuenta; la plataforma no publica una cifra fija. Por eso los valores de concurrencia indicados abajo (5, 3, 2) son puntos de partida empíricos, no límites oficiales; ajústalos según el uso real en el panel.
Pasos de solución
Síguelos en orden. La mayoría de los equipos dejan de recibir alertas al llegar al paso 3.
1. Añadir retroceso exponencial con jitter
Cualquier cliente que se comunique con api.hiapi.ai debe reintentar con un retardo creciente al recibir un 429 — nunca reintentar de inmediato. Una implementación segura por defecto:
import random, time, requests
def post_task_with_backoff(body, key, *, max_retries=5):
delay = 1.0
for attempt in range(max_retries):
r = requests.post(
"https://api.hiapi.ai/v1/tasks",
headers={"Authorization": f"Bearer {key}", "Content-Type": "application/json"},
json=body, timeout=30,
)
if r.status_code != 429:
r.raise_for_status()
return r.json()
retry_after = r.headers.get("Retry-After")
wait = float(retry_after) if retry_after else delay + random.random()
time.sleep(min(wait, 30.0))
delay = min(delay * 2, 30.0)
raise RuntimeError("rate-limited after retries")
Este código hace dos cosas bien: limita el retardo a 30 segundos como máximo; y prioriza el uso del encabezado de respuesta Retry-After cuando existe. Aunque tu respuesta 429 no incluya Retry-After, la estrategia de «límite máximo + jitter» basta para absorber la mayoría de las ráfagas.
2. Limitar la concurrencia del cliente por clave
Añadir un semáforo en el cliente es el cambio individual más eficaz. Si no sabes qué valor elegir, empieza por 5:
import asyncio, httpx
sem = asyncio.Semaphore(5)
async def create_task(client, body):
async with sem:
r = await client.post("https://api.hiapi.ai/v1/tasks", json=body, timeout=30)
return r.json()
Ejecutar 5 tareas simultáneas es holgado para la mayoría de las cuentas. Si aún recibes 429, baja a 3. Los modelos de vídeo pesados suelen requerir un semáforo separado y más bajo (prueba con 2).
3. Pasar del sondeo a callback.url
Para cargas de producción, sondear GET /v1/tasks/{taskId} no es una buena opción por defecto. Pasa callback.url en el cuerpo de la solicitud y HiAPI enviará el resultado por POST cuando la tarea alcance un estado terminal:
{
"model": "Nano-Banana",
"input": { "prompt": "a calm lake at dawn", "aspect_ratio": "16:9" },
"callback": { "url": "https://your-domain.com/hiapi/callback", "when": "final" }
}
Esto reduce el patrón de solicitudes de O(número de tareas × número de sondeos) a O(número de tareas) — normalmente una caída del volumen de llamadas de 10 a 50 veces, y el remedio casi inmediato para los 429 causados por sondeo. Reserva GET /v1/tasks/{taskId} para depuración local y llamadas puntuales de baja frecuencia.
4. Ralentizar el ritmo de sondeo y añadir jitter
Si no puedes usar callbacks (scripts sin conexión, notebooks locales, conciliación de respaldo), no sondees más rápido que cada 2–5 segundos y añade jitter para evitar que varios workers avancen al unísono:
import random, time
time.sleep(2 + random.random() * 3) # 2–5 segundos, con jitter
5. Separar claves por entorno
Genera una clave para cada entorno en la página de claves de API de HiAPI — dev, staging, prod. Las ráfagas de cada entorno quedan aisladas entre sí, y si una clave se filtra, puedes revocarla por separado sin afectar a los demás entornos.
6. Consultar el uso actual
Abre el panel de HiAPI para confirmar si chocaste con el límite de concurrencia o del plan, o si solo fue una ráfaga breve; las cuotas de cada nivel de plan se pueden comparar en la página de precios. Si el uso está muy por debajo del plan y aun así recibes 429, la causa es casi con certeza una ráfaga del lado del cliente, no la cuenta en sí.
Verificación mínima
Con la capa de reintentos lista, una tarea de Nano-Banana es la forma más económica de confirmar si la cadena funciona. Sustituye $HIAPI_API_KEY por tu clave:
curl -s -X POST https://api.hiapi.ai/v1/tasks \
-H "Authorization: Bearer $HIAPI_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "Nano-Banana",
"input": { "prompt": "a single red apple on a white table", "aspect_ratio": "1:1" }
}'
Una respuesta exitosa se ve más o menos así: {"code":200,"data":{"taskId":"tk-hiapi-..."}}. Luego sondea una vez:
curl -s -H "Authorization: Bearer $HIAPI_API_KEY" \
https://api.hiapi.ai/v1/tasks/tk-hiapi-...
El estado pasa por queued → handling → archiving → success, y el data.output[0].url final es tu imagen. Si este único ciclo devuelve 200 pero tus tareas por lotes siguen dando 429, el problema está en la concurrencia del cliente, no en tu clave.
Preguntas frecuentes
¿Por qué recibo 429 si solo envié una solicitud?
Casi siempre es porque el volumen real de solicitudes proviene del bucle de sondeo, no de la creación de tareas. Sondear 5 tareas concurrentes cada 200 ms supone por sí solo 25 solicitudes por segundo. Baja el sondeo a 2–5 segundos o cambia a callback.url.
¿HiAPI siempre incluye el encabezado de respuesta Retry-After?
Trata Retry-After como un valor sugerido: úsalo si está, y si no, recurre al retroceso exponencial (1s, 2s, 4s… con tope de 30s). En cualquier caso, no reintentes sin retardo — eso solo amplifica la ráfaga.
¿Son lo mismo 429 y 401 / 403?
No. 401 / 403 indican fallo de autenticación y usan el mismo sobre hiapi_error, por ejemplo {"error":{"code":"permission_denied","type":"hiapi_error","request_id":"req_..."}} (en pruebas, el message de un 401 indica “This API key is invalid. Check that it is correct...”). Si ves 401/403, verifica el valor de la clave en la página de claves de API — el retroceso no lo soluciona.
¿Puedo subir directamente el límite de velocidad?
Si tu tráfico realmente necesita un límite de concurrencia mayor, primero confirma la cuota del plan en la página de precios y luego contacta con el servicio de atención al cliente desde allí. En la práctica, las soluciones anteriores resuelven más del 90 % de los problemas de 429 sin cambiar ningún límite.
¿Qué diferencia hay entre un 429 en /v1/tasks y un 429 en /v1/tasks/{taskId}?
El endpoint solo te dice qué estabas haciendo en ese momento — ambos comparten el mismo presupuesto de velocidad por dimensión de clave. El 429 del endpoint de creación apunta al fan-out (limita la concurrencia, cambia el procesamiento por lotes); el 429 del endpoint de sondeo apunta al bucle de sondeo apretado (ralentiza el ritmo o cambia a callbacks). Para la estructura completa de solicitud/respuesta, consulta HiAPI Quickstart y la documentación de autenticación.
Resumen
El 429 es una señal normal y recuperable que devuelve cualquier pasarela de API de nivel de producción. Añade retroceso exponencial, limita la concurrencia del cliente, usa callbacks en lugar de sondeo y confirma el uso en el panel. Con estas cuatro cosas bien hechas, puedes dejar de pensar en el 429 por completo. Esta página es la versión en chino simplificado del original en inglés «How to Fix HiAPI Rate Limit (429) Errors», con los detalles técnicos coherentes con el original.
Artículos relacionados
Ver todos los artículos →-
Tutorial
Cómo llamar a hailuo-2.3-fast/image-to-video a través de la API de HiAPI: práctica con curl y Python
La primera solicitud ejecutable del nivel rápido y de bajo coste de imagen a vídeo: del ID del modelo a la descarga del MP4
-
Tutorial
Cómo llamar a hailuo-2.3/text-to-video mediante la API de HiAPI: curl, Python y ejemplos de solicitud ejecutables
-
Tutorial
Uso de Kandinsky 6.0 Pro texto a video en HiAPI: tutorial con curl y Python
Demostración práctica centrada en la solicitud: construir la llamada de prompt a clip de video, enviar la solicitud, sondear el estado de finalización y descargar el resultado