Tutorial
Cómo usar gemini-omni-1.2-flash a través de la API de HiAPI: curl y Python
En esta página
Cómo es una solicitud a gemini-omni-1.2-flash
Antes de escribir la primera línea de código, resulta útil entender en qué consiste exactamente una llamada a gemini-omni-1.2-flash en HiAPI. Cada solicitud que envías es un objeto JSON, se entrega a un único endpoint y se autentica con tu clave de API de HiAPI. Esta estructura se mantiene consistente entre modelos, lo que significa que, una vez que la domines para este modelo, podrás reutilizar el mismo patrón en otros lugares.
Desde un punto de vista general, una solicitud contiene cuatro tipos de información:
- Identificador del modelo: la cadena
gemini-omni-1.2-flash, que indica a HiAPI a qué modelo enrutar tu tarea. - Entrada: el contenido que deseas que procese el modelo. Según la modalidad a la que te dirijas, se presenta como un prompt o como campos de entrada estructurados.
- Parámetros de generación: opciones que moldean la salida, como la duración y la resolución. Son los ajustes que irás calibrando a lo largo de esta guía.
- Metadatos de la solicitud: cualquier información que la plataforma necesite para identificar y rastrear tu tarea, como una referencia del lado del cliente que puedes usar para correlacionarla.
Estructura de la respuesta
La respuesta es igual de predecible. Las llamadas síncronas devuelven el resultado directamente en el campo de resultado. Las llamadas asíncronas devuelven un identificador de tarea, un identificador que se usa para consultar el estado y, finalmente, obtener la salida. Saber de antemano cuál de los dos casos tienes delante te ahorra mucho tiempo de depuración posterior.
Por qué importa la estructura
La mayoría de los fallos en la primera integración provienen de la estructura de la solicitud: campos ausentes, tipos de parámetros incorrectos o asumir que la llamada es síncrona cuando no lo es. Si interiorizas esta anatomía antes de escribir código, los ejemplos de curl y Python que siguen serán simples traducciones directas en lugar de conjuros misteriosos.
Un hábito útil: guarda el cuerpo JSON exacto que envías en una variable o en un archivo. Cuando algo falle, querrás ver qué se envió realmente, en lugar de reconstruirlo de memoria.
Autenticación en una línea
Cada solicitud lleva tu clave de API en la cabecera de autorización. Trata la clave como un secreto: cárgala desde una variable de entorno en lugar de codificarla directamente, y nunca la confirmes en el control de versiones. Esta única disciplina evita el error de seguridad más común en las integraciones de API.
Envía tu primera solicitud funcional con curl
La forma más rápida de confirmar que la clave, el endpoint y la estructura de la solicitud son correctos es una llamada con curl. Elimina cada capa de abstracción entre tú y la API, así que si funciona, sabrás que el problema (si lo hay) está en tu código y no en la configuración de tu entorno.
Paso 1: guarda tu clave
Coloca tu clave de API de HiAPI en una variable de entorno para que no aparezca en el historial de tu shell ni en scripts compartidos:
export HIAPI_API_KEY="your_key_here"
Paso 2: construye el cuerpo de la solicitud
Escribe el cuerpo JSON en un archivo. Esto mantiene legible el comando curl y te da un artefacto reutilizable:
cat > request.json <<'EOF'
{
"model": "gemini-omni-1.2-flash",
"input": {
"prompt": "Describe el contenido que deseas que genere el modelo."
},
"parameters": {
"duration": 5,
"resolution": "720p"
}
}
EOF
Los valores concretos de los parámetros dependen de tu caso de uso; lo importante aquí es la estructura. En la primera llamada, mantén duration y resolution moderados para obtener una señal rápida y de bajo coste de que el flujo de trabajo funciona.
Paso 3: envíala
curl -sS -X POST "https://api.hiapi.ai/v1/generate" \
-H "Authorization: Bearer $HIAPI_API_KEY" \
-H "Content-Type: application/json" \
--data @request.json
Paso 4: lee la respuesta
Si la solicitud es síncrona, verás el resultado generado en el cuerpo de la respuesta. Si es asíncrona, recibirás un identificador de tarea: un ID de tarea más un campo de estado. Anota ese ID; lo necesitarás al sondear.
Si tu terminal lo admite, pasa la salida por un formateador JSON o guárdala en un archivo para examinarla con detalle:
curl -sS -X POST "https://api.hiapi.ai/v1/generate" \
-H "Authorization: Bearer $HIAPI_API_KEY" \
-H "Content-Type: application/json" \
--data @request.json > response.json
Paso 5: confirma antes de escalar
No empieces a calibrar la duración, la resolución ni el procesamiento por lotes hasta que esta llamada básica funcione y puedas leer la salida. La primera solicitud exitosa es tu línea base; todo lo que venga después son cambios incrementales que puedes comparar con ella.
Porta la llamada a Python
Una vez que curl funciona, portar a Python es un trabajo mecánico. El objetivo es escribir un cliente pequeño y legible que replique exactamente la solicitud, de modo que, si la llamada en Python falla, puedas comparar campo por campo con la versión de curl.
Un cliente mínimo
import json
import os
import requests
API_KEY = os.environ["HIAPI_API_KEY"]
ENDPOINT = "https://api.hiapi.ai/v1/generate"
payload = {
"model": "gemini-omni-1.2-flash",
"input": {
"prompt": "Describe el contenido que deseas que genere el modelo."
},
"parameters": {
"duration": 5,
"resolution": "720p"
},
}
headers = {
"Authorization": f"Bearer {API_KEY}",
"Content-Type": "application/json",
}
response = requests.post(ENDPOINT, headers=headers, json=payload, timeout=60)
response.raise_for_status()
data = response.json()
print(json.dumps(data, indent=2))
Aspectos a tener en cuenta
json=payloadserializa el diccionario por ti; por eso el cuerpo coincide con el archivo de curl, en lugar de ser una cadena construida a mano.raise_for_status()convierte las respuestas que no son 2xx en excepciones, de modo que los fallos salen a la luz de inmediato en lugar de devolver silenciosamente un cuerpo de error que luego intentas interpretar como resultado.timeout=60evita que el script se quede colgado indefinidamente si la conexión se estanca. Elige un valor en función de cuánto tiempo esperas que tarde la generación.
Maneja las dos estructuras de respuesta
Dado que una llamada puede devolver un resultado o un identificador de tarea, ramifica según la respuesta en lugar de asumir una sola estructura:
if "job_id" in data:
print("Tarea asíncrona iniciada:", data["job_id"])
else:
print("Resultado listo")
Esta pequeña comprobación marca la diferencia entre un cliente que funciona en ambos modos y uno que se rompe en cuanto la plataforma decide por primera vez que tu tarea debe ejecutarse de forma asíncrona.
Envuelve todo en una función
Envuelve la llamada en una función que reciba como parámetros el prompt, la duración y la resolución. Así, cuando empieces a calibrar, ejecutar el mismo código con distintos parámetros será trivial, y la estructura de la solicitud se definirá en un solo lugar.
Tareas asíncronas y sondeo de resultados
Algunas solicitudes a gemini-omni-1.2-flash se completan con la suficiente rapidez como para devolver el resultado en línea. Otras tardan más, y HiAPI devuelve en su lugar un identificador de tarea. Tu integración debe manejar ambos casos, y la ruta asíncrona es precisamente donde fallan la mayoría de los clientes frágiles.
Identifica una respuesta asíncrona
Una respuesta asíncrona contiene un identificador de tarea y un estado. No obtienes la salida ya terminada, sino una promesa: el trabajo ha sido aceptado y será procesado. Tu tarea es volver a consultarlo.
Sondea correctamente
El enfoque ingenuo (golpear el endpoint de estado en un bucle apretado while True) tiene dos desventajas: desperdicia tu presupuesto de límite de frecuencia y genera una carga innecesaria en la plataforma sin conseguir el resultado más rápido.
Un patrón mejor utiliza un retroceso con intervalos acotados:
import time
def poll_job(job_id, base_delay=1.0, max_delay=10.0, max_wait=300.0):
elapsed = 0.0
delay = base_delay
while elapsed < max_wait:
status = get_job_status(job_id)
if status["state"] == "succeeded":
return status
if status["state"] == "failed":
raise RuntimeError(status.get("error", "job failed"))
time.sleep(delay)
elapsed += delay
delay = min(delay * 2, max_delay)
raise TimeoutError(f"job {job_id} did not finish in time")
Tres reglas del sondeo
- Empieza con intervalos cortos y auméntalos despacio. Un intervalo inicial breve captura tareas rápidas con bajo coste; duplicarlo hasta un límite evita consultar las tareas lentas con demasiada frecuencia.
- Establece siempre un tiempo máximo de espera. Sin él, una tarea atascada colgará tu proceso indefinidamente. Un tiempo de espera agotado que lanza una excepción es mucho mejor que un cuelgue silencioso.
- Distingue entre éxito, fallo y pendiente. Solo dos de estos estados deben detener el bucle, y solo uno debe devolver un resultado.
Prefiere los webhooks cuando estén disponibles
Si tu carga de trabajo es intensa, sondear cada tarea no escala bien. Donde HiAPI ofrezca callbacks de finalización, úsalos para recibir los resultados en lugar de preguntar repetidamente. Para herramientas interactivas y scripts de bajo volumen, el sondeo con retroceso es más que suficiente.
En cualquier caso, trata el identificador de tarea como el identificador persistente del trabajo. Guárdalo, regístralo y úsalo más tarde para conciliar los resultados.
Elige la duración y la resolución
La duración y la resolución son los dos parámetros que más influyen directamente en tu salida, y también en tu factura y en el tiempo de espera. Ninguno de los dos tiene un valor único correcto; la elección adecuada depende de lo que estés construyendo. Lo importante es que los elijas de forma consciente, en lugar de copiar los números del ejemplo.
Duración
La duración controla la longitud de la salida generada. Una duración mayor te da más contenido, pero requiere más potencia de cálculo para generarlo, lo que afecta tanto a la latencia como a cómo se factura la solicitud (la facturación se basa en la duración de la salida). Algunas pautas prácticas:
- Empieza corto durante las pruebas. Una duración breve demuestra que el flujo de trabajo funciona de extremo a extremo sin perder tiempo en cada iteración.
- Ajusta la duración al propósito. Un clip corto para una vista previa o una miniatura no necesita la longitud de un entregable completo.
- No alargues de forma especulativa. Genera la longitud que realmente vas a usar; recortar después no te aporta ningún beneficio.
Resolución
La resolución controla la fidelidad de la salida. Una resolución más alta significa más detalle y un mayor tamaño de archivo, con el correspondiente aumento del tiempo de procesamiento y del coste. Las compensaciones a tener en cuenta:
- Vistas previas y trabajo de borrador no necesitan alta resolución: es una comprobación de corrección, no el producto final.
- Los entregables finales pueden merecer un ajuste más alto, especialmente si la salida se muestra a tamaño completo.
- El ancho de banda y el almacenamiento también importan: las salidas de alta resolución son más pesadas de transferir y de conservar.
Ajusta una sola variable a la vez
Al calibrar parámetros, cambia solo uno cada vez y compáralo con tu llamada curl de referencia. Si cambias la duración y la resolución a la vez, no podrás atribuir los cambios de calidad, latencia o coste a ninguno de los dos. Mantén una pequeña matriz que registre los ajustes que has probado y el comportamiento observado.
Razona el coste como una fórmula, no como un número
Como los precios están en el panel de precios del sitio, trata el coste como una función: el coste total escala con la duración de la salida y, para resoluciones más altas, también con el tamaño de la salida final y el volumen de procesamiento. Tu trabajo es saber qué parámetros impulsan esa función y luego consultar los precios actuales antes de comprometerte con un volumen de producción. Así tus estimaciones seguirán siendo correctas aunque los precios cambien.
Errores comunes y cómo solucionarlos
La mayoría de los fallos en la primera integración se pueden agrupar en unas pocas categorías. Revísalas en este orden: cada paso depende de que el anterior sea correcto, así que saltártelos te hará perseguir síntomas superficiales.
1. Estructura de la solicitud
Síntoma: errores de validación, o mensajes sobre campos ausentes o inesperados.
Solución: confirma que el cuerpo es JSON válido (las comas finales son el culpable clásico), confirma que el campo model es exactamente gemini-omni-1.2-flash y compara tu carga línea por línea con el ejemplo de curl que funciona. Si curl funciona y Python no, compara los dos cuerpos de la solicitud.
2. Parámetros
Síntoma: un error que menciona duration o resolution, o un tamaño de salida inesperado.
Solución: comprueba los tipos (números donde deben ser números, cadenas donde deben ser cadenas) y comprueba que los valores estén dentro del rango aceptable. Si un parámetro se ignora silenciosamente, confirma que está anidado donde la API lo espera y no en el nivel superior.
3. Autenticación
Síntoma: respuestas 401 o 403.
Solución: confirma que la clave está presente en la cabecera Authorization con el prefijo Bearer, confirma que la variable de entorno contiene realmente un valor (una cadena vacía se parece mucho a una clave errónea) y confirma que no has copiado espacios en blanco ni comillas alrededor de la clave. Si sospechas que la clave se ha filtrado, vuelve a generarla.
4. Estado de la tarea
Síntoma: sondeas pero nunca ves el éxito, o tratas una tarea pendiente como un fallo.
Solución: confirma que estás sondeando el ID de tarea correcto, que el bucle reconoce todos los estados (pending, running, succeeded, failed) y que el tiempo máximo de espera es lo bastante largo para una tarea realista. Registra cada transición de estado para poder ver dónde se atasca.
5. Límites de frecuencia y fallos transitorios
Síntoma: respuestas 429 o errores 5xx intermitentes.
Solución: reintenta con retroceso y jitter en lugar de reintentar de inmediato. Si estás sondeando muchas tareas, reduce la concurrencia. Los errores transitorios son normales; un cliente con reintentos inteligentes los supera.
Una disciplina de depuración
Cuando algo falle, cambia solo una cosa a la vez y vuelve a ejecutar la solicitud más pequeña posible. Conserva el cuerpo de respuesta original: los mensajes de error suelen nombrar el campo o la condición exactos, y leerlos con atención ahorra más tiempo que cualquier conjetura.
Lista de verificación para la integración en producción
Un script que se ejecuta una vez en tu portátil no es una integración. Antes de lanzarte, cierra estas brechas.
Reintentos con retroceso
Envuelve las llamadas de red en una política de reintentos que gestione fallos transitorios: tiempos de espera agotados, restablecimientos de conexión, respuestas 429 y 5xx. Usa retroceso exponencial con jitter, limita el número de intentos y nunca reintentes solicitudes que fallen la validación; reintentar un cuerpo mal formado solo fallará de nuevo más despacio.
Tiempos de espera en todas partes
Establece tiempos de espera explícitos para cada llamada HTTP. Distingue entre el tiempo de espera de conexión y el de lectura, y asegúrate de que el tiempo de espera de la solicitud de generación sea al menos tan largo como el tiempo real necesario para generar, pero con un límite.
Idempotencia en torno a las tareas
Un fallo de red puede ocurrir entre el momento en que el servidor ya ha aceptado tu solicitud y el momento en que tú ves la respuesta. Si reintentas a ciegas, puedes crear tareas duplicadas. Adjunta a cada solicitud lógica una referencia generada por el cliente, de modo que puedas detectar y reutilizar una tarea existente en lugar de crear una nueva, y guarda el identificador de tarea en un almacenamiento persistente usando esa referencia como clave.
Registros que responden preguntas
Registra para cada solicitud el nombre del modelo, los valores de los parámetros (duración, resolución), el identificador de tarea, las transiciones de estado y la latencia. Nunca registres las claves de API ni el contenido completo de los prompts que pueda contener datos sensibles. Cuando algo falle a las 3 de la madrugada, esos registros son lo que te permite reconstruir exactamente lo que ocurrió.
Observabilidad y alertas
Haz seguimiento de las tasas de éxito tanto de las solicitudes como del ciclo de vida de las tareas, de la distribución de errores por tipo y de la latencia de extremo a extremo. Alerta ante tasas de error sostenidas, no ante fallos puntuales. Un panel que separe los errores de validación de los errores transitorios te dirá de inmediato si tienes un bug o si la red está en mal estado.
Higiene de la configuración
Coloca el endpoint, el nombre del modelo y los parámetros predeterminados en la configuración, en lugar de dispersarlos por todo el código. Carga las claves de API desde un gestor de secretos o una variable de entorno. Si los precios y los límites son relevantes para tu planificación, consulta el panel de precios en lugar de codificar números directamente, porque cambian.
Recorre esta lista y tu integración de gemini-omni-1.2-flash podrá manejar tráfico real, no solo la primera prueba. Empieza con la llamada curl que funciona, porta a Python y construye desde ahí hacia afuera.
Artículos relacionados
Ver todos los artículos →-
Tutorial
Cómo llamar a kimi-k3.1-pro mediante la API de HiAPI: curl, Python y solicitudes listas para ejecutar
Una guía práctica de integración que cubre el endpoint, los parámetros de solicitud, el streaming, las llamadas a herramientas y la resolución de errores
-
Tutorial
API de ElevenLabs Music en HiAPI: genera música con curl, Python y recetas de prompts
Un tutorial práctico para llamar a elevenlabs/music-v2.5 a través de HiAPI, con recetas de prompts listas para copiar para estilo, estado de ánimo y duración
-
Tutorial
Cómo usar gpt-image-2.5-sunburst/image-to-image a través de la API de HiAPI: curl y Python
Solicitudes ejecutables, flujo de carga de la imagen de referencia y diagnóstico de errores para desarrolladores