Ver como Markdown

Hyperouter API

Versión v1 · Actualizado el 25 de octubre de 2026

Esta documentación está disponible en Markdown para asistentes de IA. Empieza en /llms.txt, u obtén /llms-full.txt para tener todas las páginas en un solo archivo. Esta página es /docs.md.

Hyperouter es una API HTTP única delante de muchos proveedores de modelos. Envías una solicitud que indica un modelo. Hyperouter elige un proveedor que pueda atenderla, le reenvía la solicitud y cobra de tu saldo el precio de lista de ese proveedor.

BASEhttps://api.hyperouter.app/v1

Todos los endpoints siguen las estructuras de solicitud y respuesta de OpenAI. Los SDK de OpenAI funcionan cuando cambias la URL base y la clave de API. Hyperouter añade algunos campos a los cuerpos de OpenAI. En esta referencia están marcados como añadidos.

EndpointFinalidadAutenticación
GET /v1/modelsEnumera los modelos que tu cuenta puede llamar.Clave de API
POST /v1/chat/completionsChat completion, con streaming opcional.Clave de API
POST /v1/images/generationsDe texto a imagen.Clave de API
POST /v1/images/editsEdita imágenes.Clave de API
POST /v1/videosCrea un vídeo a partir de un prompt, con una imagen opcional.Clave de API
POST /v1/videos/editsEdita o escala un vídeo.Clave de API
POST /v1/videos/extensionsExtiende un vídeo.Clave de API
POST /v1/videos/{id}/remixCrea una nueva versión de un vídeo con un nuevo prompt.Clave de API
GET /v1/videos, GET /v1/videos/{id}, GET /v1/videos/{id}/content, DELETE /v1/videos/{id}Lista, consulta, descarga y elimina vídeos.Clave de API
GET /v1/generations/{id}Consulta el registro de cualquier solicitud: estado, consumo y cargo.Clave de API
GET /v1/creditsTu saldo, lo que retienen las solicitudes abiertas y lo que te queda por gastar (balance_usd, held_usd, available_usd, cadenas decimales en USD).Clave de API

Inicia sesión en dash.hyperouter.app con Google o GitHub para crear una clave de API. GET /v1/models devuelve los modelos que puedes llamar en el momento de la solicitud.

Inicio rápido

  1. Inicia sesión y crea una clave de API. Las claves empiezan por sk-hr-v1- y se muestran una sola vez.
  2. Guárdala en una variable de entorno, por ejemplo HYPEROUTER_API_KEY.
  3. Añade crédito: abre una solicitud de recarga en el panel. El equipo acredita tu saldo cuando se confirma el pago.
  4. Apunta cualquier SDK de OpenAI a la URL base anterior y elige un modelo.
curl https://api.hyperouter.app/v1/chat/completions \
  -H "Authorization: Bearer $HYPEROUTER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "x-ai/grok-4.7",
    "messages": [{"role": "user", "content": "Hello"}]
  }'

Autenticación

Envía tu clave de API como token bearer en cada solicitud.

Authorization: Bearer sk-hr-v1-...

Las claves dan acceso a tu saldo. Guárdalas en tu servidor. Nunca las pongas en código de navegador ni de móvil. Hyperouter guarda solo un hash de cada clave, así que una clave perdida no se puede volver a mostrar: crea una nueva.

En el panel puedes ponerle nombre a cada clave, asignarle un límite de crédito y desactivarla. Una clave desactivada deja de funcionar al instante. Una solicitud que llevaría a una clave más allá de su límite se rechaza con 402 insufficient_credits.

Errores de autenticación

EstadotypecodeCuándomessage
401authentication_errorinvalid_api_keyFalta el encabezado, no es Bearer, o la clave no empieza por sk-hr-v1-.The API key is missing or malformed. Send Authorization: Bearer sk-hr-v1-…
401authentication_errorinvalid_api_keyLa clave es desconocida o está desactivada.The API key is not valid.
403permission_erroraccount_suspendedLa cuenta está suspendida. La comprobación se hace en cada solicitud.This account is suspended. Open a support ticket.
429rate_limit_errortoo_many_auth_failuresMás de 30 solicitudes desde tu dirección en un minuto usaron una clave ausente o no válida. Todas las solicitudes a /v1 desde esa dirección se rechazan durante 15 minutos, incluso con una clave válida. Retry-After indica los segundos restantes.Too many failed API key checks from this address. Try again after the time in Retry-After.
500server_errorinternalHyperouter no pudo comprobar la clave.An internal error occurred. Try again.
curl https://api.hyperouter.app/v1/generations/0194f2c4-7a1e-7b3c-9d02-5f6a1c0e8b21 \
  -H "Authorization: Bearer $HYPEROUTER_API_KEY"
{ "error": { "message": "The API key is not valid.", "type": "authentication_error", "code": "invalid_api_key", "param": null } }

Errores

Todos los errores usan el objeto de error de OpenAI y un estado HTTP correspondiente.

{
  "error": {
    "message": "n must be an integer from 1 to 128",
    "type": "invalid_request_error",
    "code": "invalid_body",
    "param": "n"
  }
}
CampoTipoDescripción
messagestringUna frase que dice qué falla. No la analices programáticamente.
typestringLa clase de error. Consulta la lista siguiente.
codestringUn identificador estable de la causa. Compara por este campo.
paramstring | nullEl campo de la solicitud que causa el error, o null.

Tipos y estados

EstadotypeSignificado
400invalid_request_errorLa solicitud no es válida. code indica la causa y param el campo.
401authentication_errorLa clave de API falta o no es válida.
402insufficient_creditsTu saldo, o el límite de la clave, no cubre lo máximo que podría costar la solicitud.
403permission_errorLa cuenta está suspendida.
404not_foundEl id no existe, pertenece a otra cuenta, o un vídeo ha superado su expires_at.
409conflictEl objeto no está en un estado que permita la llamada (video_not_finished), o hay un conflicto de Idempotency-Key (consulta Reintentos e idempotencia).
422invalid_request_errorLa solicitud era válida, pero su respuesta se rechazó (expansion_refused). No se factura.
429rate_limit_errorTodos los proveedores del modelo están al límite de su capacidad, tu cuenta supera sus límites de velocidad, o han fallado demasiadas comprobaciones de clave de API desde tu dirección. Reintenta después del tiempo indicado en el encabezado Retry-After.
500, 501server_errorHyperouter ha fallado, o el endpoint no está implementado. No se factura.
503upstream_errorUn proveedor falló o no respondió a tiempo: code indica cuál (all_venues_failed, upstream_error o timeout). El encabezado X-Upstream-Status contiene 502 (fallo) o 504 (tiempo agotado).

Hyperouter nunca responde 502 ni 504: te llegarían como una página simple de nuestra red perimetral, sin el cuerpo del error. Donde una pasarela respondería con ellos, recibes 503 con el cuerpo de más arriba y el estado de la pasarela en X-Upstream-Status.

Códigos que puedes recibir

codeEstadoCuándo
invalid_body400Un campo del cuerpo o un parámetro de consulta no se puede analizar, tiene el tipo equivocado o está fuera de sus valores permitidos. param lo nombra.
unsupported_content_type400/v1/images/generations recibió un cuerpo multipart/form-data. Envía JSON. param es null.
request_too_large413Una subida multipart/form-data supera los 50 MiB. Envía los medios grandes como URL https.
unknown_model400El modelo no existe para este endpoint, o ningún proveedor puede atenderlo con tus preferencias de provider.
unsupported_parameter400Un parámetro que existe para otros modelos no está disponible en este modelo. Consulta Parámetros específicos de cada modelo.
invalid_combination400El proveedor no permite estos parámetros juntos, por ejemplo medios de referencia con fotogramas clave.
invalid_size400size no es WIDTHxHEIGHT, o no está permitido para el modelo.
too_many_images400n o el número de imágenes de entrada supera el límite.
invalid_image, invalid_video400La URL de una imagen o un vídeo no es https a un host público: una URL data:, una URL http://, una dirección IP o un nombre interno. param nombra el campo.
image_required400El modelo necesita una imagen de entrada y no enviaste ninguna (o solo edita y llamaste a generations).
invalid_seconds400seconds no está permitido para el modelo, o falta en un vídeo indicado por URL.
unsupported_operation400El modelo no admite la operación (editar, extender o remix, o edición de imágenes).
video_not_ready400El vídeo de origen no ha terminado.
context_length_exceeded400El prompt del chat y max_tokens no caben en el contexto del modelo.
content_rejected400El filtro de seguridad del proveedor rechazó la entrada.
vendor_rejected400El modelo rechazó la solicitud por no ser válida. Revisa sus parámetros y entradas.
clip_too_long400Un clip de referencia más los seconds solicitados superan el límite del modelo (30 s). No se factura.
prompt_rejected400El prompt pide al modelo de expansión del prompt sus instrucciones. No se factura. Consulta Expansión del prompt.
expansion_refused422La reescritura del modelo de expansión del prompt se rechazó o llegó vacía. No se factura. Consulta Expansión del prompt.
invalid_api_key401Consulta Autenticación.
insufficient_credits402Consulta Facturación y límites.
account_suspended403La cuenta está suspendida.
moderation_not_enabled403moderation: "low" no está habilitado para la cuenta. Consulta Moderación.
feature_not_enabled403prompt_expand no está habilitado para la cuenta, en un modelo que lo ofrece. Abre un ticket de soporte para solicitar el acceso. No se retiene nada ni se envía al proveedor. Consulta Expansión del prompt.
model_not_enabled403El modelo requiere que se conceda acceso a tu cuenta. Abre un ticket de soporte para solicitarlo. No se retiene nada ni se envía nada al proveedor.
not_found404El objeto no existe.
video_not_finished409Eliminaste un vídeo que todavía se está creando.
venue_busy429Todos los proveedores del modelo de chat superan su presupuesto de velocidad.
rate_limited429Tu cuenta supera sus solicitudes por minuto o sus solicitudes concurrentes. Consulta Límites de velocidad.
too_many_auth_failures429Más de 30 solicitudes desde tu dirección en un minuto usaron una clave de API no válida. Consulta Límites de velocidad.
all_venues_failed503Ningún proveedor está disponible, o todos han fallado.
upstream_error503Un trabajo de imagen o vídeo falló en el modelo. No se te cobra.
internal, server_error, no_price500Hyperouter ha fallado (no_price: el modelo no se puede valorar ahora). No se factura.
not_implemented501This endpoint is not implemented yet.
invalid_idempotency_key400El encabezado Idempotency-Key supera los 255 caracteres o no es ASCII imprimible. Consulta Reintentos e idempotencia.
idempotency_key_reused409La Idempotency-Key ya se usó con una solicitud distinta.
idempotency_key_in_use409Una solicitud con esta Idempotency-Key todavía se está iniciando. Reintenta con la misma clave.
idempotency_key_replayed409Un chat completion con esta Idempotency-Key ya se ejecutó. error.generation_id es su id.
timeout503Una imagen síncrona no estuvo lista en 90 segundos. Todavía se está creando: error.generation_id es el id que debes consultar.

Reintentos e idempotencia

Un error de red o un tiempo de espera agotado no te dice si Hyperouter recibió la solicitud. Si la vuelves a enviar, puedes iniciar un segundo trabajo y pagar dos veces. Una Idempotency-Key hace segura la repetición: Hyperouter reconoce la repetición, no inicia un segundo trabajo, no hace una segunda retención y responde a partir de la primera solicitud.

Envía una en cada solicitud que cueste dinero. Genera un valor aleatorio nuevo, como un UUID v4, para cada solicitud nueva. Guárdalo junto con la solicitud y envía el mismo valor cada vez que repitas esa solicitud.

Enviar una clave

El encabezado se acepta en estos endpoints:

EndpointUna repetición devuelve
POST /v1/images/generations, POST /v1/images/editsla imagen de la primera solicitud, o su 202 con el mismo id bajo Prefer: respond-async
POST /v1/videos, /v1/videos/edits, /v1/videos/extensions, /v1/videos/{id}/remixel objeto Video de la primera solicitud, tal como está ahora
POST /v1/chat/completions409 idempotency_key_replayed con el id de la primera solicitud (consulta Chat completions)

Los SDK de OpenAI no envían este encabezado por su cuenta. Pásalo como encabezado adicional; los SDK lo reenvían sin cambios en sus reintentos automáticos.

curl https://api.hyperouter.app/v1/images/generations \
  -H "Authorization: Bearer $HYPEROUTER_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: 7c9e6679-7425-40de-944b-e07fc1f90ae7" \
  -d '{"model": "x-ai/grok-imagine-image", "prompt": "A lighthouse at dusk", "n": 1}'

Qué devuelve una repetición

EnvíasHyperouter responde
Una clave nuevaEjecuta la solicitud con normalidad.
La misma clave y la misma solicitud, después de que la primera fuera aceptadaEl resultado de la primera solicitud, como en la tabla anterior. Ni segundo trabajo, ni segunda retención, ni segundo cargo.
La misma clave y la misma solicitud, mientras la primera todavía se está aceptandoEspera a la primera y luego responde como arriba. Si la primera no ha iniciado su trabajo en 60 segundos: 409 idempotency_key_in_use. Reintenta con la misma clave.
La misma clave y una solicitud distinta409 idempotency_key_reused. No se ejecuta nada. Usa una clave nueva.
La misma clave, después de que la primera fuera rechazada antes de iniciar ningún trabajo (un 400, un 402 o un 5xx enviado sin x-should-retry: false)Ejecuta la solicitud como nueva, para que puedas corregirla y volver a enviarla con la misma clave.
La misma clave, más de 30 minutos después de la primera solicitudEjecuta la solicitud como nueva.
Una clave de más de 255 caracteres, o que no sea ASCII imprimible400 invalid_idempotency_key. No se ejecuta nada.

Reglas

Chat completions

Las respuestas de chat no se reproducen. Una repetición con la misma clave responde 409 con el código idempotency_key_replayed, y error.generation_id es el id de la primera solicitud. La solicitud no se vuelve a ejecutar ni a facturar. Consulta la primera solicitud con GET /v1/generations/{id} para ver su estado, consumo y coste. Si el primer chat completion falló y no se facturó, su clave queda libre y una repetición se ejecuta como solicitud nueva.

{
  "error": {
    "message": "A request with this Idempotency-Key already ran as generation 019a1f3c-5b7e-7d21-9c4a-2e8f6b0d3a17. Chat replies are not replayed: GET /v1/generations/019a1f3c-5b7e-7d21-9c4a-2e8f6b0d3a17 for its record.",
    "type": "conflict",
    "code": "idempotency_key_replayed",
    "param": null,
    "generation_id": "019a1f3c-5b7e-7d21-9c4a-2e8f6b0d3a17"
  }
}

Reintentos automáticos en los SDK de OpenAI

Los SDK de OpenAI reintentan dos veces, por defecto, una respuesta 408, 409, 429 o 5xx, salvo que la respuesta incluya el encabezado x-should-retry: false. Hyperouter envía x-should-retry: false en toda respuesta en la que un reintento iniciaría un segundo trabajo o un segundo cargo:

Nunca lo envía en un 429, en un 409 idempotency_key_in_use ni en un 5xx anterior a que exista cualquier trabajo. Esos son seguros de reintentar. Con una Idempotency-Key, todos los reintentos son seguros.

Modelos

GET/v1/models

Enumera todos los modelos que tu cuenta puede llamar ahora mismo, con sus precios y lo que admiten. Un modelo sin un proveedor habilitado no aparece. Algunos modelos requieren que se conceda acceso a tu cuenta: aparecen una vez concedido. Este endpoint necesita una clave de API y enumera los modelos que puede llamar la cuenta de esa clave. La respuesta puede almacenarse en caché durante 60 segundos, solo por tu cliente.

Parámetros

Ninguno.

Respuesta

{
  "data": [{
    "id": "x-ai/grok-4.7",
    "name": "Grok 4.7",
    "kind": "chat",
    "context_length": 500000,
    "architecture": { "input_modalities": ["text", "image"], "output_modalities": ["text"] },
    "pricing": {
      "prompt": "0.000002", "completion": "0.000006", "input_cache_read": "0.0000005",
      "request": "0", "image": "0", "video_second": "0"
    },
    "top_provider": { "context_length": 500000, "max_completion_tokens": 32768 },
    "response_modes": ["sync", "stream"],
    "supported_parameters": ["max_tokens", "temperature", "top_p", "stop", "stream", "tools", "tool_choice", "response_format", "seed", "frequency_penalty", "presence_penalty"],
    "extra_parameters": {}
  }]
}
CampoTipoDescripción
idstringEl id del modelo, <provider>/<name>, por ejemplo x-ai/grok-4.7 o qwen/qwen-image-2.0. Envíalo como model. Un modelo renombrado sigue respondiendo a su id anterior.
response_modesstring[]Cómo responde el modelo: sync (una respuesta retenida), async (envía Prefer: respond-async, recibe 202 y consulta periódicamente) y stream ("stream": true). Un modelo que solo lista async necesita el encabezado Prefer, y stream solo funciona donde aparece listado. El vídeo es siempre asíncrono a través de la API de vídeos, con o sin el encabezado.
namestringNombre para mostrar.
kindstringchat, image o video.
context_lengthintegerVentana de contexto en tokens. 0 para modelos de imagen y vídeo.
architectureobjectinput_modalities y output_modalities. La salida es ["text"], ["image"] o ["video"].
pricingobject of stringsUSD por unidad, como cadenas decimales, en el nivel base: prompt y completion (por token), input_cache_read (por token en caché), request, image (por imagen), video_second (por segundo de vídeo). Un vídeo con precio según la resolución muestra el precio más bajo. Una unidad que no se aplica es "0".
top_providerobjectcontext_length y max_completion_tokens.
supported_parametersstring[]En chat, los parámetros de OpenAI que admite el modelo. En imagen y vídeo, las funciones compartidas que admite (resolution, ratio, audio, seed, negative_prompt, first_frame, last_frame, reference_images, reference_videos, prompt_extend).
operationsstring[]Solo en modelos de vídeo: edit, extend y remix, para cada una que el modelo admita. Ausente cuando el modelo no admite ninguna.
extra_parametersobjectLos campos de primer nivel específicos del modelo, por nombre. Cada uno tiene type, values (valores permitidos; vacío significa cualquiera), price_condition (el campo cambia el precio) y description. Consulta Parámetros específicos de cada modelo.
curl https://api.hyperouter.app/v1/models \
  -H "Authorization: Bearer $HYPEROUTER_API_KEY"

Errores

Ninguno específico de este endpoint.

Modelos de chat

Precios por 1 M de tokens: entrada / entrada en caché / salida.

ModeloContextoPrecio
x-ai/grok-4.7500K$2.00 / $0.50 / $6.00
x-ai/grok-4.6500K$2.00 / $0.50 / $6.00
x-ai/grok-4.5500K$2.00 / $0.30 / $6.00
x-ai/grok-4.31M$1.25 / $0.20 / $2.50
x-ai/grok-build-0.1256K$1.00 / $0.20 / $2.00
deepseek/deepseek-v4.1-flash1M$0.15 / $0.003 / $0.60
deepseek/deepseek-v4.1-flash-10171M$0.15 / $0.003 / $0.60
openai/gpt-6-astra272K$10.00 / $1.00 / $50.00
openai/gpt-6.1-sol272K$2.00 / $0.10 / $10.00
z-ai/glm-5.31M$1.40 / $0.26 / $4.40
lumina/face-detect4K$0.0013 por solicitud

En los modelos x-ai/, una solicitud con 200 000 tokens de prompt o más se factura por completo con las tarifas de contexto largo, que son el doble de las anteriores. Los modelos deepseek/ tienen una única tarifa para cualquier longitud de prompt, razonan antes de responder por defecto (reasoning_effort: "none" lo desactiva) y cuentan su razonamiento dentro de max_tokens, con un máximo de 384 000. z-ai/glm-5.3 siempre razona: reasoning_effort es low, high o max, y none se rechaza. Los modelos openai/ también razonan y aceptan prompts de 272 000 tokens como máximo.

Chat completions

POST/v1/chat/completions

Crea la respuesta de un modelo a una conversación. El cuerpo es la solicitud de Chat Completions de OpenAI. Hyperouter añade models, provider y moderation.

Parámetros

NombreTipoObligatorioValores permitidosPor defectoDescripción
modelstringSíUn id de modelo de chat de GET /v1/modelsEl modelo que se usará, por ejemplo x-ai/grok-4.7.
messagesobject[]SíNo vacío. Roles system, user, assistant, toolLa conversación hasta ahora. Se aceptan imágenes (partes image_url) cuando el modelo admite imágenes.
modelsstring[]NoComo máximo 5 ids de modeloAñadido. Modelos de reserva, probados en orden después de que fallen todos los proveedores de model.
providerobjectNoVer más abajoAñadido. Preferencias de enrutamiento.
moderationstringNoauto, lowautoAñadido. Consulta Moderación.
streambooleanNofalseDevuelve eventos enviados por el servidor.
stream_optionsobjectNo{"include_usage": true}Con include_usage, el stream termina con un fragmento que incluye usage.
max_tokens, max_completion_tokensintegerNo1 o másEl máximo de salida del modeloLímite superior de tokens generados. También fija lo máximo que puede costar una solicitud, que Hyperouter retiene antes de la llamada (consulta Facturación).
nintegerNoDe 1 a 1281Número de opciones.
temperature, top_p, seed, frequency_penalty, presence_penalty, logit_biasnumber / integer / objectNoComo en OpenAIControles de muestreo, pasados al proveedor.
stopstring | string[]NoSecuencias que terminan la generación.
tools, tool_choice, parallel_tool_callsobject[], string | object, booleanNoFormato de function calling de OpenAIFunction calling. Solo herramientas de tipo function: cualquier otro tipo se rechaza con 400 unsupported_parameter.
response_formatobjectNo{"type":"json_object"} o un esquema JSONSalida estructurada.
reasoning_effort, logprobs, top_logprobs, usercomo en OpenAINoSe pasan al proveedor cuando el modelo los admite.

Los demás campos se ignoran. supported_parameters de cada modelo en GET /v1/models enumera exactamente lo que admite. Grok 4.20 y posteriores ignoran logprobs y top_logprobs, por lo que no aparecen en la lista.

El objeto provider

Por defecto, Hyperouter envía cada solicitud de chat al proveedor disponible con el precio más bajo para ese modelo, y desempata por el menor tiempo reciente hasta el primer token. Un proveedor que falla repetidamente se omite hasta que se recupera. El objeto provider sigue la estructura de solicitud de OpenRouter.

NombreTipoObligatorioValores permitidosPor defectoDescripción
sortstringNoprice, latency, throughputpriceCómo ordenar los proveedores.
orderstring[]NoNombres de proveedoresProveedores que se probarán primero, en orden, por ejemplo ["xai"]. El nombre de un proveedor es su nombre público en cualquier capitalización (xAI, Qwen) o la primera parte de sus ids de modelo (x-ai, qwen).
onlystring[]NoNombres de proveedoresEnruta solo a estos proveedores.
ignorestring[]NoNombres de proveedoresNo enruta nunca a estos proveedores.

Respuesta

El chat completion de OpenAI. El id es el id de la solicitud: consúltalo con GET /v1/generations/{id}. Hyperouter añade provider (el nombre público del proveedor que atendió la solicitud, por ejemplo xAI) y usage.cost (el cargo, en USD, como número JSON).

{
  "id": "0194f2c4-7a1e-7b3c-9d02-5f6a1c0e8b21",
  "object": "chat.completion",
  "model": "x-ai/grok-4.7",
  "provider": "xAI",
  "choices": [{
    "index": 0,
    "message": { "role": "assistant", "content": "Hello! How can I help?" },
    "finish_reason": "stop"
  }],
  "usage": {
    "prompt_tokens": 9,
    "completion_tokens": 8,
    "total_tokens": 17,
    "prompt_tokens_details": { "cached_tokens": 0 },
    "cost": 0.000066
  }
}

Un modelo de reescritura de prompts responde con una opción, un usage de cero tokens y un cost fijo por solicitud.

Streaming

Con "stream": true la respuesta es un flujo de eventos enviados por el servidor en el formato de fragmentos de OpenAI. Termina con data: [DONE]. Cuando defines stream_options.include_usage, el último fragmento antes de [DONE] tiene un array choices vacío y un objeto usage que incluye cost, además de un campo provider. El consumo siempre se registra para la facturación, pidas o no el fragmento.

Hasta que llega el primer token, el stream envía la línea de comentario : processing cada 15 segundos para mantener abierta la conexión. Los clientes SSE ignoran los comentarios.

La conmutación a otro proveedor solo ocurre antes de enviar el primer token. Si un proveedor falla a mitad del stream, este termina con data: {"error": {...}} seguido de data: [DONE], y se te facturan los tokens ya producidos.

Se te facturan los tokens que produce el proveedor, los leas o no. Un stream que abortas, o una respuesta que dejas de esperar, no se detiene en el proveedor, que continúa y factura toda su respuesta: Hyperouter la lee hasta el final (durante 5 minutos más como máximo) y factura eso.

Un proveedor que ha aceptado una solicitud puede estar ejecutándola. Si luego deja de responder (5 minutos sin ningún token en un stream, o más de lo que tarda una respuesta de max_tokens) o su respuesta se corta antes del primer token, la solicitud no se envía a otro proveedor: responde 503 con el código timeout o upstream_error con error.generation_id, y se factura según su retención, con usage_estimated: true en su registro.

Ejemplo

curl https://api.hyperouter.app/v1/chat/completions \
  -H "Authorization: Bearer $HYPEROUTER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "x-ai/grok-4.7",
    "models": ["x-ai/grok-4.6"],
    "provider": { "sort": "latency" },
    "messages": [{ "role": "user", "content": "Hello" }]
  }'

Errores

EstadotypecodeparamCuándo
400invalid_request_errorinvalid_bodyel campoEl cuerpo no es JSON válido o supera los 32 MiB; falta model; models tiene más de 5 entradas; n está fuera del rango de 1 a 128; max_tokens no es positivo; provider.sort no está permitido; moderation no es auto ni low (moderation must be auto or low.); messages está vacío. También cuando todos los proveedores rechazaron la solicitud por no ser válida.
400invalid_request_errorunknown_modelmodel o modelsEl modelo no es un modelo de chat, o no tiene un proveedor habilitado.
400invalid_request_errorunsupported_parametertools, response_format, messages o max_tokensEl modelo no admite herramientas, un formato de respuesta ni imágenes; una herramienta no es de tipo function; o ningún proveedor del modelo puede acotar su salida.
400invalid_request_errorcontext_length_exceededmessagesEl prompt y max_tokens superan el contexto del modelo.
402insufficient_creditsinsufficient_creditsmax_tokensEl saldo o el límite de la clave no cubre lo máximo que podría costar la solicitud. El mensaje indica cuántos tokens puedes permitirte.
429rate_limit_errorvenue_busyTodos los proveedores del modelo superan su presupuesto de velocidad.
429rate_limit_errorrate_limitedTu cuenta supera sus solicitudes por minuto o sus solicitudes concurrentes (consulta Límites de velocidad). No se retiene ni se reenvía nada.
409conflictidempotency_key_replayed, idempotency_key_reused, idempotency_key_in_useConsulta Reintentos e idempotencia.
503upstream_errorall_venues_failedNingún proveedor está disponible, o todos han fallado. No se factura.
503upstream_errorupstream_errorEl proveedor aceptó la solicitud y su respuesta se cortó antes del primer token. Se factura según la retención (consulta Streaming).
503upstream_errortimeoutEl proveedor aceptó la solicitud y no la terminó a tiempo. Se factura según la retención (consulta Streaming).
401, 403, 500Consulta Autenticación.

Imágenes

POST/v1/images/generations
POST/v1/images/edits

Ambos siguen la API de imágenes de OpenAI y aceptan un cuerpo JSON. /v1/images/edits acepta la forma JSON de OpenAI: las imágenes son images, de 1 a 5 URL https. El images.edit de los SDK de OpenAI envía los archivos de imagen como multipart/form-data, y eso también funciona: el edge de Hyperouter guarda cada archivo (PNG, JPEG o WebP, 20 MiB cada uno, 50 MiB por solicitud) durante 3 días en una URL https://api.hyperouter.app/u/... imposible de adivinar que el proveedor descarga, y luego ejecuta la solicitud como JSON. Un archivo de vídeo se rechaza (400 invalid_video): envía un vídeo como URL https. Ambos aceptan las funciones compartidas que siguen y cualquier parámetro específico del modelo como campos de primer nivel.

Parámetros

NombreTipoObligatorioValores permitidosPor defectoDescripción
modelstringSíUn id de modelo de imagenEl modelo que se usará.
promptstringGenerations: sí. Edits: según lo que necesite el modeloTexto no vacíoQué crear.
imagesobject[]Edits: síDe 1 a 5 objetos {"image_url": "https://..."}, tantos como admita el modelo. Cada URL es https a un host público, nunca una URL data:, una dirección IP ni un nombre interno. No se acepta file_id.Las imágenes que se editarán. Cada URL se pasa al proveedor tal cual, por lo que el proveedor debe poder descargarla; si no puede descargarla o leerla, el trabajo falla con vendor_rejected y no se cobra nada. Un modelo que las acepta en un orden determinado lo indica en sus notas de la referencia de modelos.
nintegerNoDe 1 a 10, y como máximo el límite del modelo1Número de imágenes.
sizestringNoWIDTHxHEIGHT, por ejemplo 1024x1024; el modelo puede permitir menos tamaños1024x1024Tamaño de salida.
qualitystringNoSegún lo que permita el modeloSe pasa al modelo.
response_formatstringNourlurlCómo se devuelve la imagen: siempre como URL. b64_json se rechaza con 400 unsupported_parameter.
seedintegerNoSi el modelo lista seedSemilla para una salida repetible.
negative_promptstringNoSi el modelo lo listaQué evitar.
prompt_extendbooleanNoSi el modelo lo listaDesactivado salvo que lo pidasPermite que el modelo amplíe el prompt.
prompt_expandbooleanNoSi el modelo lo listafalseAñadido. Hyperouter reescribe el prompt para el modelo antes de generar. Consulta Expansión del prompt.
prompt_expand_modelstringNoEl slug de un modelo de chat que tu cuenta puede llamarx-ai/grok-4.6Añadido. Con prompt_expand: el modelo que escribe la reescritura. Sin prompt_expand: true es 400 invalid_body. Consulta Expansión del prompt.
localestringNoUna etiqueta BCP 47, por ejemplo zh-CNInglésAñadido. Con prompt_expand: el idioma de los diálogos, si el modelo lo habla.
ratiostringNoSi el modelo lo listaRelación de aspecto.
resolutionstringNo480p, 720p, 1080p, 2K, 4K, según lo que permita el modeloResolución de salida.
modelsstring[]NoIds de modelos de imagenAñadido. Modelos de reserva.
providerobjectNoonly, ignore, order (arrays de nombres de proveedores)Añadido. Preferencias de enrutamiento.
moderationstringNoauto, lowautoAñadido. Consulta Moderación.
campos específicos del modelosegún se declareSegún se declareSegún se declareConsulta Parámetros específicos de cada modelo.

Una función compartida que el modelo no lista, como seed en un modelo que no la tiene, se rechaza con 400 unsupported_parameter. Nunca se descarta en silencio, porque cambiaría la salida y el precio.

Respuesta

{
  "created": 1730000000,
  "data": [{ "url": "https://..." }],
  "usage": { "cost": 0.02 },
  "id": "0194f2c4-7a1e-7b3c-9d02-5f6a1c0e8b21"
}
CampoTipoDescripción
createdintegerHora Unix de la solicitud.
data[].urlstringCon response_format: "url": un enlace firmado, válido durante 24 horas. GET /v1/generations/{id} firma uno nuevo.
usage.costnumberEl cargo en USD, como número JSON.
idstringEl id de la solicitud. Úsalo con GET /v1/generations/{id}.
expanded_promptstring | nullAñadido. Con prompt_expand: el prompt con el que se generó. null si no se reescribió nada.

Hyperouter almacena cada resultado durante 30 días, de modo que un enlace nunca apunta a un proveedor. Pasados los 30 días el registro permanece, pero su outputs queda vacío.

Esperar el resultado

Ejemplos

curl https://api.hyperouter.app/v1/images/generations \
  -H "Authorization: Bearer $HYPEROUTER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"model": "x-ai/grok-imagine-image", "prompt": "A lighthouse at dusk", "n": 1}'
curl https://api.hyperouter.app/v1/images/edits \
  -H "Authorization: Bearer $HYPEROUTER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"model": "x-ai/grok-imagine-image", "prompt": "make it night",
       "images": [{"image_url": "https://example.com/photo.png"}]}'

Errores

EstadocodeparamCuándo
400unsupported_content_typeEl cuerpo es multipart/form-data: Send a JSON body; pictures and videos are https URLs.
400invalid_bodyel campoEl cuerpo no es JSON válido; images no es un array de objetos con image_url; falta prompt en generations; n es menor que 1; response_format no es url (response_format must be url.; b64_json es unsupported_parameter); resolution no está permitida; un campo tipado tiene el tipo equivocado; moderation no es auto ni low.
400unknown_modelmodelEl modelo no existe para imágenes, o ningún proveedor coincide con tus preferencias de provider.
400invalid_sizesizesize no tiene la forma 1024x1024, o el modelo no la permite.
400too_many_imagesn o imagesn supera 10 o el límite del modelo; más de 5 imágenes; más imágenes de las que admite el modelo.
400image_requiredimagesUna edición tiene menos imágenes de las que necesita el modelo, o llamaste a generations en un modelo que solo edita (usa /v1/images/edits).
400unsupported_operationimagesEl modelo no edita imágenes.
400unsupported_parameterel campoEl modelo no admite el campo; images[i].file_id.
400invalid_combinationel campoEl proveedor no permite estos campos juntos.
400async_requiredEl modelo solo responde de forma asíncrona: envía Prefer: respond-async.
400unsupported_parameterstream"stream": true en un modelo cuyos response_modes no incluyen stream.
400invalid_imageimages[i].image_urlLa URL no es https a un host público: images[i].image_url must be an https URL. para una URL data: o http://.
400content_rejectedEl filtro de seguridad del proveedor rechazó la entrada: The request was rejected by a content safety filter.
400vendor_rejectedThe request was refused by the model. Check its parameters and inputs.
400invalid_idempotency_keyConsulta Reintentos e idempotencia.
402insufficient_creditsEl saldo o el límite de la clave no cubre lo máximo que podría costar la solicitud.
409idempotency_key_reused, idempotency_key_in_useConsulta Reintentos e idempotencia.
429rate_limit_errorTodos los proveedores están al límite de su capacidad (sin code), o tu cuenta supera sus solicitudes por minuto o sus solicitudes concurrentes (code: rate_limited, consulta Límites de velocidad).
503upstream_errorThe model failed to produce a result. You were not charged.
503provider_busyEl proveedor siguió al límite de su capacidad durante unos dos minutos y no aceptó el trabajo. Reintenta más tarde. No se te cobró.
500server_error, no_priceHyperouter ha fallado, o el modelo no se puede valorar ahora. Un 500 después de crear la imagen lleva x-should-retry: false.
503timeoutLa imagen no estuvo lista en 90 segundos. Todavía se está creando: error.generation_id es el id que debes consultar. Lleva x-should-retry: false.

El mensaje de un trabajo fallido termina con el motivo del propio proveedor, si lo dio, tras Provider:, para distinguir un prompt rechazado, un proveedor saturado y una caída. Las URL que contenga se sustituyen por <url>.

Modelos de imagen

ModeloFunciónPrecio
x-ai/grok-imagine-imageGenera y edita. Hasta 10 imágenes, hasta 5 imágenes de entrada.$0.02 por imagen
x-ai/grok-imagine-image-2.0Genera y edita, igual que el anterior.Desde $0.04 por imagen
qwen/qwen-image-2.0Genera y edita (de 1 a 3 imágenes de entrada). n de 1 a 6.$0.035 por imagen
bytedance/seedream-5.0-flashGenera y edita (de 1 a 10 imágenes de entrada). Una imagen 2K por solicitud, sin marca de agua.$0.018 por imagen
bytedance/seedream-5.0-liteGenera y edita, como el anterior.$0.035 por imagen

Algunos modelos requieren que se conceda acceso a tu cuenta. La referencia de modelos del panel enumera todos los modelos que tu cuenta puede llamar, con sus parámetros, precios y notas.

Vídeos

El vídeo sigue la API de vídeos de OpenAI. Un vídeo es un trabajo. Una llamada de creación, edición, extensión o remix responde 200 de inmediato con el objeto Video en estado queued. Consultas GET /v1/videos/{id} hasta que el estado sea completed, o recibes un webhook. Prefer no cambia nada aquí: los vídeos son siempre asíncronos.

EndpointFunción
POST /v1/videosCrea un vídeo a partir de un prompt, con un input_reference opcional.
POST /v1/videos/editsEdita o escala un vídeo completado. Solo modelos que listan edit en operations.
POST /v1/videos/extensionsExtiende un vídeo completado. Solo modelos que listan extend.
POST /v1/videos/{id}/remixNuevo prompt sobre un vídeo completado, con el mismo modelo. Solo modelos que listan remix.
GET /v1/videosLista tus vídeos.
GET /v1/videos/{id}El objeto Video.
GET /v1/videos/{id}/contentEl MP4 o la miniatura.
DELETE /v1/videos/{id}Elimina un vídeo.

Crear un vídeo

POST/v1/videos

El cuerpo es JSON, en todos los endpoints de vídeo; el videos.create de los SDK de OpenAI con un archivo de imagen input_reference también se acepta, y el archivo se trata como en las ediciones de imágenes. Toda imagen y todo vídeo es una URL https a un host público, que se pasa al proveedor tal cual: el proveedor debe poder descargarla, y si no puede descargarla o leerla, el vídeo falla con vendor_rejected y no se cobra nada. Una URL data:, una URL http://, una dirección IP o un nombre interno se rechaza con 400 invalid_image o 400 invalid_video. Un cuerpo multipart/form-data se rechaza con 400 unsupported_content_type.

NombreTipoObligatorioValores permitidosPor defectoDescripción
modelstringSíUn id de modelo de vídeoEl modelo que se usará.
promptstringSíTexto no vacíoQué crear.
secondsstring | integerNoSegún lo que permita el modeloEl primer valor permitido del modelo; si no, 4 s (o el máximo del modelo si es menor)Duración del vídeo. "8" y 8 son lo mismo.
sizestringNoWIDTHxHEIGHTLa altura determina la resolución salvo que envíes resolution: hasta 480 es 480p, hasta 720 es 720p, hasta 1080 es 1080p, hasta 1440 es 2K, por encima es 4K. El modelo debe permitir esa resolución.
input_referenceobjectSi el modelo necesita una imagen{"image_url": "https://..."}, una URL httpsLa primera imagen del vídeo. No se acepta file_id.
resolutionstringNo480p, 720p, 1080p, 2K, 4K, según lo que permita el modeloLa primera resolución del modeloResolución de salida. Cambia el precio.
ratiostringNoSi el modelo lo listaRelación de aspecto.
audiobooleanNoSi el modelo genera sonidofalseGenera sonido.
seedintegerNoSi el modelo lo listaSemilla para una salida repetible.
negative_promptstringNoSi el modelo lo listaQué evitar.
prompt_extendbooleanNoSi el modelo lo listaDesactivado salvo que lo pidasPermite que el modelo amplíe el prompt.
prompt_expand, localeboolean, stringNoComo en imágenesfalseAñadido. Consulta Expansión del prompt.
prompt_expand_modelstringNoComo en imágenesx-ai/grok-4.6Añadido. Con prompt_expand: el modelo que escribe la reescritura. Consulta Expansión del prompt.
first_frame, last_framestringNoUna URL https de una imagenFotogramas clave.
reference_images, reference_videosstring[]NoURL httpsMedios de referencia. No se pueden combinar con fotogramas clave, según lo establece el proveedor.
models, providerstring[], objectNoComo en imágenesAñadido. Modelos de reserva y preferencias de enrutamiento.
moderationstringNoauto, lowautoAñadido. Consulta Moderación.
campos específicos del modelosegún se declareSegún se declareSegún se declareConsulta Parámetros específicos de cada modelo.

Editar, extender y remix

EndpointCuerpo (JSON)
POST /v1/videos/editsmodel, video (obligatorio), prompt, resolution y las funciones compartidas. video es {"id": "<your video id>"} (un vídeo tuyo completado) o {"url": "https://..."}. model toma por defecto el modelo del vídeo de origen cuando envías un id.
POST /v1/videos/extensionsmodel, video (obligatorio), prompt, seconds. Los nuevos segundos siguen las mismas reglas que en una creación.
POST /v1/videos/{id}/remixprompt (obligatorio). El modelo es el del vídeo de origen.

El vídeo de origen debe haberse completado. Un vídeo indicado por URL es una URL https, que se pasa al proveedor tal cual, igual que una imagen. Si indicas un vídeo por URL, seconds es obligatorio en los modelos que no tienen un máximo fijo.

Listar, consultar, descargar, eliminar

EndpointParámetrosRespuesta
GET /v1/videosConsulta: after (un id de vídeo), limit (de 1 a 100, por defecto 20), order (desc por defecto, o asc){"object":"list","data":[Video],"first_id","last_id","has_more"}. Los vídeos que han superado su expires_at se omiten.
GET /v1/videos/{id}El objeto Video.
GET /v1/videos/{id}/contentConsulta: variant (video por defecto, o thumbnail)302 Found a un enlace firmado a los bytes (video/mp4, o el tipo de la miniatura), válido durante 15 minutos. Los clientes HTTP y los SDK de OpenAI lo siguen. 404 not_found antes de completarse o cuando no hay miniatura.
DELETE /v1/videos/{id}{"id","object":"video.deleted","deleted":true}. Responde 409 video_not_finished mientras el trabajo se ejecuta. Un vídeo eliminado responde 404.

El objeto Video

{
  "id": "0194f2c4-7a1e-7b3c-9d02-5f6a1c0e8b21",
  "object": "video",
  "model": "x-ai/grok-imagine-video",
  "status": "completed",
  "progress": 100,
  "prompt": null,
  "seconds": "8",
  "size": "",
  "created_at": 1730000000,
  "completed_at": 1730000137,
  "expires_at": 1732592000,
  "error": null,
  "remixed_from_video_id": null,
  "usage": { "cost": 0.4, "seconds": 8 }
}
CampoTipoDescripción
statusstringqueued, in_progress, completed o failed.
progressintegerDe 0 a 100.
promptstring | nullEl prompt solo se devuelve mientras el trabajo se ejecuta. El objeto terminado devuelve null.
secondsstringDuración del vídeo, como cadena, igual que en OpenAI.
sizestringEl size que enviaste, si lo hiciste.
expires_atintegerHora Unix: created_at más 30 días. Después, GET /v1/videos/{id} y /content responden 404 not_found y el vídeo se omite de la lista. Descarga lo que quieras conservar antes de esa fecha.
errorobject | nullEn un trabajo fallido: {"code", "message"}, por ejemplo content_rejected.
remixed_from_video_idstring | nullEl vídeo de origen de una edición, extensión o remix.
usageobject | nullSe define cuando el trabajo se liquida: cost (USD, número JSON) y seconds (entero).
expanded_promptstring | nullAñadido. Con prompt_expand: el prompt con el que se generó, una vez enviado el trabajo. Se conserva 30 días; después, null.

Un vídeo se factura según los segundos que solicitas. El importe se retiene por adelantado y se libera por completo si el trabajo falla.

Ejemplo: x-ai/grok-imagine-video

El modelo x-ai/grok-imagine-video crea un vídeo a partir de un prompt, con una imagen opcional como punto de partida. seconds va de 1 a 15. Precio: $0.050 por segundo.

curl https://api.hyperouter.app/v1/videos \
  -H "Authorization: Bearer $HYPEROUTER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "x-ai/grok-imagine-video",
    "prompt": "She turns to the camera and smiles",
    "input_reference": { "image_url": "https://example.com/portrait.png" },
    "seconds": 8
  }'
{
  "id": "0194f2c4-7a1e-7b3c-9d02-5f6a1c0e8b21",
  "object": "video",
  "model": "x-ai/grok-imagine-video",
  "status": "queued",
  "progress": 0,
  "prompt": "She turns to the camera and smiles",
  "seconds": "8",
  "size": "",
  "created_at": 1730000000,
  "completed_at": null,
  "expires_at": 1732592000,
  "error": null,
  "remixed_from_video_id": null,
  "usage": null
}

A este trabajo se le cobra 8 × $0.050 = $0.40, así que el objeto liquidado muestra "usage": {"cost": 0.4, "seconds": 8}.

Errores

EstadocodeparamCuándo
400unsupported_content_typeEl cuerpo es multipart/form-data: Send a JSON body; pictures and videos are https URLs.
400invalid_bodyel campoEl cuerpo no es JSON válido; prompt está vacío; video no es un objeto con id o url; input_reference no es un objeto con image_url; limit, after o variant no es válido; un campo tipado tiene el tipo equivocado; resolution no está permitida; moderation no es auto ni low.
400unknown_modelmodelEl modelo no existe para vídeos.
400invalid_secondssecondsseconds no está permitido para el modelo (el mensaje enumera los valores permitidos), o hace falta para un vídeo indicado por URL.
400invalid_sizesizesize no tiene la forma 1280x720.
400unsupported_parameterel campoEl modelo no admite el campo; la resolución no está disponible (resolution o size); audio en un modelo sin sonido; input_reference.file_id.
400unsupported_operationmodelEl modelo no lista la operación (editar, extender o remix).
400invalid_combinationel campoMedios de referencia junto con fotogramas clave, según lo establece el proveedor.
400image_requiredinput_referenceThis model needs an input_reference picture.
400video_not_readyvideoEl vídeo de origen no ha terminado.
400invalid_image, invalid_videoel campoLa URL de una imagen (invalid_image) o de un vídeo (invalid_video: reference_videos[i], video.url) no es https a un host público, por ejemplo una URL data: o http://: <field> must be an https URL. param es el campo, por ejemplo input_reference.image_url, first_frame o reference_images[1]. Una URL se pasa al proveedor tal cual: si el proveedor no puede descargarla o leerla, el vídeo falla con vendor_rejected y no se cobra nada.
400clip_too_longEl clip de referencia más los seconds solicitados superan el límite del modelo: The reference clip plus the requested seconds run past the model's limit of 30 s. Send a shorter clip or fewer seconds. You were not charged. Aparece en error.code del objeto Video.
400content_rejected, vendor_rejectedEl trabajo falló en el proveedor. Aparece en error.code del objeto Video.
402insufficient_creditsEl saldo o el límite de la clave no cubre el importe retenido.
404not_foundEl vídeo no existe, no es tuyo, se eliminó o ha superado expires_at; o el contenido no está listo.
409video_not_finishedEliminaste un vídeo que todavía se está creando.
409idempotency_key_reused, idempotency_key_in_useConsulta Reintentos e idempotencia.
429, 503, 500Igual que en imágenes. Un 500 después de crear el vídeo lleva x-should-retry: false.

Modelos de vídeo

ModeloPrecio por segundo de vídeoNotas
x-ai/grok-imagine-videoDesde $0.050Entrada de texto, imagen o vídeo. 15 s como máximo. Admite edit.
x-ai/grok-imagine-video-1.5Desde $0.080Entrada de texto, imagen o referencia. 15 s como máximo.
x-ai/grok-imagine-video-1.5-liteDesde $0.020Igual que el anterior, más pequeño y barato.
bytedance/seedance-2.0Desde $0.0431892Entrada de texto, primer y último fotograma o imágenes de referencia, audio opcional. De 4 a 15 s. 480p, 720p, 1080p o 4K; la tarifa indicada es la de 480p.
bytedance/seedance-2.0-fastDesde $0.0331452Entrada de texto, primer y último fotograma o imágenes de referencia, audio opcional. De 4 a 15 s. 480p o 720p; la tarifa indicada es la de 480p.
bytedance/seedance-2.0-miniDesde $0.0210924Entrada de texto, primer y último fotograma o imágenes de referencia, audio opcional. De 4 a 15 s. 480p o 720p; la tarifa indicada es la de 480p.
bytedance/seedance-2.5Desde $0.0642816Entrada de texto, primer y último fotograma o imágenes de referencia, audio opcional. De 4 a 15 s. 480p, 720p o 1080p; la tarifa indicada es la de 480p.
lumina/berry-1.0Desde $0.050Entrada de texto, imagen o referencia, audio opcional. 30 s como máximo. 480p, 720p o 1080p; la tarifa indicada es la de 480p.
minimax/minimax-h3Desde $0.080Entrada de texto, primer y último fotograma o imágenes de referencia, sin audio. De 4 a 15 s, a 768p o 2K.
alibaba/wan3.0Desde $0.050Entrada de texto, imagen o referencia, audio opcional. 30 s como máximo. 480p, 720p o 1080p; la tarifa indicada es la de 480p.

La referencia de modelos del panel enumera todos los modelos de vídeo que tu cuenta puede llamar.

Generaciones

GET/v1/generations/{id}

Devuelve el registro de una de tus solicitudes, de cualquier tipo: su estado, consumo, cargo, tiempos y, para imágenes y vídeos, enlaces firmados a las salidas. Úsalo para consultar periódicamente una solicitud de imagen que enviaste con Prefer: respond-async y para conciliar el gasto. El texto del prompt y de la respuesta nunca está en el registro. Hyperouter lo conserva cifrado durante 180 días solo para cumplir obligaciones legales, y ninguna API ni página del panel lo devuelve (Política de privacidad).

Parámetros

NombreEnTipoObligatorioDescripción
idpathstring (UUID)SíEl id de un chat completion, una respuesta de imagen o un objeto Video.

Respuesta

{
  "data": {
    "id": "0194f2c4-7a1e-7b3c-9d02-5f6a1c0e8b21",
    "kind": "chat",
    "model": "x-ai/grok-4.7",
    "provider_name": "xAI",
    "status": "done",
    "created_at": "2026-10-24T08:12:00Z",
    "finished_at": "2026-10-24T08:12:02Z",
    "usage": {
      "input_tokens": 120, "output_tokens": 300, "cache_read_tokens": 0,
      "image": 0, "video_seconds": 0, "cost": 0.00204
    },
    "usage_estimated": false,
    "ttft_ms": 320,
    "latency_ms": 2100,
    "error": null,
    "outputs": []
  }
}
CampoTipoDescripción
kindstringchat, image o video.
provider_namestring | nullEl proveedor que atendió una solicitud de chat terminada. null para imágenes y vídeos.
statusstringqueued, submitting, running, done o failed.
created_at, finished_atstring | nullRFC 3339 UTC. finished_at es null hasta que la solicitud termina.
usageobjectinput_tokens, output_tokens, cache_read_tokens, image, video_seconds y cost. cost es el cargo en USD, un número JSON. Los contadores son 0 hasta que la solicitud termina.
usage_estimatedbooleantrue cuando el proveedor no envió el recuento de tokens y Hyperouter lo calculó.
ttft_ms, latency_msinteger | nullTiempo hasta el primer token y tiempo total, en milisegundos.
errorobject | null{"code", "message"} cuando la solicitud falló.
outputsobject[]Para imágenes y vídeos: [{"url", "expires_at"}], enlaces firmados válidos durante 24 horas. Disponibles durante 30 días tras la solicitud; después outputs queda vacío y el registro permanece. Siempre vacío en chat.
expanded_promptstring | nullPara imágenes y vídeos enviados con prompt_expand: el prompt con el que se generó. Se conserva 30 días tras la solicitud; después, null.
curl https://api.hyperouter.app/v1/generations/0194f2c4-7a1e-7b3c-9d02-5f6a1c0e8b21 \
  -H "Authorization: Bearer $HYPEROUTER_API_KEY"

Errores

EstadotypecodeparamCuándo
404not_foundnot_foundidNo generation with that id. El id no es un UUID, no existe, pertenece a otra cuenta o se eliminó.
500server_errorserver_errorHyperouter no pudo leer ni firmar el registro.
401, 403Consulta Autenticación.

Parámetros específicos de cada modelo

Algunos modelos tienen campos que otros modelos no tienen. Son los parámetros adicionales. Los envías como campos de primer nivel del cuerpo de la solicitud, como cualquier otro campo. Cualquier SDK de OpenAI puede enviarlos (extra_body en Python, propiedades adicionales en JavaScript).

GET /v1/models enumera los parámetros adicionales de cada modelo en extra_parameters. Cada entrada tiene:

CampoTipoDescripción
typestringUno de string, integer, number, boolean, array, object.
valuesarrayLos valores permitidos. Vacío significa cualquier valor del tipo.
price_conditionbooleantrue cuando el campo cambia el precio.
descriptionstringQué hace el campo.

La referencia de modelos del panel describe los parámetros adicionales de cada modelo que tu cuenta puede llamar.

Reglas

Funciones compartidas

Estos campos tienen el mismo nombre en todos los modelos que los tienen. Un modelo lista los que admite en supported_parameters.

CampoSignificado
resolution480p, 720p, 1080p, 2K o 4K, según lo que permita el modelo.
ratio, seed, negative_prompt, prompt_extend, audioSegún su nombre. audio y prompt_extend están desactivados salvo que los pidas.
first_frame, last_frameFotogramas clave para vídeo.
reference_images, reference_videosMedios de referencia para vídeo y edición de imágenes.

Expansión del prompt

Con "prompt_expand": true, Hyperouter reescribe tu prompt para el modelo antes de generar: una descripción más completa para una imagen y un guion segundo a segundo para un vídeo. Está desactivada por defecto, así que el prompt se envía tal cual. Solo la acepta un modelo cuyo supported_parameters incluya prompt_expand, y solo para crear una imagen o un vídeo; en cualquier otro modelo, y en la edición, extensión o remezcla de un vídeo, se rechaza con 400 unsupported_parameter. Tampoco se puede combinar con prompt_extend: true (400 invalid_body).

La expansión del prompt está disponible para una cuenta cuando Hyperouter la habilita; abre un ticket de soporte para solicitar el acceso. Hasta entonces, GET /v1/models no lista prompt_expand en ningún modelo, y una solicitud con prompt_expand: true en un modelo que lo ofrece responde 403 permission_error, código feature_not_enabled, param prompt_expand, sin retener nada ni enviarlo al proveedor.

La reescritura como modelo de chat

Una cuenta con expansión del prompt también tiene un modelo de chat que devuelve la reescritura en lugar de generarla; tu referencia de modelos lo nombra. Llámalo en POST /v1/chat/completions con exactamente un mensaje user: su texto es el prompt, y sus partes image_url (URL https, 5 como máximo) son las imágenes; una URL data: o http:// devuelve 400 invalid_image con param igual a messages. target_model es obligatorio: un modelo que liste prompt_expand. seconds, locale y negative_prompt son opcionales. Un destino de vídeo con una imagen se escribe a partir de ese primer fotograma. No admite streaming (stream: true devuelve 400 unsupported_parameter), y cualquier otro mensaje, incluido un mensaje system, devuelve 400 invalid_body.

Este modelo de chat usa siempre x-ai/grok-4.6; no admite prompt_expand_model. choices[0].message.content es una cadena JSON, {"prompt": "...", "negative_prompt": "..."}, más "beats" (una línea por segundo) para un destino de vídeo. Se factura a los precios por token de x-ai/grok-4.6, que figuran en usage. Un prompt que pide las instrucciones del modelo devuelve 400 prompt_rejected; una reescritura rechazada o vacía devuelve 422 expansion_refused, y una que falla, 503 upstream_error. Ninguno de estos casos se cobra.

Moderación

El campo moderation es de OpenAI. Funciona en /v1/chat/completions, /v1/images/generations, /v1/images/edits y /v1/videos con sus llamadas de edición, extensión y remix.

ValorSignificado
auto (por defecto)Se aplica el filtrado propio del proveedor. Hyperouter no envía nada adicional.
lowHyperouter envía la exclusión voluntaria del filtrado del proveedor, en los modelos donde el proveedor la ofrece. En los demás modelos low se ignora sin error, como hace OpenAI. La entrada de cada modelo en tu referencia de modelos indica si la ofrece. Envía moderation en el cuerpo: una cabecera o un campo de filtrado propio del proveedor no se reenvía en estos endpoints.

Cualquier otro valor se rechaza: 400 invalid_request_error, código invalid_body, param moderation, mensaje moderation must be auto or low.

low está disponible para una cuenta una vez que Hyperouter lo ha habilitado; abre un ticket de soporte para solicitarlo. Hasta entonces, una solicitud con low responde 403 permission_error, código moderation_not_enabled, param moderation, y no se envía al proveedor.

{
  "model": "qwen/qwen-image-2.0",
  "prompt": "...",
  "moderation": "low"
}

La respuesta no indica si se usó la exclusión voluntaria. Las políticas de los Términos del servicio siguen aplicándose. Una solicitud que el filtro del proveedor rechaza falla con 400 content_rejected y no se cobra.

Webhooks

En lugar de consultar periódicamente, un endpoint tuyo puede recibir una solicitud cuando termina un trabajo. Añade endpoints en el panel. La estructura es la de los webhooks de OpenAI, firmados con el esquema Standard Webhooks, por lo que los SDK de OpenAI los verifican.

EventoSe envía cuando
video.completed, video.failedTermina un trabajo de vídeo.
image.completed, image.failedTermina un trabajo de imagen que enviaste con Prefer: respond-async.
raw.completed, raw.failedTermina la tarea de una llamada directa (cuentas con llamadas directas): cobrada, o su retención liberada. Una llamada directa que responde en el momento no envía ninguno.

La carga útil lleva un id, nunca un resultado, un prompt ni un cargo. Obtén el objeto con tu clave de API: data.id es el id que aceptan GET /v1/videos/{id} y GET /v1/generations/{id}. En una tarea directa es el X-Generation-Id que devolvió la creación.

{
  "id": "evt_0194f2c4-7a1e-7b3c-9d02-5f6a1c0e8b21",
  "object": "event",
  "type": "video.completed",
  "created_at": 1761300000,
  "data": { "id": "0194f2c4-7a1e-7b3c-9d02-5f6a1c0e8b21" }
}

Encabezados y verificación

Cada entrega es un POST con content-type: application/json y estos encabezados:

El secreto de firma empieza por whsec_. Se muestra una sola vez, cuando creas el endpoint y cuando lo rotas. Verifica el cuerpo bruto de la solicitud, antes de analizarlo:

// Node, with the OpenAI SDK
const event = client.webhooks.unwrap(rawBody, req.headers, process.env.HYPEROUTER_WEBHOOK_SECRET);
if (event.type === "video.completed") {
  const video = await client.videos.retrieve(event.data.id);
}

unwrap lanza una excepción cuando la firma no se verifica; responde a una solicitud así con un estado de error. La llamada posterior usa la misma URL base que el resto de esta API.

Endpoints, reintentos y límites

Servidor MCP

POSThttps://api.hyperouter.app/mcp

Un asistente de IA puede trabajar con tu cuenta de Hyperouter a través del Model Context Protocol (MCP). El servidor gestiona el panel: claves de API, actividad, créditos, tickets, webhooks y la lista de modelos. No ejecuta modelos. Las llamadas a modelos siguen yendo a /v1 con una clave de API.

El servidor habla Streamable HTTP y JSON-RPC 2.0. Admite las revisiones de MCP 2025-11-25 y 2025-06-18. No tiene estado: no hay sesiones, y GET /mcp responde 405.

Tokens de acceso

Un cliente MCP se autentica con un token de acceso del panel, no con una clave de API.

ÁmbitoHerramientas que el token puede llamar
readHerramientas que solo leen datos.
writeTodas las herramientas que el usuario tiene permiso para usar.

Envía el token como token bearer:

Authorization: Bearer hr_dt_...

Protocolo

MétodoRespuesta
initializeLa versión del protocolo (la del cliente, si se admite; si no, 2025-11-25), la capacidad tools y la información del servidor.
pingUn resultado vacío.
tools/listLas herramientas que permiten el usuario y el ámbito del token.
tools/callEl resultado de una herramienta.

Una notificación, o una respuesta al servidor, responde 202 sin cuerpo. Un lote JSON-RPC se rechaza con el error -32600. Un mensaje no debe superar 1 MiB. Un encabezado MCP-Protocol-Version desconocido responde 400. Una solicitud de navegador debe proceder de https://dash.hyperouter.app; un cliente que no envía el encabezado Origin no se ve afectado.

curl https://api.hyperouter.app/mcp \
  -H "Authorization: Bearer $HYPEROUTER_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc": "2.0", "id": 1, "method": "tools/list"}'

Herramientas

tools/list devuelve el conjunto actual de herramientas. Cada herramienta corresponde a una ruta del panel y lleva un esquema JSON Schema para sus argumentos. Las herramientas cubren:

Una herramienta responde con un elemento de contenido de texto que contiene el cuerpo JSON de la ruta. Cuando la ruta falla, el resultado tiene isError: true y el texto <message> (<code>, HTTP <status>). Una herramienta desconocida, o una que tu token no puede ver, es el error JSON-RPC -32602.

Aprobaciones

Una escritura sensible, como acreditar una cuenta, no se ejecuta de inmediato. La herramienta no la ejecuta. Responde con status igual a approval_required y una approval_url en el panel. El usuario abre el enlace, confirma con un segundo factor y aprueba la acción. Una aprobación caduca a las 24 horas. El usuario también puede rechazarla.

Facturación y límites

Límites de velocidad

Cada cuenta tiene un límite de solicitudes por minuto y de solicitudes en curso a la vez. Ambos cuentan juntas todas las claves de API de la cuenta, y se aplican a toda solicitud que inicia trabajo: chat completions, creaciones de imagen y vídeo, y creaciones directas. Leer un resultado (GET /v1/generations/{id}, GET /v1/videos…, una consulta directa de tarea) no cuenta; las consultas directas se cuentan aparte, por proveedor, con el mismo límite de solicitudes por minuto.

Tu nivel depende del total que hayas recargado, antes de la comisión por recarga:

NivelRecargadoSolicitudes por minutoSolicitudes concurrentes
1Menos de $106010
2$10 o más30030
3$100 o más1,200100
4$1,000 o más6,000300

Tus límites actuales aparecen en la página Credits. Son los valores por defecto; el personal puede cambiarlos para la plataforma o para una cuenta concreta, y el cambio se aplica en un minuto.

Si se supera cualquiera de los dos límites, la solicitud se rechaza antes de retener o reenviar nada, con 429, type: rate_limit_error, code: rate_limited y un encabezado Retry-After en segundos. El mensaje indica el límite alcanzado. Una solicitud cuenta para el minuto aunque se rechace. Una solicitud en curso, incluido un stream, cuenta hasta que termina.

Como protección contra el intento de adivinar claves, Hyperouter cuenta las comprobaciones fallidas de clave de API por dirección de cliente. Más de 30 en un minuto bloquean esa dirección en todas las rutas /v1 durante 15 minutos: 429, rate_limit_error, too_many_auth_failures, con Retry-After. Una clave válida no levanta el bloqueo.

Soporte

Abre un ticket en el panel para dudas sobre facturación, recargas y la API; el equipo responde en el mismo hilo. También puedes escribir a [email protected]. Incluye el id de la respuesta cuando informes de una solicitud concreta.