HiAPI
Blog

Tutoriel

Comment utiliser mureka-9.5/instrumental via l'API HiAPI : guide curl et Python

Nov 3, 2026
棕褐与燕麦色调的宽织物条带交织封面图,呈扁平织机图式的篮纹节奏,点缀克制的黄铜色细条。

Les fonctionnalités de mureka-9.5/instrumental sur HiAPI

mureka-9.5/instrumental est un point de terminaison de génération musicale à partir de texte sur HiAPI, spécialement optimisé pour les sorties purement instrumentales : musique de fond, boucles, nappes musicales et musiques de scène. Vous décrivez le morceau avec un prompt, soumettez une tâche unique, et HiAPI renvoie une ressource audio finie que vous pouvez télécharger et intégrer dans un jeu, un montage vidéo, un podcast ou une démo produit.

Le mot instrumental est essentiel. Ce point de terminaison cible une musique sans performance vocale principale, ce qui le rend adapté aux scénarios où une narration ou un dialogue doit rester clairement intelligible. Si vous avez besoin de morceaux chantés avec paroles, c'est un autre problème ; si vous avez besoin d'une musique de fond propre sous une voix off, c'est le bon outil.

Choisissez ce point de terminaison lorsque :

  • Vous voulez générer une musique de fond (BGM) plutôt que d'en puiser dans une bibliothèque musicale.
  • Vous avez besoin de générer rapidement et par programmation un grand nombre de variantes, plutôt qu'une commande sur mesure ponctuelle.
  • Votre pipeline utilise déjà HTTP et vous voulez traiter la musique comme n'importe quelle autre étape de génération de ressource.
  • Vous tenez à une forme de requête prévisible : soumettre, interroger, télécharger.

Comme avec les autres points de terminaison de génération musicale, le travail est asynchrone. La soumission renvoie une tâche que vous devez suivre jusqu'à la génération de l'audio. Concevez votre code autour de cela dès le départ, et le reste de l'intégration devient une routine.

Où cela s'insère dans un produit

L'utilisateur type est un pipeline de contenu qui a besoin de morceaux à la demande : un moteur de rendu vidéo qui veut une couche musicale sous chaque clip, un jeu qui veut une boucle d'ambiance, ou un outil de prototypage qui laisse l'utilisateur saisir une ambiance et écouter le résultat. Comme ce point de terminaison est piloté par du texte, vous pouvez modéliser le prompt à partir des métadonnées dont vous disposez déjà — genre, sensation rythmique, ambiance et durée prévue — et générer au moment du rendu.

Traitez chaque requête comme une tâche de génération dotée de son propre cycle de vie. Ce cadre garde votre logique de nouvelle tentative, votre journalisation et votre comptabilisation des coûts raisonnables.

Préparatifs avant d'envoyer la requête

Plusieurs conditions doivent être remplies avant le premier appel réussi. Aucune n'est compliquée, mais en omettre une est la cause la plus fréquente d'échec de la première requête.

Identifiants

Vous avez besoin d'une clé API HiAPI. Traitez-la comme un secret : chargez-la depuis une variable d'environnement comme HIAPI_API_KEY, ne la codez jamais en dur dans un script que vous soumettez, et renouvelez-la en cas de fuite. La clé est envoyée sous forme de jeton bearer via l'en-tête Authorization.

export HIAPI_API_KEY="your_api_key_here"

Point de terminaison et transport

Vous appelez le modèle mureka-9.5/instrumental via l'API unifiée HiAPI. L'URL de base est l'hôte de l'API HiAPI ; l'identifiant du modèle est placé dans la charge utile de la requête ou dans le chemin selon la convention documentée par HiAPI pour ce point de terminaison. Utilisez HTTPS, envoyez Content-Type: application/json et envoyez un corps JSON.

Ne devinez pas les noms de paramètres. HiAPI documente les champs acceptés par ce modèle ; tout ce qui sort de cet ensemble est au mieux ignoré, au pire rejeté. Si un champ que vous voulez n'est pas documenté, il ne fait pas partie du contrat — construisez autour de ce qui existe.

Ce qu'il faut préparer

  • Un prompt décrivant la musique : genre, instrumentation, ambiance, sensation rythmique et usage prévu.
  • Les options de durée ou de variantes documentées et exposées par le modèle.
  • Un endroit pour stocker l'identifiant de tâche et, plus tard, l'URL de téléchargement.
  • Un accès réseau depuis l'emplacement d'exécution du code vers l'hôte HiAPI.

Une note sur le temps

La génération n'est pas instantanée. Réglez les délais d'attente du client de façon généreuse et prévoyez d'interroger le statut. Une approche synchrone — envoyer la requête et bloquer jusqu'à ce que l'audio revienne dans la même réponse — conduit à un code instable.

Une requête curl fonctionnelle

Commencez par curl. Il supprime toutes les couches entre vous et le dialogue HTTP, ce qui vous permet de voir immédiatement si quelque chose ne va pas.

L'appel

curl -sS -X POST "$HIAPI_BASE_URL" \
  -H "Authorization: Bearer $HIAPI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "mureka-9.5/instrumental",
    "input": {
      "prompt": "warm lo-fi hip hop instrumental, mellow electric piano, soft vinyl crackle, relaxed 80 bpm, no vocals"
    }
  }'

Définissez d'abord ces deux variables d'environnement, afin qu'aucune information sensible ne reste en clair dans l'historique du shell en dehors du contenu que vous choisissez :

export HIAPI_BASE_URL="https://api.hiapi.ai/v1/..."   # utilisez le chemin documenté pour ce point de terminaison
export HIAPI_API_KEY="your_api_key_here"

Le rôle de chaque partie

  • -X POST — la soumission est une opération de création.
  • -H "Authorization: Bearer ..." — authentifie l'appel auprès de votre compte.
  • -H "Content-Type: application/json" — indique au serveur que le corps est du JSON ; si vous l'omettez, de nombreux serveurs rejettent simplement le corps.
  • -d '{...}' — la charge utile JSON. Le champ model indique le point de terminaison ; l'objet input porte votre prompt et les autres champs documentés.
  • -sS — mode silencieux pour la progression, mais affiche tout de même les erreurs. Utile dans les scripts.

Lire la réponse

La réponse est du JSON. Vous cherchez un identifiant de tâche ou de job ainsi qu'un champ de statut. Affichez-la joliment pour l'inspecter :

curl -sS -X POST "$HIAPI_BASE_URL" \
  -H "Authorization: Bearer $HIAPI_API_KEY" \
  -H "Content-Type: application/json" \
  -d @payload.json | jq .

Conservez l'identifiant. C'est le handle de chaque vérification de statut ultérieure. Ne parsez pas tout le corps de réponse dans votre application ; extrayez l'ID de tâche et le statut, et stockez la réponse brute pour le débogage.

Si vous obtenez un statut non 2xx, lisez le corps — HiAPI renvoie des messages d'erreur structurés, qui indiquent généralement le champ problématique.

La même requête en Python

La version Python correspond exactement à l'appel curl : mêmes en-têtes, même corps JSON. Utilisez requests pour la concision, ou la bibliothèque standard si vous voulez zéro dépendance.

Avec requests

import os
import requests

API_KEY = os.environ["HIAPI_API_KEY"]
BASE_URL = os.environ["HIAPI_BASE_URL"]

payload = {
    "model": "mureka-9.5/instrumental",
    "input": {
        "prompt": (
            "warm lo-fi hip hop instrumental, mellow electric piano, "
            "soft vinyl crackle, relaxed 80 bpm, no vocals"
        )
    },
}

headers = {
    "Authorization": f"Bearer {API_KEY}",
    "Content-Type": "application/json",
}

resp = requests.post(BASE_URL, json=payload, headers=headers, timeout=30)
resp.raise_for_status()
data = resp.json()
job_id = data["id"]          # use the documented field name
print("submitted:", job_id, data.get("status"))

Avec la bibliothèque standard

Si vous ne pouvez pas ajouter de dépendance :

import json, os, urllib.request

req = urllib.request.Request(
    os.environ["HIAPI_BASE_URL"],
    data=json.dumps(payload).encode("utf-8"),
    headers={
        "Authorization": f"Bearer {os.environ['HIAPI_API_KEY']}",
        "Content-Type": "application/json",
    },
    method="POST",
)
with urllib.request.urlopen(req, timeout=30) as r:
    data = json.load(r)

Bonnes habitudes

  • N'utilisez timeout=30 que pour la soumission. L'interrogation du statut nécessite sa propre boucle et son propre délai d'attente.
  • Appelez raise_for_status() avant de parser. Le corps d'une réponse d'erreur n'est pas une tâche.
  • Enveloppez l'extraction de l'ID de tâche dans une petite fonction utilitaire, afin qu'un changement de nom de champ ne nécessite qu'une correction d'une ligne.
  • Ne journalisez jamais la clé API ; journalisez plutôt l'ID de tâche et le statut.
  • Gardez la charge utile sous forme de dictionnaire dans le code, sérialisez-la une fois, afin que les tests puissent faire des assertions dessus.

Gérer les tâches asynchrones et l'interrogation

La soumission n'est que la première étape. La génération se fait côté serveur et se termine plus tard ; vous interrogez donc le point de terminaison de statut jusqu'à ce que la tâche signale un état terminal.

La forme de la boucle

  1. Soumettez la tâche, capturez l'ID.
  2. Patientez brièvement.
  3. Interrogez le statut de cet ID.
  4. Si le statut est en file d'attente ou en traitement, appliquez un backoff et répétez.
  5. Si le statut est un statut de succès, lisez la sortie.
  6. Si le statut est un statut d'échec, journalisez l'erreur et arrêtez — ne réessayez pas aveuglément.

Une implémentation fiable

import time, random, requests

def wait_for_job(job_id, base_status_url, headers,
                 timeout_s=600, initial_delay=2.0, max_delay=30.0):
    deadline = time.monotonic() + timeout_s
    delay = initial_delay

    while time.monotonic() < deadline:
        r = requests.get(f"{base_status_url}/{job_id}", headers=headers, timeout=30)
        r.raise_for_status()
        status = r.json()["status"]

        if status in ("succeeded", "completed", "success"):
            return r.json()
        if status in ("failed", "error", "cancelled"):
            raise RuntimeError(f"job {job_id} ended as {status}: {r.text}")

        time.sleep(delay + random.uniform(0, 0.5))   # jitter
        delay = min(delay * 1.5, max_delay)          # exponential backoff

    raise TimeoutError(f"job {job_id} did not finish in {timeout_s}s")

Pourquoi chaque détail compte

  • Le jitter évite des nouvelles tentatives synchronisées lorsque plusieurs tâches s'exécutent en parallèle.
  • Le backoff évite de marteler le point de terminaison de statut pendant que le morceau se rend.
  • La date limite transforme une attente infinie en une exception propre que le pipeline peut traiter.
  • La vérification des états terminaux doit correspondre aux chaînes de statut documentées par HiAPI. Confirmez-les dans la référence de l'API plutôt que de faire confiance à une supposition.
  • Les nouvelles tentatives doivent porter sur des erreurs réseau transitoires (timeouts, 5xx), et non sur une tâche déjà échouée à cause d'une erreur de validation.

Conseils d'exploitation

Persistez le job_id avant de commencer à interroger. Si votre processus meurt, vous pouvez reprendre l'interrogation au lieu de payer pour une seconde génération. Journalisez les transitions de statut horodatées, afin de voir où le temps est passé. Si vous exécutez de nombreuses tâches, interrogez en parallèle un petit nombre de tâches via une file d'attente, plutôt que de bloquer un thread de requête sur chaque tâche.

Obtenir la sortie instrumentale et la télécharger

Le mode instrumental s'exprime par votre requête, ce point de terminaison étant dédié à ce type de sortie. En pratique, la formulation du prompt renforce cela : nommez les instruments, décrivez l'ambiance et déclarez l'absence de voix. Un prompt demandant une ligne vocale entre en conflit avec l'objectif du point de terminaison.

Où apparaît l'audio

Lorsque la tâche atteint un état de succès, la réponse de statut porte le résultat. Attendez-vous à ce que l'audio soit livré sous forme d'URL récupérée séparément, et non en base64 dans le JSON de statut. Lisez la réponse et extrayez l'URL de téléchargement depuis le champ de sortie documenté.

result = wait_for_job(job_id, status_url, headers)
# inspectez le résultat avec soin les premières fois, puis figez le champ.
audio_url = result["output"]["audio_url"]   # confirmez le nom du champ dans la référence de l'API

with requests.get(audio_url, stream=True, timeout=60) as r:
    r.raise_for_status()
    with open(f"{job_id}.mp3", "wb") as f:
        for chunk in r.iter_content(chunk_size=65536):
            f.write(chunk)

Bonnes habitudes de téléchargement

  • Écrivez en flux sur le disque. Les fichiers musicaux sont volumineux ; les charger entièrement en mémoire est une pression évitable.
  • Vérifiez le type de contenu. Enregistrez le fichier avec l'extension suggérée par la réponse, et non une extension codée en dur.
  • Considérez l'URL comme temporaire. Téléchargez rapidement, ou ne persistez l'URL que si la documentation indique qu'elle est stable. Copiez les octets dans votre propre stockage pour une conservation durable.
  • Ne récupérez qu'une fois. Télécharger dans une boucle de nouvelle tentative sans marqueur d'achèvement crée facilement des fichiers partiels. Écrivez sous un nom temporaire, puis renommez en cas de succès.
  • Enregistrez la provenance. Stockez l'ID de tâche et le prompt avec le fichier. Lorsque vous aurez besoin d'une variante plus tard, vous aurez les entrées exactes.

Points d'échec courants et correctifs

La plupart des problèmes d'intégration initiale se retrouvent dans une courte liste. Voici la liste de vérification.

401 / 403 — authentification. L'en-tête est incorrect, la clé manque, ou la variable d'environnement se résout en chaîne vide. Vérifiez que la clé est définie dans le même shell ou processus que celui qui exécute le code, et que l'en-tête se lit exactement Authorization: Bearer <key>.

400 — charge utile mal formée. Champ model manquant, faute de frappe dans mureka-9.5/instrumental, JSON invalide, ou champ non accepté par le point de terminaison. Envoyez d'abord le corps avec curl pour isoler la charge utile du code. Validez le JSON avant l'envoi ; les virgules finales sont un problème classique.

415 ou erreur de corps vide — type de contenu. Content-Type: application/json doit être présent. Certains clients HTTP le définissent automatiquement lorsque vous passez json=, mais pas tous.

Délai d'interrogation dépassé. Votre date limite est trop courte, votre backoff trop agressif, ou la tâche a effectivement échoué alors que vous l'avez classée comme toujours en cours. Vérifiez les chaînes de statut exactes dans la documentation et imprimez chaque transition de statut pendant le débogage.

URL de téléchargement manquante. Vous avez lu le mauvais champ, ou vous avez lu la réponse avant que la tâche n'atteigne l'état terminal de succès. Enregistrez une fois une charge utile de succès complète, confirmez le chemin de l'URL audio, puis figez-le.

Génération en double. Votre interogateur a planté et quelque chose a resoumis. Persistez l'ID de tâche avant d'interroger, et vérifiez les tâches existantes avant d'en soumettre une nouvelle.

Limitation de débit. Appliquez un backoff avec jitter sur les réponses 429, et mettez le travail en file d'attente plutôt que de le lancer simultanément depuis de nombreux threads.

Traitez-les dans cet ordre — authentification, charge utile, type de contenu, interrogation, sortie — et vous trouverez généralement la cause du premier coup. Une fois que l'appel curl et son équivalent Python réussissent de bout en bout, le point de terminaison fait ce que vous lui demandez : transformer un prompt en morceau instrumental et vous remettre une URL de téléchargement.

Articles similaires

Voir tous les articles →

Commencez avec des artefacts IA persistants

Obtenez votre clé API et appelez des modèles d'image, de vidéo et d'audio via une API unique basée sur les tasks.

Lire la documentation de l'API