Tutorial
PixVerse V6 Text-zu-Video-API: Ein curl- und Python-Beispiel, das tatsächlich funktioniert
- Modell
- pixverse-v6
Mit pixverse-v6/text-to-video auf hiapi ein Video zu erzeugen, ist im Kern ein POST /v1/tasks plus eine Runde Polling – exakt dasselbe asynchrone Aufgabenmuster, das jedes generative Modell auf der Plattform verwendet. Dieser Artikel liefert dir direkt kopierbare curl- und Python-Beispiele, die Eingabefelder, die der Endpoint tatsächlich validiert, sowie den Aufgaben-Lebenszyklus und die Stolperfallen, die ich bei einem tatsächlich durchgeführten Generierungslauf festgehalten habe.
Was du vor dem Start brauchst
- Einen hiapi API-Key. Erstelle ihn im Dashboard und übergib ihn per Header
Authorization: Bearer sk-<dein key>. Das Header-Format findest du in der Authentifizierungsdokumentation. - Die model id lautet
pixverse-v6/text-to-video. Behalte den Schrägstrich in der Mitte bei – er gehört zur id und ist kein URL-Pfad. - curl benötigt keine Installation; das Python-Beispiel verwendet nur die Standardbibliothek plus
requests.
PixVerse V6 Text-zu-Video verwandelt einen Text-Prompt in einen 1–15 Sekunden langen Videoclip mit 360p–1080p. Es nutzt die einheitliche asynchrone Aufgaben-API: Aufgabe einreichen → Ergebnis pollen → das Video herunterladen, bevor die Ausgabe-URL abläuft.
Minimaler lauffähiger Request (curl)
Reiche die Aufgabe bei POST /v1/tasks ein:
curl -s -X POST https://api.hiapi.ai/v1/tasks \
-H "Authorization: Bearer sk-<dein key>" \
-H "Content-Type: application/json" \
-d '{
"model": "pixverse-v6/text-to-video",
"input": {
"prompt": "Am Morgen im Sonnenlicht trottet ein roter Fuchs durch frisch gefallenen Schnee, filmische Optik, Zeitlupe",
"aspect_ratio": "16:9",
"duration": 5,
"resolution": "720p"
}
}'
In der Antwort erhältst du eine Aufgaben-id:
{ "code": 200, "data": { "taskId": "tk-hiapi-...." }, "message": "success" }
Dann pollst du GET /v1/tasks/<taskId>, bis data.status zu success wird:
curl -s https://api.hiapi.ai/v1/tasks/tk-hiapi-.... \
-H "Authorization: Bearer sk-<dein key>"
Nach Erfolg steht die URL des fertigen Videos in data.output[0].url:
{
"code": 200,
"data": {
"status": "success",
"storage": "temp",
"output": [
{ "type": "video", "url": "https://temp.hiapi.ai/....mp4", "expireAt": 1793036664 }
]
},
"message": "success"
}
Diese Ausgabe-URL ist temporär – sie enthält einen expireAt-Zeitstempel (gemessen: 7 Tage nach der Generierung). Lade die .mp4 sofort herunter und speichere sie in deinem eigenen Objektspeicher; verlinke diese Adresse nicht direkt per Hotlink.
Derselbe Ablauf (Python)
import time, requests
BASE = "https://api.hiapi.ai/v1/tasks"
HEADERS = {"Authorization": "Bearer sk-<dein key>", "Content-Type": "application/json"}
def create_task():
payload = {
"model": "pixverse-v6/text-to-video",
"input": {
"prompt": "Am Morgen im Sonnenlicht trottet ein roter Fuchs durch frisch gefallenen Schnee, filmische Optik, Zeitlupe",
"aspect_ratio": "16:9",
"duration": 5,
"resolution": "720p",
},
}
r = requests.post(BASE, json=payload, headers=HEADERS, timeout=60)
r.raise_for_status()
data = r.json()
task_id = (data.get("data") or {}).get("taskId")
if not task_id:
raise RuntimeError(f"Erstellung fehlgeschlagen: {data}")
return task_id
def wait_for(task_id, timeout_s=600):
deadline = time.time() + timeout_s
while time.time() < deadline:
try:
r = requests.get(f"{BASE}/{task_id}", headers=HEADERS, timeout=30)
task = (r.json().get("data") or {})
except requests.RequestException:
time.sleep(5) # ein einzelner Netzwerk-Aussetzer sollte nicht das gesamte Polling abbrechen
continue
status = task.get("status")
if status == "success":
return task["output"][0]["url"]
if status == "fail":
raise RuntimeError(f"Aufgabe fehlgeschlagen: {task.get('error')}")
time.sleep(5) # noch in der Warteschlange/in der Wiedergabe – mit derselben task_id weiter pollen
raise TimeoutError(task_id)
task_id = create_task()
url = wait_for(task_id)
video = requests.get(url, timeout=120).content
open("out.mp4", "wb").write(video)
print("out.mp4 gespeichert")
Die Polling-Schleife prüft nur die beiden Endzustände success und fail; bei allen anderen Status wartet sie einfach weiter – so kann der Code weder handling noch archiving während der Wiedergabe fälschlich interpretieren. Entscheidend: Wenn ein einzelner Polling-Request selbst fehlschlägt, warte kurz und frage mit derselben gespeicherten task_id erneut ab, statt die Aufgabe neu einzureichen – eine erneute Einreichung rendert noch einmal und berechnet noch einmal.
Die Parameter, die pixverse-v6/text-to-video tatsächlich validiert
Die folgenden Felder akzeptiert der Endpoint tatsächlich. Jedes davon habe ich bestätigt, indem ich einen ungültigen Wert gesendet und die eigene Validierungsfehlermeldung zurückgelesen habe, und mit der Modell-Dokumentation abgeglichen:
| Feld | Typ | Wert / Bereich | Standardwert | Beschreibung |
|---|---|---|---|---|
prompt |
string | 1–2048 Bytes UTF-8 (1 chinesisches Zeichen = 3 Bytes, ca. 682 Zeichen) | — | Pflichtfeld. |
aspect_ratio |
enum | 16:9, 4:3, 1:1, 3:4, 9:16, 2:3, 3:2, 21:9 |
16:9 |
Beachte, dass 21:9 (Ultrabreit) sowie 2:3/3:2 unterstützt werden. |
duration |
integer | 1–15 |
5 |
Einheit Sekunden, muss eine Ganzzahl sein, kein String. |
resolution |
enum | 360p, 540p, 720p, 1080p |
720p |
Ausgabeauflösung. |
generate_audio |
boolean | true / false |
false |
Ob Hintergrundmusik, Soundeffekte und Dialog gleichzeitig generiert werden; standardmäßig aus, für Audio musst du es explizit aktivieren. |
negative_prompt |
string | maximal 2048 Bytes UTF-8 | — | Optional; Inhalte, die du vermeiden möchtest. |
seed |
integer | beliebige Ganzzahl | — | Optional; gleicher seed + gleicher prompt reproduziert dasselbe Ergebnis. |
style |
enum | anime, 3d_animation, clay, comic, cyberpunk |
keiner | Optionales Stil-Preset; leer lassen für natürlichen Look. |
Wenn du statt Polling einen Callback verwenden willst, kannst du auf derselben Ebene wie input ein callback-Objekt mitgeben: url (HTTPS-Callback-Adresse) + when (derzeit nur final, also Callback beim Endzustand der Aufgabe).
So schreibst du es für die Produktion
- Das ist ein geschlossenes Schema. Jedes Feld, das nicht in der obigen Tabelle steht, wird direkt abgelehnt mit
invalid input: <root>: additional properties '<Feld>' not allowed. Das ist tatsächlich gut: Vertippte oder erfundene Felder schlagen schon beim Einreichen deutlich fehl, statt still ignoriert zu werden. durationist eine Ganzzahl – anders als bei manchen Videomodellen der Plattform, die Strings ("6") akzeptieren. Sendest du"5", erhältst duinvalid input: duration: got string, want integer; bei Ausreißern werden dir direkt die Grenzen genannt, z. B.duration: maximum: got 999, want 15,duration: minimum: got 0, want 1.- Fehler melden jeweils nur ein Feld, der Envelope ist flach:
{"code":400,"error_code":"INVALID_REQUEST","message":"invalid input: aspect_ratio: value must be one of ..."}. Korrigiere das gemeldete Feld und sende erneut; das nächste ungültige Feld (falls vorhanden) taucht beim nächsten Aufruf auf. - Bei einer fehlgeschlagenen Aufgabe ist HTTP trotzdem 200. Die Fehlerinformation steht in
data.status: "fail"des Antwortkörpers; zu prüfen ist dieses status-Feld, nicht der HTTP-Statuscode. - Polling oder Callback? Für leichte Skripte ist Polling am einfachsten; für Skalierung, bei der du keine Verbindung dauerhaft offen halten willst, nutze
callback. In beiden Fällen musst duoutput[0].urlsofort herunterladen – die URL enthältexpireAtund wird nach Ablauf zu 404.
Messprotokoll: Ich habe es tatsächlich einmal ausgeführt
Dieser Artikel basiert nicht nur auf Read-only-Sonden – ich habe mit einer echten Anfrage den vollständigen Lebenszyklus durchlaufen und dokumentiere es hier:
- Erstellung: Der obige Request mit 720p / 5 Sekunden / 16:9 wurde abgeschickt und lieferte sofort
{"code":200,"data":{"taskId":"tk-hiapi-01M5AM..."},"message":"success"}. Beachte, dass die taskId ein String mit Präfixtk-hiapi-ist, keine UUID. - Polling:
data.statusvonGET /v1/tasks/<id>durchlief nacheinanderhandling→archiving→success; der gesamte 5-Sekunden-Clip brauchte von der Erstellung bis zur Fertigstellung etwa 74 Sekunden. - Ausgabe: Im Endzustand ist
data.output[0]gleich{"type":"video","url":"https://temp.hiapi.ai/....mp4","expireAt":...,"artifactId":"...","storage":"temp"}.expireAtminus Erstellungszeit ergibt genau 604800 Sekunden, also 7 Tage. - Artefakt: Ein HEAD auf diese Ausgabe-URL lieferte
content-type: video/mp4und eine Größe von etwa 2,2 MB – bestätigt eine gültige mp4-Datei.
Eine Korrektur zum Thema Audio ist es wert, separat festgehalten zu werden: Ich habe benachbarte Feldnamen jeweils mit ungültigen Werten geprüft – generate_audio meldete got string, want boolean (also ist es ein gültiges boolesches Feld), während sound und audio beide additional properties not allowed meldeten (existieren nicht). Das heißt: Audio wird über den Schalter generate_audio gesteuert, Standard false; auf der Preisseite gibt es entsprechend zwei Stufen „Sound On / Sound Off“. In diesem Test habe ich generate_audio nicht aktiviert, daher war das Ergebnis ein stummer Clip.
Zur Bildqualität habe ich keine subjektive Bewertung abgegeben (in diesem Test habe ich nur den Request-Vertrag, den Aufgaben-Lebenszyklus und die Gültigkeit der mp4-Ausgabe verifiziert) – diesen Teil beurteile bitte selbst, nachdem du mit deinen eigenen Prompts tatsächlich generiert hast.
Wie die Kosten berechnet werden
pixverse-v6/text-to-video wird pro Sekunde abgerechnet (der Abrechnungsfaktor ist duration); je länger die Dauer, desto teurer; je höher die Auflösung und wenn generate_audio aktiviert ist (Stufe „Sound On“), desto höher der Sekundenpreis. Die konkreten Sekundensätze richten sich nach den Echtzeitdaten auf der Preisseite – wirf einen Blick darauf, bevor du in großem Umfang generierst.
Relevante Links
- PixVerse V6 Text-zu-Video – Modellseite
- PixVerse V6 Text-zu-Video – API-Dokumentation
- Aufgabe erstellen und Aufgabendetails abfragen – API-Referenz
- Schnellstart und Authentifizierung
- Möchtest du mit einem Bild ein Video erstellen? Sieh dir PixVerse V6 Bild-zu-Video an
- Preise
Häufige Fragen
Ist duration in Sekunden oder Frames? Sekunden – eine beliebige Ganzzahl zwischen 1 und 15, Standard 5.
Kann man Videos mit Ton generieren? Ja. Setze generate_audio auf true, dann generiert das Modell Hintergrundmusik, Soundeffekte und Dialog mit; Standard ist false (stumm). Das Aktivieren von Audio nutzt eine teurere Abrechnungsstufe, Details auf der Preisseite.
Wie lang darf der Prompt sein? Die Obergrenze liegt bei 2048 Bytes UTF-8. Ein chinesisches Zeichen zählt als 3 Bytes, also maximal etwa 682 chinesische Zeichen.
Worin unterscheidet es sich von Bild-zu-Video? Dieser Endpoint (pixverse-v6/text-to-video) startet nur von einem Text-Prompt. Bild-zu-Video ist eine andere model id, die ein Ausgangsbild entgegennimmt und es in Bewegung setzt – wenn du ein vorhandenes Bild animieren statt aus dem Nichts generieren willst, nutze jene.
Warum meldet mein Request "additional properties not allowed"? Du hast ein Feld übergeben, das nicht im Schema ist. Die Eingabe akzeptiert nur prompt, aspect_ratio, duration, resolution, generate_audio, negative_prompt, seed und style.
Ähnliche Artikel
Alle Artikel ansehen →-
Tutorial
So rufen Sie hailuo-2.3-fast/image-to-video über die HiAPI API auf: curl und Python in der Praxis
Die erste lauffähige Anfrage für die schnelle, kostengünstige Bild-zu-Video-Stufe – von der Modell-ID bis zum heruntergeladenen MP4
-
Tutorial
So rufen Sie hailuo-2.3/text-to-video über die HiAPI API auf: curl, Python und lauffähige Anfragebeispiele
-
Tutorial
Kandinsky 6.0 Pro Text-zu-Video auf HiAPI: curl- und Python-Tutorial
Eine anfrageorientierte praktische Demonstration: Aufbau des Aufrufs vom Prompt zum Videoclip, Absenden der Anfrage, Abfragen des Fertigstellungsstatus und Herunterladen des Ergebnisses