Voir en Markdown

Hyperouter API

Version v1 · Mis à jour le 25 octobre 2026

Cette documentation est disponible en Markdown pour les assistants IA. Commencez par /llms.txt, ou récupérez /llms-full.txt pour avoir toutes les pages dans un seul fichier. Cette page est /docs.md.

Hyperouter est une API HTTP unique devant de nombreux éditeurs de modèles. Vous envoyez une requête qui nomme un modèle. Hyperouter choisit un fournisseur capable de la servir, lui transmet la requête et débite votre solde au tarif public de ce fournisseur.

BASEhttps://api.hyperouter.app/v1

Chaque endpoint suit les formats de requête et de réponse d’OpenAI. Les OpenAI SDK fonctionnent dès que vous changez l’URL de base et la clé API. Hyperouter ajoute quelques champs aux corps d’OpenAI. Ils sont signalés comme ajouts dans cette référence.

EndpointRôleAuth
GET /v1/modelsLister les modèles que votre compte peut appeler.Clé API
POST /v1/chat/completionsChat completion, avec streaming optionnel.Clé API
POST /v1/images/generationsTexte vers image.Clé API
POST /v1/images/editsModifier des images.Clé API
POST /v1/videosCréer une vidéo à partir d’un prompt, avec une image facultative.Clé API
POST /v1/videos/editsModifier ou agrandir une vidéo.Clé API
POST /v1/videos/extensionsProlonger une vidéo.Clé API
POST /v1/videos/{id}/remixProduire une nouvelle version d’une vidéo avec un nouveau prompt.Clé API
GET /v1/videos, GET /v1/videos/{id}, GET /v1/videos/{id}/content, DELETE /v1/videos/{id}Lister, lire, télécharger et supprimer des vidéos.Clé API
GET /v1/generations/{id}Lire l’enregistrement de n’importe quelle requête : statut, consommation et coût.Clé API
GET /v1/creditsVotre solde, ce que bloquent les requêtes ouvertes, et ce qu’il reste à dépenser (balance_usd, held_usd, available_usd, chaînes décimales en USD).Clé API

Connectez-vous sur dash.hyperouter.app avec Google ou GitHub pour créer une clé API. GET /v1/models renvoie les modèles que vous pouvez appeler au moment de la requête.

Démarrage rapide

  1. Connectez-vous et créez une clé API. Les clés commencent par sk-hr-v1- et ne sont affichées qu’une seule fois.
  2. Stockez-la dans une variable d’environnement, par exemple HYPEROUTER_API_KEY.
  3. Ajoutez des crédits : ouvrez une demande de recharge dans le tableau de bord. Notre équipe crédite votre solde une fois le paiement confirmé.
  4. Pointez n’importe quel OpenAI SDK vers l’URL de base ci-dessus et choisissez un modèle.
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"}]
  }'

Authentification

Envoyez votre clé API comme bearer token dans chaque requête.

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

Les clés donnent accès à votre solde. Gardez-les côté serveur. Ne les mettez jamais dans du code navigateur ou mobile. Hyperouter ne stocke que le hash de chaque clé : une clé perdue ne peut donc pas être affichée de nouveau, il faut en créer une nouvelle.

Dans le tableau de bord, vous pouvez nommer chaque clé, lui fixer une limite de crédit et la désactiver. Une clé désactivée cesse de fonctionner immédiatement. Une requête qui ferait dépasser sa limite à une clé est refusée avec 402 insufficient_credits.

Erreurs d’authentification

StatuttypecodeQuandmessage
401authentication_errorinvalid_api_keyL’en-tête est absent, n’est pas de type Bearer, ou la clé ne commence pas par sk-hr-v1-.The API key is missing or malformed. Send Authorization: Bearer sk-hr-v1-…
401authentication_errorinvalid_api_keyLa clé est inconnue ou désactivée.The API key is not valid.
403permission_erroraccount_suspendedLe compte est suspendu. La vérification est faite à chaque requête.This account is suspended. Open a support ticket.
429rate_limit_errortoo_many_auth_failuresPlus de 30 requêtes provenant de votre adresse en une minute ont utilisé une clé absente ou invalide. Toutes les requêtes /v1 de cette adresse sont refusées pendant 15 minutes, même avec une clé valide. Retry-After indique les secondes restantes.Too many failed API key checks from this address. Try again after the time in Retry-After.
500server_errorinternalHyperouter n’a pas pu vérifier la clé.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 } }

Erreurs

Chaque erreur utilise l’objet d’erreur d’OpenAI et un statut HTTP correspondant.

{
  "error": {
    "message": "n must be an integer from 1 to 128",
    "type": "invalid_request_error",
    "code": "invalid_body",
    "param": "n"
  }
}
ChampTypeDescription
messagestringUne phrase qui dit ce qui ne va pas. Ne l’analysez pas.
typestringLa classe d’erreur. Voir la liste ci-dessous.
codestringUn identifiant stable de la cause. Fiez-vous à ce champ.
paramstring | nullLe champ de la requête en cause, ou null.

Types et statuts

StatuttypeSignification
400invalid_request_errorLa requête est invalide. code désigne la cause et param le champ.
401authentication_errorLa clé API est absente ou invalide.
402insufficient_creditsVotre solde, ou la limite de la clé, ne peut pas couvrir le coût maximal de la requête.
403permission_errorLe compte est suspendu.
404not_foundCet id n’existe pas, l’id appartient à un autre compte, ou une vidéo a dépassé son expires_at.
409conflictL’objet n’est pas dans un état qui autorise l’appel (video_not_finished), ou conflit d’Idempotency-Key (voir Nouvelles tentatives et idempotence).
422invalid_request_errorLa requête était valide, mais sa réponse a été refusée (expansion_refused). Non facturé.
429rate_limit_errorTous les fournisseurs du modèle sont saturés, votre compte dépasse ses limites de débit, ou trop de vérifications de clé API depuis votre adresse ont échoué. Réessayez après le délai indiqué dans l’en-tête Retry-After.
500, 501server_errorHyperouter a échoué, ou l’endpoint n’est pas implémenté. Non facturé.
503upstream_errorUn fournisseur a échoué ou n’a pas répondu à temps : code indique lequel (all_venues_failed, upstream_error ou timeout). L’en-tête X-Upstream-Status contient 502 (échec) ou 504 (délai dépassé).

Hyperouter ne répond jamais 502 ni 504 : ils vous parviendraient sous forme de page brute de notre réseau en périphérie, sans le corps d’erreur. Là où une passerelle répondrait ces statuts, vous recevez 503 avec le corps ci-dessous et le statut de la passerelle dans X-Upstream-Status.

Codes possibles

codeStatutQuand
invalid_body400Un champ du corps ou un paramètre de requête ne peut pas être analysé, est du mauvais type, ou sort de ses valeurs autorisées. param le désigne.
unsupported_content_type400/v1/images/generations a reçu un corps multipart/form-data. Envoyez du JSON. param vaut null.
request_too_large413Un envoi multipart/form-data dépasse 50 MiB. Envoyez les médias volumineux sous forme d’URL https.
unknown_model400Le modèle n’existe pas pour cet endpoint, ou aucun fournisseur ne peut le servir avec vos préférences provider.
unsupported_parameter400Un paramètre qui existe pour d’autres modèles n’est pas disponible sur ce modèle. Voir Paramètres propres à chaque modèle.
invalid_combination400L’éditeur n’autorise pas ces paramètres ensemble, par exemple des médias de référence avec des images clés.
invalid_size400size n’est pas de la forme WIDTHxHEIGHT, ou n’est pas autorisé pour le modèle.
too_many_images400n ou le nombre d’images en entrée dépasse la limite.
invalid_image, invalid_video400L’URL d’une image ou d’une vidéo n’est pas en https vers un hôte public : une URL data:, une URL http://, une adresse IP ou un nom interne. param désigne le champ.
image_required400Le modèle exige une image en entrée et vous n’en avez envoyé aucune (ou il ne fait que modifier, et vous avez appelé generations).
invalid_seconds400seconds n’est pas autorisé pour le modèle, ou est absent pour une vidéo donnée par URL.
unsupported_operation400Le modèle ne prend pas en charge l’opération (modifier, prolonger ou remixer, ou modifier une image).
video_not_ready400La vidéo source n’est pas terminée.
context_length_exceeded400Le prompt de chat et max_tokens ne tiennent pas dans le contexte du modèle.
content_rejected400Le filtre de sécurité de l’éditeur a refusé l’entrée.
vendor_rejected400Le modèle a refusé la requête comme invalide. Vérifiez ses paramètres et ses entrées.
clip_too_long400Un clip de référence et les seconds demandées dépassent la limite du modèle (30 s). Non facturé.
prompt_rejected400Le prompt demande au modèle d’expansion du prompt ses instructions. Non facturé. Voir Expansion du prompt.
expansion_refused422La réécriture du modèle d’expansion du prompt a été refusée ou est revenue vide. Non facturé. Voir Expansion du prompt.
invalid_api_key401Voir Authentification.
insufficient_credits402Voir Facturation et limites.
account_suspended403Le compte est suspendu.
moderation_not_enabled403moderation: "low" n’est pas activé pour le compte. Voir Modération.
feature_not_enabled403prompt_expand n’est pas activé pour le compte, sur un modèle qui le propose. Ouvrez un ticket de support pour en demander l’accès. Rien n’est réservé ni envoyé au fournisseur. Voir Expansion du prompt.
model_not_enabled403Le modèle exige un accès accordé à votre compte. Ouvrez un ticket de support pour le demander. Rien n’est bloqué ni envoyé au fournisseur.
not_found404Cet objet n’existe pas.
video_not_finished409Vous avez supprimé une vidéo encore en cours de création.
venue_busy429Tous les fournisseurs du modèle de chat ont dépassé leur budget de débit.
rate_limited429Votre compte dépasse ses requêtes par minute ou ses requêtes simultanées. Voir Limites de débit.
too_many_auth_failures429Plus de 30 requêtes provenant de votre adresse en une minute ont utilisé une clé API invalide. Voir Limites de débit.
all_venues_failed503Aucun fournisseur n’est en bonne santé, ou tous ont échoué.
upstream_error503Une tâche d’image ou de vidéo a échoué au niveau du modèle. Vous n’êtes pas facturé.
internal, server_error, no_price500Hyperouter a échoué (no_price : le modèle ne peut pas être tarifé pour le moment). Non facturé.
not_implemented501This endpoint is not implemented yet.
invalid_idempotency_key400L’en-tête Idempotency-Key dépasse 255 caractères ou n’est pas en ASCII imprimable. Voir Nouvelles tentatives et idempotence.
idempotency_key_reused409L’Idempotency-Key a déjà été utilisée avec une requête différente.
idempotency_key_in_use409Une requête avec cette Idempotency-Key est encore en cours de démarrage. Réessayez avec la même clé.
idempotency_key_replayed409Une chat completion avec cette Idempotency-Key a déjà été exécutée. error.generation_id en est l’id.
timeout503Une image synchrone n’était pas prête au bout de 90 secondes. Elle est toujours en cours de création : error.generation_id est l’id à interroger.

Nouvelles tentatives et idempotence

Une erreur réseau ou un délai dépassé ne vous dit pas si Hyperouter a reçu la requête. Si vous la renvoyez, vous pouvez démarrer une seconde tâche et payer deux fois. Une Idempotency-Key rend la répétition sûre : Hyperouter reconnaît la répétition, ne démarre pas de seconde tâche, ne bloque pas de second montant, et répond à partir de la première requête.

Envoyez-en une sur chaque requête qui coûte de l’argent. Générez une nouvelle valeur aléatoire, par exemple un UUID v4, pour chaque nouvelle requête. Conservez-la avec la requête et envoyez la même valeur chaque fois que vous renvoyez cette requête.

Envoyer une clé

L’en-tête est accepté sur ces endpoints :

EndpointUne répétition renvoie
POST /v1/images/generations, POST /v1/images/editsl’image de la première requête, ou son 202 avec le même id sous Prefer: respond-async
POST /v1/videos, /v1/videos/edits, /v1/videos/extensions, /v1/videos/{id}/remixl’objet Video de la première requête, dans son état actuel
POST /v1/chat/completions409 idempotency_key_replayed avec l’id de la première requête (voir Chat completions)

Les OpenAI SDK n’envoient pas cet en-tête d’eux-mêmes. Passez-le comme en-tête supplémentaire ; les SDK le renvoient alors inchangé lors de leurs nouvelles tentatives automatiques.

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}'

Ce que renvoie une répétition

Vous envoyezHyperouter répond
Une nouvelle cléExécute la requête normalement.
La même clé et la même requête, après acceptation de la premièreLe résultat de la première requête, comme dans le tableau ci-dessus. Pas de seconde tâche, pas de second blocage, pas de second débit.
La même clé et la même requête, alors que la première est encore en cours d’acceptationAttend la première, puis répond comme ci-dessus. Si la première n’a pas démarré sa tâche au bout de 60 secondes : 409 idempotency_key_in_use. Réessayez avec la même clé.
La même clé et une requête différente409 idempotency_key_reused. Rien ne s’exécute. Utilisez une nouvelle clé.
La même clé, après que la première a été refusée avant le démarrage de toute tâche (un 400, un 402, ou un 5xx envoyé sans x-should-retry: false)Exécute la requête comme une nouvelle, ce qui vous permet de la corriger et de la renvoyer avec la même clé.
La même clé, plus de 30 minutes après la première requêteExécute la requête comme une nouvelle.
Une clé de plus de 255 caractères, ou qui n’est pas en ASCII imprimable400 invalid_idempotency_key. Rien ne s’exécute.

Règles

Chat completions

Les réponses de chat ne sont pas rejouées. Une répétition avec la même clé répond 409 avec le code idempotency_key_replayed, et error.generation_id est l’id de la première requête. La requête n’est ni réexécutée ni refacturée. Retrouvez la première requête avec GET /v1/generations/{id} pour voir son statut, sa consommation et son coût. Si la première chat completion a échoué et n’a pas été facturée, sa clé est libérée et une répétition s’exécute comme une nouvelle requête.

{
  "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"
  }
}

Nouvelles tentatives automatiques dans les OpenAI SDK

Les OpenAI SDK réessaient deux fois par défaut une réponse 408, 409, 429 ou 5xx, sauf si la réponse porte l’en-tête x-should-retry: false. Hyperouter envoie x-should-retry: false sur toute réponse pour laquelle une nouvelle tentative démarrerait une seconde tâche ou un second débit :

Il ne l’envoie jamais sur un 429, sur un 409 idempotency_key_in_use, ni sur un 5xx survenu avant l’existence de toute tâche. Dans ces cas, réessayer est sans risque. Avec une Idempotency-Key, chaque nouvelle tentative est sûre.

Modèles

GET/v1/models

Liste tous les modèles que votre compte peut appeler à l’instant, avec leurs prix et ce qu’ils prennent en charge. Un modèle sans fournisseur activé n’est pas listé. Certains modèles exigent un accès accordé à votre compte : ils sont listés dès qu’il l’est. Cet endpoint exige une clé API et liste les modèles que le compte de cette clé peut appeler. La réponse peut être mise en cache pendant 60 secondes, par votre client uniquement.

Paramètres

Aucun.

Réponse

{
  "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": {}
  }]
}
ChampTypeDescription
idstringL’id du modèle, <provider>/<name>, par exemple x-ai/grok-4.7 ou qwen/qwen-image-2.0. Envoyez-le comme model. Un modèle renommé continue de répondre à son ancien id.
response_modesstring[]La manière dont le modèle répond : sync (une réponse retenue), async (envoyez Prefer: respond-async, recevez 202, puis interrogez) et stream ("stream": true). Un modèle qui ne liste que async exige l’en-tête Prefer, et stream ne fonctionne que là où il est listé. La vidéo est toujours asynchrone via la Videos API, avec ou sans l’en-tête.
namestringNom d’affichage.
kindstringchat, image ou video.
context_lengthintegerFenêtre de contexte en tokens. 0 pour les modèles d’image et de vidéo.
architectureobjectinput_modalities et output_modalities. La sortie est ["text"], ["image"] ou ["video"].
pricingobject of stringsUSD par unité, en chaînes décimales, au palier de base : prompt et completion (par token), input_cache_read (par token en cache), request, image (par image), video_second (par seconde de vidéo). Une vidéo tarifée selon la résolution affiche le prix le plus bas. Une unité qui ne s’applique pas vaut "0".
top_providerobjectcontext_length et max_completion_tokens.
supported_parametersstring[]Pour le chat, les paramètres OpenAI que le modèle accepte. Pour l’image et la vidéo, les fonctionnalités communes qu’il accepte (resolution, ratio, audio, seed, negative_prompt, first_frame, last_frame, reference_images, reference_videos, prompt_extend).
operationsstring[]Modèles vidéo uniquement : edit, extend et remix, pour chacune des opérations que le modèle prend en charge. Absent lorsque le modèle n’en prend aucune.
extra_parametersobjectLes champs de premier niveau propres au modèle, par nom. Chacun a type, values (valeurs autorisées ; vide signifie n’importe laquelle), price_condition (le champ modifie le prix) et description. Voir Paramètres propres à chaque modèle.
curl https://api.hyperouter.app/v1/models \
  -H "Authorization: Bearer $HYPEROUTER_API_KEY"

Erreurs

Aucune propre à cet endpoint.

Modèles de chat

Prix par million de tokens : entrée / entrée en cache / sortie.

ModèleContextePrix
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 par requête

Sur les modèles x-ai/, une requête de 200 000 tokens de prompt ou plus est facturée intégralement aux tarifs de long contexte, qui sont le double de ceux-ci. Les modèles deepseek/ ont un seul tarif quelle que soit la longueur du prompt, raisonnent avant de répondre par défaut (reasoning_effort: "none" le désactive), et comptent leur raisonnement dans max_tokens, au plus 384 000. z-ai/glm-5.3 raisonne toujours : reasoning_effort vaut low, high ou max, et none est refusé. Les modèles openai/ raisonnent aussi et acceptent des prompts de 272 000 tokens au plus.

Chat completions

POST/v1/chat/completions

Crée une réponse de modèle pour une conversation. Le corps est la requête Chat Completions d’OpenAI. Hyperouter ajoute models, provider et moderation.

Paramètres

NomTypeRequisValeurs autoriséesDéfautDescription
modelstringOuiUn id de modèle de chat issu de GET /v1/modelsLe modèle à utiliser, par exemple x-ai/grok-4.7.
messagesobject[]OuiNon vide. Rôles system, user, assistant, toolLa conversation jusqu’ici. Les images (parties image_url) sont acceptées lorsque le modèle prend en charge les images.
modelsstring[]NonAu plus 5 ids de modèleAjout. Modèles de repli, essayés dans l’ordre lorsque tous les fournisseurs de model ont échoué.
providerobjectNonVoir ci-dessousAjout. Préférences de routage.
moderationstringNonauto, lowautoAjout. Voir Modération.
streambooleanNonfalseRenvoyer des server-sent events.
stream_optionsobjectNon{"include_usage": true}Avec include_usage, le flux se termine par un chunk qui porte usage.
max_tokens, max_completion_tokensintegerNon1 ou plusLe maximum de sortie du modèleBorne supérieure des tokens générés. Elle fixe aussi le coût maximal d’une requête, qu’Hyperouter bloque avant l’appel (voir Facturation).
nintegerNon1 à 1281Nombre de choix.
temperature, top_p, seed, frequency_penalty, presence_penalty, logit_biasnumber / integer / objectNonComme OpenAIContrôles d’échantillonnage, transmis au fournisseur.
stopstring | string[]NonSéquences qui mettent fin à la génération.
tools, tool_choice, parallel_tool_callsobject[], string | object, booleanNonFormat d’appel de fonctions d’OpenAIAppel de fonctions. Uniquement des outils de type function : tout autre type est refusé avec 400 unsupported_parameter.
response_formatobjectNon{"type":"json_object"} ou un schéma JSONSortie structurée.
reasoning_effort, logprobs, top_logprobs, usercomme OpenAINonTransmis au fournisseur lorsque le modèle les accepte.

Les autres champs sont ignorés. supported_parameters de chaque modèle dans GET /v1/models liste exactement ce qu’il accepte. Grok 4.20 et les versions plus récentes ignorent logprobs et top_logprobs, qui ne sont donc pas listés.

L’objet provider

Par défaut, Hyperouter envoie chaque requête de chat au fournisseur en bonne santé dont le prix est le plus bas pour ce modèle, et départage les égalités par le plus court temps récent jusqu’au premier token. Un fournisseur qui renvoie des erreurs à répétition est ignoré jusqu’à son rétablissement. L’objet provider suit le format de requête d’OpenRouter.

NomTypeRequisValeurs autoriséesDéfautDescription
sortstringNonprice, latency, throughputpriceLa manière de classer les fournisseurs.
orderstring[]NonNoms de fournisseursFournisseurs à essayer en premier, dans l’ordre, par exemple ["xai"]. Un nom de fournisseur est son nom public, quelle que soit la casse (xAI, Qwen), ou la première partie de ses ids de modèle (x-ai, qwen).
onlystring[]NonNoms de fournisseursRouter uniquement vers ces fournisseurs.
ignorestring[]NonNoms de fournisseursNe jamais router vers ces fournisseurs.

Réponse

La chat completion d’OpenAI. L’id est l’id de la requête : retrouvez-la avec GET /v1/generations/{id}. Hyperouter ajoute provider (le nom public du fournisseur qui a exécuté la requête, par exemple xAI) et usage.cost (le coût, en USD, sous forme de nombre 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 modèle de réécriture de prompt répond avec un seul choix, un usage de zéro token et un cost fixe par requête.

Streaming

Avec "stream": true, la réponse est un flux de server-sent events au format de chunk d’OpenAI. Il se termine par data: [DONE]. Lorsque vous définissez stream_options.include_usage, le dernier chunk avant [DONE] a un tableau choices vide, un objet usage qui inclut cost, et un champ provider. La consommation est toujours collectée pour la facturation, que vous demandiez ou non ce chunk.

Tant que le premier token n’est pas arrivé, le flux envoie la ligne de commentaire : processing toutes les 15 secondes pour garder la connexion ouverte. Les clients SSE ignorent les commentaires.

Le repli vers un autre fournisseur n’a lieu qu’avant l’envoi du premier token. Si un fournisseur échoue en cours de flux, le flux se termine par data: {"error": {...}} suivi de data: [DONE], et vous êtes facturé pour les tokens déjà produits.

Vous êtes facturé pour les tokens que le fournisseur produit, que vous les lisiez ou non. Un flux que vous interrompez, ou une réponse que vous cessez d’attendre, n’est pas arrêté chez le fournisseur, qui continue et facture sa réponse entière : Hyperouter la lit jusqu’au bout (pendant 5 minutes au plus) et la facture.

Un fournisseur qui a accepté une requête peut être en train de l’exécuter. S’il cesse ensuite de répondre (5 minutes sans token sur un flux, ou plus longtemps que ne prend une réponse de max_tokens) ou si sa réponse s’interrompt avant le premier token, la requête n’est pas envoyée à un autre fournisseur : elle répond 503 avec le code timeout ou upstream_error et error.generation_id, et est facturée sur son montant bloqué, avec usage_estimated: true sur son enregistrement.

Exemple

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" }]
  }'

Erreurs

StatuttypecodeparamQuand
400invalid_request_errorinvalid_bodyle champLe corps n’est pas du JSON valide ou dépasse 32 MiB ; model est absent ; models a plus de 5 entrées ; n est hors de 1 à 128 ; max_tokens n’est pas positif ; provider.sort n’est pas autorisé ; moderation n’est ni auto ni low (moderation must be auto or low.) ; messages est vide. Aussi lorsque tous les fournisseurs ont refusé la requête comme invalide.
400invalid_request_errorunknown_modelmodel ou modelsLe modèle n’est pas un modèle de chat, ou n’a aucun fournisseur activé.
400invalid_request_errorunsupported_parametertools, response_format, messages ou max_tokensLe modèle n’accepte pas les outils, un format de réponse ou les images ; un outil n’est pas de type function ; ou aucun fournisseur du modèle ne peut borner sa sortie.
400invalid_request_errorcontext_length_exceededmessagesLe prompt et max_tokens dépassent le contexte du modèle.
402insufficient_creditsinsufficient_creditsmax_tokensLe solde ou la limite de la clé ne peut pas couvrir le coût maximal de la requête. Le message indique combien de tokens vous pouvez vous permettre.
429rate_limit_errorvenue_busyTous les fournisseurs du modèle ont dépassé leur budget de débit.
429rate_limit_errorrate_limitedVotre compte dépasse ses requêtes par minute ou ses requêtes simultanées (voir Limites de débit). Rien n’est bloqué ni transmis.
409conflictidempotency_key_replayed, idempotency_key_reused, idempotency_key_in_useVoir Nouvelles tentatives et idempotence.
503upstream_errorall_venues_failedAucun fournisseur n’est en bonne santé, ou tous ont échoué. Non facturé.
503upstream_errorupstream_errorLe fournisseur a accepté la requête et sa réponse s’est interrompue avant le premier token. Facturé sur le montant bloqué (voir Streaming).
503upstream_errortimeoutLe fournisseur a accepté la requête et ne l’a pas terminée à temps. Facturé sur le montant bloqué (voir Streaming).
401, 403, 500Voir Authentification.

Images

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

Les deux suivent l’Images API d’OpenAI et prennent un corps JSON. /v1/images/edits prend la forme JSON d’OpenAI : les images sont images, de 1 à 5 URL https. Le images.edit des OpenAI SDK envoie les fichiers d’image en multipart/form-data, et cela fonctionne aussi : l’edge d’Hyperouter conserve chaque fichier (PNG, JPEG ou WebP, 20 MiB chacun, 50 MiB par requête) pendant 3 jours à une URL https://api.hyperouter.app/u/... impossible à deviner, que le fournisseur récupère, puis exécute la requête comme du JSON. Un fichier vidéo est refusé (400 invalid_video) : envoyez une vidéo sous forme d’URL https. Les deux acceptent les fonctionnalités communes ci-dessous et tous les paramètres propres au modèle comme champs de premier niveau.

Paramètres

NomTypeRequisValeurs autoriséesDéfautDescription
modelstringOuiUn id de modèle d’imageLe modèle à utiliser.
promptstringGenerations : oui. Edits : selon le modèleTexte non videCe qu’il faut produire.
imagesobject[]Edits : oui1 à 5 objets {"image_url": "https://..."}, autant que le modèle en prend. Chaque URL est en https vers un hôte public, jamais une URL data:, une adresse IP ni un nom interne. file_id n’est pas accepté.Les images à modifier. Chaque URL est transmise telle quelle au fournisseur, qui doit donc pouvoir la récupérer ; une URL qu’il ne peut pas récupérer ou lire fait échouer la tâche avec vendor_rejected, sans aucun débit. Un modèle qui les prend dans un ordre précis l’indique dans ses notes de la référence des modèles.
nintegerNon1 à 10, et au plus la limite du modèle1Nombre d’images.
sizestringNonWIDTHxHEIGHT, par exemple 1024x1024 ; le modèle peut autoriser moins de tailles1024x1024Taille de sortie.
qualitystringNonSelon le modèleTransmis au modèle.
response_formatstringNonurlurlLa manière dont l’image est renvoyée : toujours une URL. b64_json est refusé avec 400 unsupported_parameter.
seedintegerNonSi le modèle liste seedSeed pour une sortie reproductible.
negative_promptstringNonSi le modèle le listeCe qu’il faut éviter.
prompt_extendbooleanNonSi le modèle le listeDésactivé sauf demandeLaisser le modèle enrichir le prompt.
prompt_expandbooleanNonSi le modèle le listefalseAjout. Hyperouter réécrit le prompt pour le modèle avant le rendu. Voir Expansion du prompt.
prompt_expand_modelstringNonLe slug d’un modèle de chat que votre compte peut appelerx-ai/grok-4.6Ajout. Avec prompt_expand : le modèle qui écrit la réécriture. Sans prompt_expand: true, c’est 400 invalid_body. Voir Expansion du prompt.
localestringNonUne balise BCP 47, par exemple zh-CNAnglaisAjout. Avec prompt_expand : la langue des répliques, si le modèle la parle.
ratiostringNonSi le modèle le listeFormat d’image.
resolutionstringNon480p, 720p, 1080p, 2K, 4K, selon le modèleRésolution de sortie.
modelsstring[]NonIds de modèles d’imageAjout. Modèles de repli.
providerobjectNononly, ignore, order (tableaux de noms de fournisseurs)Ajout. Préférences de routage.
moderationstringNonauto, lowautoAjout. Voir Modération.
champs propres au modèlecomme déclaréComme déclaréComme déclaréVoir Paramètres propres à chaque modèle.

Une fonctionnalité commune que le modèle ne liste pas, comme seed sur un modèle qui ne l’a pas, est refusée avec 400 unsupported_parameter. Elle n’est jamais ignorée en silence, car cela changerait la sortie et le prix.

Réponse

{
  "created": 1730000000,
  "data": [{ "url": "https://..." }],
  "usage": { "cost": 0.02 },
  "id": "0194f2c4-7a1e-7b3c-9d02-5f6a1c0e8b21"
}
ChampTypeDescription
createdintegerHeure Unix de la requête.
data[].urlstringAvec response_format: "url" : un lien signé, valable 24 heures. GET /v1/generations/{id} en signe un nouveau.
usage.costnumberLe coût en USD, sous forme de nombre JSON.
idstringL’id de la requête. Utilisez-le avec GET /v1/generations/{id}.
expanded_promptstring | nullAjout. Avec prompt_expand : le prompt qui a servi au rendu. null si rien n’a été réécrit.

Hyperouter stocke chaque résultat pendant 30 jours, de sorte qu’un lien ne pointe jamais vers un éditeur. Au-delà de 30 jours, l’enregistrement subsiste mais son outputs est vide.

Attendre le résultat

Exemples

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"}]}'

Erreurs

StatutcodeparamQuand
400unsupported_content_typeLe corps est du multipart/form-data : Send a JSON body; pictures and videos are https URLs.
400invalid_bodyle champLe corps n’est pas du JSON valide ; images n’est pas un tableau d’objets avec image_url ; prompt est absent sur generations ; n est inférieur à 1 ; response_format n’est pas url (response_format must be url. ; b64_json est unsupported_parameter) ; resolution n’est pas autorisée ; un champ typé a le mauvais type ; moderation n’est ni auto ni low.
400unknown_modelmodelLe modèle n’existe pas pour les images, ou aucun fournisseur ne correspond à vos préférences provider.
400invalid_sizesizesize ne ressemble pas à 1024x1024, ou le modèle ne l’autorise pas.
400too_many_imagesn ou imagesn dépasse 10 ou la limite du modèle ; plus de 5 images ; plus d’images que le modèle n’en accepte.
400image_requiredimagesUn edit a moins d’images que le modèle n’en exige, ou vous avez appelé generations sur un modèle qui ne fait que modifier (utilisez /v1/images/edits).
400unsupported_operationimagesLe modèle ne modifie pas les images.
400unsupported_parameterle champLe modèle ne prend pas en charge ce champ ; images[i].file_id.
400invalid_combinationle champL’éditeur n’autorise pas ces champs ensemble.
400async_requiredLe modèle ne répond que de façon asynchrone : envoyez Prefer: respond-async.
400unsupported_parameterstream"stream": true sur un modèle dont les response_modes n’incluent pas stream.
400invalid_imageimages[i].image_urlL’URL n’est pas en https vers un hôte public : images[i].image_url must be an https URL. pour une URL data: ou http://.
400content_rejectedLe filtre de sécurité de l’éditeur a refusé l’entrée : The request was rejected by a content safety filter.
400vendor_rejectedThe request was refused by the model. Check its parameters and inputs.
400invalid_idempotency_keyVoir Nouvelles tentatives et idempotence.
402insufficient_creditsLe solde ou la limite de la clé ne peut pas couvrir le coût maximal de la requête.
409idempotency_key_reused, idempotency_key_in_useVoir Nouvelles tentatives et idempotence.
429rate_limit_errorTous les fournisseurs sont saturés (pas de code), ou votre compte dépasse ses requêtes par minute ou ses requêtes simultanées (code: rate_limited, voir Limites de débit).
503upstream_errorThe model failed to produce a result. You were not charged.
503provider_busyLe fournisseur est resté à pleine capacité pendant environ deux minutes et n’a pas accepté la tâche. Réessayez plus tard. Rien ne vous a été facturé.
500server_error, no_priceHyperouter a échoué, ou le modèle ne peut pas être tarifé pour le moment. Un 500 survenu après la création de l’image porte x-should-retry: false.
503timeoutL’image n’était pas prête au bout de 90 secondes. Elle est toujours en cours de création : error.generation_id est l’id à interroger. Porte x-should-retry: false.

Le message d’une tâche échouée se termine par la raison donnée par le fournisseur, s’il en a donné une, après Provider:, afin de distinguer un prompt refusé, un fournisseur saturé et une panne. Les URL qu’elle contient sont remplacées par <url>.

Modèles d’image

ModèleFonctionPrix
x-ai/grok-imagine-imageGénérer et modifier. Jusqu’à 10 images, jusqu’à 5 images en entrée.$0.02 par image
x-ai/grok-imagine-image-2.0Générer et modifier, comme ci-dessus.À partir de $0.04 par image
qwen/qwen-image-2.0Générer et modifier (1 à 3 images en entrée). n de 1 à 6.$0.035 par image
bytedance/seedream-5.0-flashGénérer et modifier (1 à 10 images en entrée). Une image 2K par requête, sans filigrane.$0.018 par image
bytedance/seedream-5.0-liteGénérer et modifier, comme ci-dessus.$0.035 par image

Certains modèles exigent un accès accordé à votre compte. La référence des modèles du tableau de bord liste tous les modèles que votre compte peut appeler, avec leurs paramètres, leurs prix et leurs notes.

Vidéos

La vidéo suit la Videos API d’OpenAI. Une vidéo est une tâche. Un appel de création, de modification, de prolongation ou de remix répond aussitôt 200 avec l’objet Video au statut queued. Vous interrogez GET /v1/videos/{id} jusqu’à ce que le statut soit completed, ou vous recevez un webhook. Prefer ne change rien ici : les vidéos sont toujours asynchrones.

EndpointFonction
POST /v1/videosCréer une vidéo à partir d’un prompt, avec un input_reference facultatif.
POST /v1/videos/editsModifier ou agrandir une vidéo terminée. Uniquement les modèles qui listent edit dans operations.
POST /v1/videos/extensionsProlonger une vidéo terminée. Uniquement les modèles qui listent extend.
POST /v1/videos/{id}/remixNouveau prompt sur une vidéo terminée, même modèle. Uniquement les modèles qui listent remix.
GET /v1/videosLister vos vidéos.
GET /v1/videos/{id}L’objet Video.
GET /v1/videos/{id}/contentLe MP4 ou la miniature.
DELETE /v1/videos/{id}Supprimer une vidéo.

Créer une vidéo

POST/v1/videos

Le corps est du JSON, sur tous les endpoints vidéo ; le videos.create des OpenAI SDK avec un fichier d’image input_reference est aussi accepté, le fichier étant traité comme pour les modifications d’images. Chaque image et chaque vidéo est une URL https vers un hôte public, transmise telle quelle au fournisseur : il doit pouvoir la récupérer, et une URL qu’il ne peut pas récupérer ou lire fait échouer la vidéo avec vendor_rejected, sans aucun débit. Une URL data:, une URL http://, une adresse IP ou un nom interne est refusé avec 400 invalid_image ou 400 invalid_video. Un corps multipart/form-data est refusé avec 400 unsupported_content_type.

NomTypeRequisValeurs autoriséesDéfautDescription
modelstringOuiUn id de modèle vidéoLe modèle à utiliser.
promptstringOuiTexte non videCe qu’il faut produire.
secondsstring | integerNonSelon le modèleLa première valeur autorisée du modèle, sinon 4 s (ou le maximum du modèle s’il est inférieur)Durée de la vidéo. "8" et 8 sont équivalents.
sizestringNonWIDTHxHEIGHTLa hauteur détermine la résolution, sauf si vous envoyez resolution : jusqu’à 480 donne 480p, jusqu’à 720 donne 720p, jusqu’à 1080 donne 1080p, jusqu’à 1440 donne 2K, au-delà 4K. Le modèle doit autoriser cette résolution.
input_referenceobjectSi le modèle exige une image{"image_url": "https://..."}, une URL httpsLa première image de la vidéo. file_id n’est pas accepté.
resolutionstringNon480p, 720p, 1080p, 2K, 4K, selon le modèleLa première résolution du modèleRésolution de sortie. Elle modifie le prix.
ratiostringNonSi le modèle le listeFormat d’image.
audiobooleanNonSi le modèle produit du sonfalseProduire du son.
seedintegerNonSi le modèle le listeSeed pour une sortie reproductible.
negative_promptstringNonSi le modèle le listeCe qu’il faut éviter.
prompt_extendbooleanNonSi le modèle le listeDésactivé sauf demandeLaisser le modèle enrichir le prompt.
prompt_expand, localeboolean, stringNonComme pour les imagesfalseAjout. Voir Expansion du prompt.
prompt_expand_modelstringNonComme pour les imagesx-ai/grok-4.6Ajout. Avec prompt_expand : le modèle qui écrit la réécriture. Voir Expansion du prompt.
first_frame, last_framestringNonUne URL https d’une imageImages clés.
reference_images, reference_videosstring[]NonURL httpsMédias de référence. Ils ne peuvent pas être combinés avec des images clés, selon la règle de l’éditeur.
models, providerstring[], objectNonComme pour les imagesAjout. Modèles de repli et préférences de routage.
moderationstringNonauto, lowautoAjout. Voir Modération.
champs propres au modèlecomme déclaréComme déclaréComme déclaréVoir Paramètres propres à chaque modèle.

Modifier, prolonger et remixer

EndpointCorps (JSON)
POST /v1/videos/editsmodel, video (requis), prompt, resolution et les fonctionnalités communes. video est {"id": "<your video id>"} (une vidéo terminée qui vous appartient) ou {"url": "https://..."}. model prend par défaut le modèle de la vidéo source lorsque vous envoyez un id.
POST /v1/videos/extensionsmodel, video (requis), prompt, seconds. Les nouvelles secondes suivent les mêmes règles qu’une création.
POST /v1/videos/{id}/remixprompt (requis). Le modèle est celui de la vidéo source.

La vidéo source doit être terminée. Une vidéo donnée par URL est une URL https, transmise telle quelle au fournisseur, comme une image. Si vous donnez une vidéo par URL, seconds est requis sur les modèles qui n’ont pas de maximum fixe.

Lister, lire, télécharger, supprimer

EndpointParamètresRéponse
GET /v1/videosQuery : after (un id de vidéo), limit (1 à 100, 20 par défaut), order (desc par défaut, ou asc){"object":"list","data":[Video],"first_id","last_id","has_more"}. Les vidéos ayant dépassé leur expires_at sont exclues.
GET /v1/videos/{id}L’objet Video.
GET /v1/videos/{id}/contentQuery : variant (video par défaut, ou thumbnail)302 Found vers un lien signé donnant les octets (video/mp4, ou le type de la miniature), valable 15 minutes. Les clients HTTP et les OpenAI SDK le suivent. 404 not_found avant la fin ou lorsqu’il n’y a pas de miniature.
DELETE /v1/videos/{id}{"id","object":"video.deleted","deleted":true}. Répond 409 video_not_finished tant que la tâche s’exécute. Une vidéo supprimée répond 404.

L’objet 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 }
}
ChampTypeDescription
statusstringqueued, in_progress, completed ou failed.
progressinteger0 à 100.
promptstring | nullLe prompt n’est renvoyé que pendant l’exécution de la tâche. L’objet terminé renvoie null.
secondsstringDurée de la vidéo, sous forme de chaîne, comme chez OpenAI.
sizestringLe size que vous avez envoyé, le cas échéant.
expires_atintegerHeure Unix : created_at plus 30 jours. Passé ce délai, GET /v1/videos/{id} et /content répondent 404 not_found et la vidéo est exclue de la liste. Téléchargez ce que vous voulez conserver avant.
errorobject | nullPour une tâche échouée : {"code", "message"}, par exemple content_rejected.
remixed_from_video_idstring | nullLa vidéo source d’une modification, d’une prolongation ou d’un remix.
usageobject | nullRenseigné une fois la tâche réglée : cost (USD, un nombre JSON) et seconds (entier).
expanded_promptstring | nullAjout. Avec prompt_expand : le prompt qui a servi au rendu, une fois la tâche soumise. Conservé 30 jours, puis null.

Une vidéo est facturée sur les secondes que vous demandez. Le montant est bloqué à l’avance, puis libéré intégralement si la tâche échoue.

Exemple : x-ai/grok-imagine-video

Le modèle x-ai/grok-imagine-video produit une vidéo à partir d’un prompt, avec une image de départ facultative. seconds va de 1 à 15. Prix : $0.050 par seconde.

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
}

Cette tâche est facturée 8 × $0.050 = $0.40, de sorte que l’objet réglé affiche "usage": {"cost": 0.4, "seconds": 8}.

Erreurs

StatutcodeparamQuand
400unsupported_content_typeLe corps est du multipart/form-data : Send a JSON body; pictures and videos are https URLs.
400invalid_bodyle champLe corps n’est pas du JSON valide ; prompt est vide ; video n’est pas un objet avec id ou url ; input_reference n’est pas un objet avec image_url ; limit, after ou variant n’est pas valide ; un champ typé a le mauvais type ; resolution n’est pas autorisée ; moderation n’est ni auto ni low.
400unknown_modelmodelLe modèle n’existe pas pour les vidéos.
400invalid_secondssecondsseconds n’est pas autorisé pour le modèle (le message liste les valeurs autorisées), ou est requis pour une vidéo donnée par URL.
400invalid_sizesizesize ne ressemble pas à 1280x720.
400unsupported_parameterle champLe modèle ne prend pas en charge ce champ ; la résolution n’est pas disponible (resolution ou size) ; audio sur un modèle sans son ; input_reference.file_id.
400unsupported_operationmodelLe modèle ne liste pas l’opération (modifier, prolonger ou remixer).
400invalid_combinationle champDes médias de référence avec des images clés, selon la règle de l’éditeur.
400image_requiredinput_referenceThis model needs an input_reference picture.
400video_not_readyvideoLa vidéo source n’est pas terminée.
400invalid_image, invalid_videole champL’URL d’une image (invalid_image) ou d’une vidéo (invalid_video : reference_videos[i], video.url) n’est pas en https vers un hôte public, par exemple une URL data: ou http:// : <field> must be an https URL. param est le champ, par exemple input_reference.image_url, first_frame ou reference_images[1]. Une URL est transmise telle quelle au fournisseur : une URL que le fournisseur ne peut pas récupérer ou lire fait échouer la vidéo avec vendor_rejected, sans aucun débit.
400clip_too_longLe clip de référence et les seconds demandées dépassent la limite du modèle : 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. Il figure dans error.code de l’objet Video.
400content_rejected, vendor_rejectedLa tâche a échoué chez l’éditeur. Cela apparaît dans error.code de l’objet Video.
402insufficient_creditsLe solde ou la limite de la clé ne peut pas couvrir le montant bloqué.
404not_foundCette vidéo n’existe pas, ne vous appartient pas, a été supprimée ou a dépassé expires_at ; ou le contenu n’est pas prêt.
409video_not_finishedVous avez supprimé une vidéo encore en cours de création.
409idempotency_key_reused, idempotency_key_in_useVoir Nouvelles tentatives et idempotence.
429, 503, 500Comme pour les images. Un 500 survenu après la création de la vidéo porte x-should-retry: false.

Modèles vidéo

ModèlePrix par seconde de vidéoNotes
x-ai/grok-imagine-videoÀ partir de $0.050Entrée texte, image ou vidéo. 15 s au plus. Prend en charge edit.
x-ai/grok-imagine-video-1.5À partir de $0.080Entrée texte, image ou référence. 15 s au plus.
x-ai/grok-imagine-video-1.5-liteÀ partir de $0.020Comme ci-dessus, plus petit et moins cher.
bytedance/seedance-2.0À partir de $0.0431892Entrée texte, première et dernière image, ou images de référence, audio facultatif. 4 à 15 s. 480p, 720p, 1080p ou 4K ; le tarif indiqué est celui du 480p.
bytedance/seedance-2.0-fastÀ partir de $0.0331452Entrée texte, première et dernière image, ou images de référence, audio facultatif. 4 à 15 s. 480p ou 720p ; le tarif indiqué est celui du 480p.
bytedance/seedance-2.0-miniÀ partir de $0.0210924Entrée texte, première et dernière image, ou images de référence, audio facultatif. 4 à 15 s. 480p ou 720p ; le tarif indiqué est celui du 480p.
bytedance/seedance-2.5À partir de $0.0642816Entrée texte, première et dernière image, ou images de référence, audio facultatif. 4 à 15 s. 480p, 720p ou 1080p ; le tarif indiqué est celui du 480p.
lumina/berry-1.0À partir de $0.050Entrée texte, image ou référence, audio facultatif. 30 s au plus. 480p, 720p ou 1080p ; le tarif indiqué est celui du 480p.
minimax/minimax-h3À partir de $0.080Entrée texte, première et dernière image, ou images de référence, sans audio. 4 à 15 s, en 768p ou 2K.
alibaba/wan3.0À partir de $0.050Entrée texte, image ou référence, audio facultatif. 30 s au plus. 480p, 720p ou 1080p ; le tarif indiqué est celui du 480p.

La référence des modèles du tableau de bord liste tous les modèles vidéo que votre compte peut appeler.

Generations

GET/v1/generations/{id}

Renvoie l’enregistrement de l’une de vos requêtes, de n’importe quel type : son statut, sa consommation, son coût, ses durées et, pour les images et les vidéos, des liens signés vers les sorties. Utilisez-le pour interroger une requête d’image envoyée avec Prefer: respond-async et pour rapprocher vos dépenses. Le texte des prompts et des completions ne figure jamais dans l’enregistrement. Hyperouter les conserve chiffrés pendant 180 jours uniquement pour respecter ses obligations légales, et aucune API ni page du tableau de bord ne les renvoie (Politique de confidentialité).

Paramètres

NomDansTypeRequisDescription
idpathstring (UUID)OuiL’id d’une chat completion, d’une réponse d’image ou d’un objet Video.

Réponse

{
  "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": []
  }
}
ChampTypeDescription
kindstringchat, image ou video.
provider_namestring | nullLe fournisseur qui a servi une requête de chat terminée. null pour les images et les vidéos.
statusstringqueued, submitting, running, done ou failed.
created_at, finished_atstring | nullRFC 3339 UTC. finished_at vaut null tant que la requête n’est pas terminée.
usageobjectinput_tokens, output_tokens, cache_read_tokens, image, video_seconds et cost. cost est le coût en USD, un nombre JSON. Les compteurs valent 0 tant que la requête n’est pas terminée.
usage_estimatedbooleantrue lorsque le fournisseur n’a envoyé aucun décompte de tokens et qu’Hyperouter les a comptés.
ttft_ms, latency_msinteger | nullTemps jusqu’au premier token et temps total, en millisecondes.
errorobject | null{"code", "message"} lorsque la requête a échoué.
outputsobject[]Pour les images et les vidéos : [{"url", "expires_at"}], des liens signés valables 24 heures. Disponibles pendant 30 jours après la requête ; ensuite outputs est vide et l’enregistrement subsiste. Toujours vide pour le chat.
expanded_promptstring | nullPour les images et les vidéos envoyées avec prompt_expand : le prompt qui a servi au rendu. Conservé 30 jours après la requête, puis null.
curl https://api.hyperouter.app/v1/generations/0194f2c4-7a1e-7b3c-9d02-5f6a1c0e8b21 \
  -H "Authorization: Bearer $HYPEROUTER_API_KEY"

Erreurs

StatuttypecodeparamQuand
404not_foundnot_foundidNo generation with that id. L’id n’est pas un UUID, n’existe pas, appartient à un autre compte ou a été supprimé.
500server_errorserver_errorHyperouter n’a pas pu lire ou signer l’enregistrement.
401, 403Voir Authentification.

Paramètres propres à chaque modèle

Certains modèles ont des champs que d’autres n’ont pas. Ce sont les paramètres supplémentaires. Vous les envoyez comme champs de premier niveau du corps de la requête, comme n’importe quel autre champ. Tous les OpenAI SDK peuvent les envoyer (extra_body en Python, propriétés supplémentaires en JavaScript).

GET /v1/models liste les paramètres supplémentaires de chaque modèle dans extra_parameters. Chaque entrée comporte :

ChampTypeDescription
typestringL’un de string, integer, number, boolean, array, object.
valuesarrayLes valeurs autorisées. Vide signifie n’importe quelle valeur du type.
price_conditionbooleantrue lorsque le champ modifie le prix.
descriptionstringCe que fait le champ.

La référence des modèles du tableau de bord décrit les paramètres supplémentaires de chaque modèle que votre compte peut appeler.

Règles

Fonctionnalités communes

Ces champs portent le même nom sur tous les modèles qui les ont. Un modèle liste ceux qu’il accepte dans supported_parameters.

ChampSignification
resolution480p, 720p, 1080p, 2K ou 4K, selon le modèle.
ratio, seed, negative_prompt, prompt_extend, audioComme leur nom l’indique. audio et prompt_extend sont désactivés sauf demande.
first_frame, last_frameImages clés pour la vidéo.
reference_images, reference_videosMédias de référence pour la vidéo et la modification d’images.

Expansion du prompt

Avec "prompt_expand": true, Hyperouter réécrit votre prompt pour le modèle avant le rendu : une description plus complète pour une image, un script seconde par seconde pour une vidéo. Elle est désactivée par défaut : le prompt part tel quel. Seul un modèle dont supported_parameters liste prompt_expand l’accepte, et uniquement pour créer une image ou une vidéo ; sur tout autre modèle, et pour une modification, une extension ou un remix de vidéo, elle est refusée avec 400 unsupported_parameter. Elle ne peut pas non plus être combinée avec prompt_extend: true (400 invalid_body).

L’expansion du prompt est disponible pour un compte une fois que Hyperouter l’a activée ; ouvrez un ticket de support pour en demander l’accès. D’ici là, GET /v1/models ne liste prompt_expand pour aucun modèle, et une requête avec prompt_expand: true sur un modèle qui le propose répond 403 permission_error, code feature_not_enabled, param prompt_expand, sans rien réserver ni envoyer au fournisseur.

La réécriture comme modèle de chat

Un compte doté de l’expansion du prompt dispose aussi d’un modèle de chat qui renvoie la réécriture au lieu de la rendre ; votre référence des modèles le nomme. Appelez-le sur POST /v1/chat/completions avec exactement un message user : son texte est le prompt, et ses parties image_url (URL https, 5 au plus) sont les images ; une URL data: ou http:// renvoie 400 invalid_image avec param valant messages. target_model est obligatoire : un modèle qui liste prompt_expand. seconds, locale et negative_prompt sont facultatifs. Une cible vidéo accompagnée d’une image est écrite à partir de cette première image. Il ne diffuse pas en streaming (stream: true renvoie 400 unsupported_parameter), et tout autre message, message system compris, renvoie 400 invalid_body.

Ce modèle de chat utilise toujours x-ai/grok-4.6 ; il n’accepte pas prompt_expand_model. choices[0].message.content est une chaîne JSON, {"prompt": "...", "negative_prompt": "..."}, plus "beats" (une ligne par seconde) pour une cible vidéo. Il est facturé aux prix par token de x-ai/grok-4.6, indiqués dans usage. Un prompt qui demande les instructions du modèle renvoie 400 prompt_rejected ; une réécriture refusée ou vide renvoie 422 expansion_refused, et une réécriture en échec 503 upstream_error. Aucun de ces cas n’est facturé.

Modération

Le champ moderation est celui d’OpenAI. Il fonctionne sur /v1/chat/completions, /v1/images/generations, /v1/images/edits et /v1/videos avec ses appels de modification, de prolongation et de remix.

ValeurSignification
auto (par défaut)Le filtrage propre à l’éditeur s’applique. Hyperouter n’envoie rien de plus.
lowHyperouter envoie la désactivation du filtrage prévue par le fournisseur, sur les modèles où le fournisseur en propose une. Sur les autres modèles, low est ignoré sans erreur, comme le fait OpenAI. L’entrée de chaque modèle dans votre référence des modèles indique s’il en propose une. Envoyez moderation dans le corps : un en-tête ou un champ de filtrage propre au fournisseur n’est pas transmis sur ces endpoints.

Toute autre valeur est refusée : 400 invalid_request_error, code invalid_body, param moderation, message moderation must be auto or low.

low est disponible pour un compte une fois qu’Hyperouter l’a activé ; ouvrez un ticket de support pour le demander. D’ici là, une requête avec low répond 403 permission_error, code moderation_not_enabled, param moderation, et n’est pas envoyée au fournisseur.

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

La réponse n’indique pas si la désactivation a été utilisée. Les politiques des Conditions d’utilisation continuent de s’appliquer. Une requête que le filtre de l’éditeur refuse échoue avec 400 content_rejected et n’est pas facturée.

Webhooks

Au lieu d’interroger, un de vos endpoints peut recevoir une requête lorsqu’une tâche se termine. Ajoutez des endpoints dans le tableau de bord. Le format est celui des webhooks d’OpenAI, signé selon le schéma Standard Webhooks, de sorte que les OpenAI SDK les vérifient.

ÉvénementEnvoyé quand
video.completed, video.failedUne tâche vidéo se termine.
image.completed, image.failedUne tâche d’image que vous avez envoyée avec Prefer: respond-async se termine.
raw.completed, raw.failedLa tâche d’un appel brut se termine (comptes dotés des appels bruts) : facturée, ou son blocage libéré. Un appel brut qui répond directement n’en envoie aucun.

Le payload porte un id, jamais un résultat, un prompt ou un coût. Récupérez l’objet avec votre clé API : data.id est l’id que prennent GET /v1/videos/{id} et GET /v1/generations/{id}. Pour une tâche brute, c’est le X-Generation-Id renvoyé par la création.

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

En-têtes et vérification

Chaque livraison est un POST avec content-type: application/json et ces en-têtes :

Le secret de signature commence par whsec_. Il n’est affiché qu’une fois, à la création de l’endpoint et lors de sa rotation. Vérifiez le corps brut de la requête, avant de l’analyser :

// 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 lève une exception lorsque la signature ne se vérifie pas ; répondez à une telle requête par un statut d’erreur. L’appel suivant utilise la même URL de base que le reste de cette API.

Endpoints, nouvelles tentatives et limites

Serveur MCP

POSThttps://api.hyperouter.app/mcp

Un assistant IA peut travailler avec votre compte Hyperouter via le Model Context Protocol (MCP). Le serveur gère le tableau de bord : clés API, activité, crédits, tickets, webhooks et liste des modèles. Il n’exécute pas de modèles. Les appels aux modèles continuent d’aller vers /v1 avec une clé API.

Le serveur parle Streamable HTTP et JSON-RPC 2.0. Il prend en charge les révisions MCP 2025-11-25 et 2025-06-18. Il est sans état : il n’y a pas de sessions, et GET /mcp répond 405.

Jetons d’accès

Un client MCP s’authentifie avec un jeton d’accès du tableau de bord, pas avec une clé API.

PortéeOutils que le jeton peut appeler
readLes outils qui ne font que lire des données.
writeTous les outils que l’utilisateur a la permission d’utiliser.

Envoyez le jeton comme bearer token :

Authorization: Bearer hr_dt_...

Protocole

MéthodeRéponse
initializeLa version du protocole (celle du client, si elle est prise en charge ; sinon 2025-11-25), la capacité tools et les informations du serveur.
pingUn résultat vide.
tools/listLes outils que l’utilisateur et la portée du jeton autorisent.
tools/callLe résultat d’un outil.

Une notification, ou une réponse adressée au serveur, répond 202 sans corps. Un lot JSON-RPC est refusé avec l’erreur -32600. Un message ne doit pas dépasser 1 MiB. Un en-tête MCP-Protocol-Version inconnu répond 400. Une requête de navigateur doit provenir de https://dash.hyperouter.app ; un client qui n’envoie pas d’en-tête Origin n’est pas concerné.

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"}'

Outils

tools/list renvoie l’ensemble actuel des outils. Chaque outil correspond à une route du tableau de bord et porte un JSON Schema pour ses arguments. Les outils couvrent :

Un outil répond avec un seul élément de contenu texte qui contient le corps JSON de la route. Lorsque la route échoue, le résultat porte isError: true et le texte <message> (<code>, HTTP <status>). Un outil inconnu, ou que votre jeton ne peut pas voir, donne l’erreur JSON-RPC -32602.

Approbations

Une écriture sensible, comme créditer un compte, n’est pas exécutée immédiatement. L’outil ne l’exécute pas. Il répond avec status défini sur approval_required et une approval_url sur le tableau de bord. L’utilisateur ouvre le lien, confirme avec un second facteur et approuve l’action. Une approbation expire au bout de 24 heures. L’utilisateur peut aussi la rejeter.

Facturation et limites

Limites de débit

Chaque compte a une limite de requêtes par minute et de requêtes en cours simultanément. Les deux comptent ensemble toutes les clés API du compte, et s’appliquent à chaque requête qui démarre un travail : chat completions, créations d’images et de vidéos, et créations brutes. Lire un résultat (GET /v1/generations/{id}, GET /v1/videos…, une interrogation de tâche brute) ne compte pas ; les interrogations brutes sont comptées à part, par fournisseur, avec la même limite de requêtes par minute.

Votre palier dépend du total que vous avez rechargé, avant déduction des frais de recharge :

PalierRechargéRequêtes par minuteRequêtes simultanées
1Moins de $106010
2$10 ou plus30030
3$100 ou plus1,200100
4$1,000 ou plus6,000300

Vos limites actuelles figurent sur la page Crédits. Ce sont les valeurs par défaut ; notre équipe peut les modifier pour la plateforme ou pour un compte, et un changement s’applique en moins d’une minute.

Au-delà de l’une ou l’autre limite, la requête est refusée avant que quoi que ce soit ne soit bloqué ou transmis, avec 429, type: rate_limit_error, code: rate_limited et un en-tête Retry-After en secondes. Le message nomme la limite atteinte. Une requête compte pour la minute même lorsqu’elle est refusée. Une requête en cours, flux compris, compte jusqu’à sa fin.

Pour se protéger contre la devinette de clés, Hyperouter compte les vérifications de clé API échouées par adresse client. Plus de 30 en une minute bloquent cette adresse sur toutes les routes /v1 pendant 15 minutes : 429, rate_limit_error, too_many_auth_failures, avec Retry-After. Une clé valide ne lève pas le blocage.

Support

Ouvrez un ticket dans le tableau de bord pour la facturation, les recharges et les questions sur l’API ; notre équipe répond dans le même fil. Vous pouvez aussi écrire à [email protected]. Veuillez indiquer l’id de la réponse lorsque vous signalez une requête précise.