Tutorial
So nutzt du grok-4.7 über die HiAPI-API: curl, Python und eine funktionierende Anfrage
Ein Praxisleitfaden von der ersten Anfrage bis zur verifizierten Antwort
Was du vor der ersten Anfrage vorbereiten musst
Bevor du irgendetwas an die API sendest, stelle sicher, dass vier Dinge bereit sind. Das Überspringen eines dieser Punkte ist die häufigste Ursache für einen fehlgeschlagenen ersten Aufruf – und der Grund für das Scheitern hat oft nichts mit dem Modell selbst zu tun.
Ein HiAPI-Konto
Du brauchst ein gültiges HiAPI.ai-Konto. Melde dich im Dashboard an, um Projekte, Schlüssel und Nutzung zu verwalten. Alle Aktionen in diesem Tutorial laufen über dieselbe einheitliche API-Oberfläche, daher kannst du den hier erstellten Schlüssel für alle Modelle verwenden, die die Plattform anbietet.
Ein API-Schlüssel
Erstelle im Dashboard einen API-Schlüssel und bewahre ihn sicher auf – beim Testen eine Shell-Umgebungsvariable, für alles, was in den Produktivbetrieb geht, ein Schlüsselmanager. Committe den Schlüssel niemals in ein Code-Repository und füge ihn nicht in Client-Anwendungen ein.
Für lokale Tests exportierst du ihn einmal pro Shell-Sitzung:
export HIAPI_API_KEY="your-api-key-here"
Die Basis-URL
Die Basis-URL ist die Stammadresse der HiAPI-API. Alle Anfragen in diesem Tutorial beziehen sich darauf. Prüfe in deinem Dashboard die genaue Basis-URL, die für dein Konto gilt, und speichere sie in einer Variable, damit Skripte und Anwendungscode denselben Wert referenzieren:
export HIAPI_BASE_URL="https://api.hiapi.ai"
Der Modellbezeichner
Der in diesem Tutorial verwendete Modellbezeichner ist grok-4.7. Er wird als reiner String im Request-Body übergeben. Bei einem falschen Bezeichner erhältst du in der Regel eine eindeutige Fehlerantwort statt eines stillen Fallbacks – Tippfehler sind also leicht zu erkennen.
Sobald diese vier Dinge – Konto, Schlüssel, Basis-URL, Modell-ID – bereitstehen, hast du alles, was für die Anfrageform nötig ist. Der curl-Weg erfordert kein SDK, und der Python-Weg benötigt nur einen HTTP-Client, den du wahrscheinlich ohnehin hast.
Schnelle Umgebungsprüfung
Prüfe, ob Schlüssel und Basis-URL für die Shell sichtbar sind, die du gleich verwenden wirst:
[ -n "$HIAPI_API_KEY" ] && echo "key set"
[ -n "$HIAPI_BASE_URL" ] && echo "base url set"
Wenn beide Zeilen ausgegeben werden, kannst du zum nächsten Abschnitt übergehen.
Die Form einer grok-4.7-Anfrage auf HiAPI
Jede Anfrage in diesem Tutorial teilt dieselben vier Elemente: Endpunkt, Authentifizierungs-Header, Modellfeld und messages-Array. Wenn du sie einzeln verstehst, wird es später viel einfacher, Streaming und Tool-Aufrufe zu begreifen, denn diese Funktionen ändern nur einen Teil dieser Form.
Der Endpunkt
Der Aufruf ist eine POST-Anfrage an den Chat-Completions-Endpunkt unter der Basis-URL. In diesem Tutorial stellen wir ihn so dar:
POST {HIAPI_BASE_URL}/v1/chat/completions
Wenn dein Dashboard einen anderen Pfad anzeigt, verwende den Pfad aus dem Dashboard; der Request-Body ist in beiden Fällen derselbe.
Der Authentifizierungs-Header
Die Authentifizierung erfolgt über ein Bearer-Token im Authorization-Header:
Authorization: Bearer $HIAPI_API_KEY
Da es sich um einen Header und nicht um einen Query-Parameter handelt, erscheint der Schlüssel nie in URLs, Zugriffsprotokollen oder dem Browserverlauf.
Der Content-Type
Der Request-Body ist JSON, daher sendest du Content-Type: application/json. curl und jeder Python-HTTP-Client setzen ihn für dich, aber es lohnt sich, ihn explizit anzugeben, damit die Header-Menge eindeutig ist.
Der Request-Body: model und messages
Der Request-Body ist ein JSON-Objekt mit mindestens zwei Feldern:
model— der Modellbezeichner-String, hiergrok-4.7.messages— ein geordnetes Array von Message-Objekten. Jedes Objekt hatroleundcontent. Häufige Rollen sind:systemfür Anweisungen, die das Gespräch rahmen,userfür die eigentliche Anfrage undassistantfür frühere Modellrunden, die du beim Fortsetzen des Gesprächs bereitstellst.
Ein minimaler Request-Body sieht so aus:
{
"model": "grok-4.7",
"messages": [
{ "role": "system", "content": "You are a concise technical assistant." },
{ "role": "user", "content": "Explain what an idempotent HTTP method is in two sentences." }
]
}
Das ist das gesamte Vertragswerk für einen Basisanspruch. Alles andere – Streaming, Tool-Definitionen – sind zusätzliche Felder auf demselben Objekt, und genau deshalb waren die vorherigen Abschnitte wichtig: Sobald diese Form korrekt ist, ist der Rest Ergänzung.
Wie die Antwort aussieht
Die Antwort ist ein JSON-Objekt. Der Teil, den du fast immer willst, liegt unter choices, einem Array; jeder Eintrag hat eine message mit role und content. Daneben gibt es Metadaten, etwa das Modell, das die Anfrage verarbeitet hat, und einen usage-Block, der die Token-Anzahl beschreibt. Ließ choices[0].message.content, und du hast den Antworttext. Die anderen Felder sind für Protokollierung und Kostenverfolgung nützlich, für den Einstieg aber nicht nötig.
Eine funktionierende curl-Anfrage
Nachdem der Schlüssel exportiert und die Anfrageform verstanden ist, ist der curl-Aufruf kurz. Wenn du dein Problem vom Anwendungscode isolieren willst, ist dies die Version, die du kopieren solltest.
curl -sS "$HIAPI_BASE_URL/v1/chat/completions" \
-H "Authorization: Bearer $HIAPI_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "grok-4.7",
"messages": [
{ "role": "system", "content": "You are a concise technical assistant." },
{ "role": "user", "content": "In one sentence, what is a bearer token?" }
]
}'
Was jedes Flag bewirkt
-sShält die Ausgabe ruhig, gibt aber Fehler weiterhin aus. Ohne dies könnte eine fehlgeschlagene Anfrage wie eine leere Antwort aussehen.- Die URL setzt sich aus der Basis-URL-Variable plus dem Chat-Completions-Pfad zusammen, sodass du den Host nie im Skript fest verdrahten musst.
-H "Authorization: ..."sendet das Bearer-Token. Die Variable wird von der Shell expandiert – deshalb war das vorherige Exportieren wichtig.-H "Content-Type: application/json"teilt dem Server mit, dass der Request-Body JSON ist.-d '...'ist der Request-Body. Die einfachen Anführungszeichen um das JSON verhindern, dass die Shell die darin enthaltenen geschweiften Klammern und Anführungszeichen interpretiert.
Wenn du den Request-Body lieber in einer Datei ablegst, schreibe ihn in body.json und ersetze den -d-Parameter durch -d @body.json. Das ist oft übersichtlicher, sobald das messages-Array länger wird.
Das rohe JSON lesen
Die Antwort kommt als JSON-Objekt auf stdout an. Wenn du sie mit eigenen Augen prüfen willst, leite sie durch einen Formatierer:
curl -sS "$HIAPI_BASE_URL/v1/chat/completions" \
-H "Authorization: Bearer $HIAPI_API_KEY" \
-H "Content-Type: application/json" \
-d @body.json | python -m json.tool
Du solltest ein choices-Array sehen, dessen erstes Element ein message-Objekt mit einem content-String enthält – dieser String ist die Antwort des Modells. Daneben stehen in der Regel eine Kennung der Antwort, der zurückgegebene Modellname und ein usage-Objekt mit den Token-Zählungen für Prompt und Completion. Halte jetzt eine erfolgreiche Antwort fest: Sie ist deine Referenz, wenn du den Python-Client verifizierst.
Häufige Fehler in dieser Phase
401 bedeutet fast immer, dass das Bearer-Token fehlt, falsch formatiert ist oder nicht wirklich in der aktuellen Shell exportiert wurde. 400 mit einer Meldung zum Request-Body bedeutet meist fehlerhaftes JSON – nachgestellte Kommas oder aus der Dokumentation kopierte typografische Anführungszeichen sind häufige Übeltäter. Behebe diese beiden Punkte, bevor du irgendetwas anderes untersuchst.
Dieselbe Anfrage in Python
Die Python-Version tut dasselbe mit demselben Request-Body. Der Sinn des Umschreibens liegt darin, vom Shell-Test zu Code zu wechseln, den du in eine Anwendung einbauen kannst, wobei der Request-Body eine Datenstruktur statt eines zitierten Strings ist.
Die Standardbibliothek verwenden
Wenn du keine Abhängigkeit hinzufügen willst, reicht urllib aus:
import json
import os
import urllib.request
api_key = os.environ["HIAPI_API_KEY"]
base_url = os.environ["HIAPI_BASE_URL"]
payload = {
"model": "grok-4.7",
"messages": [
{"role": "system", "content": "You are a concise technical assistant."},
{"role": "user", "content": "In one sentence, what is a bearer token?"},
],
}
request = urllib.request.Request(
f"{base_url}/v1/chat/completions",
data=json.dumps(payload).encode("utf-8"),
headers={
"Authorization": f"Bearer {api_key}",
"Content-Type": "application/json",
},
method="POST",
)
with urllib.request.urlopen(request) as response:
body = json.loads(response.read().decode("utf-8"))
print(body["choices"][0]["message"]["content"])
requests verwenden
Wenn requests bereits in deiner Umgebung vorhanden ist, ist der Aufruf kürzer:
import os
import requests
response = requests.post(
f"{os.environ['HIAPI_BASE_URL']}/v1/chat/completions",
headers={"Authorization": f"Bearer {os.environ['HIAPI_API_KEY']}"},
json={
"model": "grok-4.7",
"messages": [
{"role": "system", "content": "You are a concise technical assistant."},
{"role": "user", "content": "In one sentence, what is a bearer token?"},
],
},
timeout=60,
)
response.raise_for_status()
print(response.json()["choices"][0]["message"]["content"])
Warum diese Version für Anwendungen sicherer ist
Beachte drei bewusste Entscheidungen. Schlüssel und Basis-URL kommen aus Umgebungsvariablen, niemals aus Literalen im Quellcode. Der Request-Body ist ein Python-Dictionary, sodass ein falsch platziertes Anführungszeichen sofort einen SyntaxError auslöst statt einer verwirrenden serverseitigen Ablehnung. Und der Aufruf hat ein Timeout: Ohne Timeout kann eine hängende Verbindung einen Worker unbegrenzt blockieren.
Führe die Python-Version mit demselben Prompt aus, den du in curl verwendet hast. Die Formulierung der Antwort kann zwischen Läufen leicht variieren – Modelle sind nicht deterministisch – aber die Struktur der Antwort sollte exakt übereinstimmen: ein choices-Array, eine message mit content und ein usage-Block. Wenn die Struktur übereinstimmt, ist dein Client korrekt verbunden, und alle weiteren Abschnitte sind optionale Erweiterungen.
Streaming aktivieren
Streaming ändert, wie die Token ankommen, nicht was du anforderst. Statt auf die vollständige Antwort zu warten, erhältst du sie nach und nach – genau das lässt Chat-Oberflächen reaktionsschnell wirken.
Die Änderung an der Anfrage
Füge deinem bestehenden Request-Body ein Feld hinzu:
{
"model": "grok-4.7",
"stream": true,
"messages": [
{ "role": "user", "content": "Count from one to five, one number per line." }
]
}
Endpunkt, Header und der Rest der messages bleiben unverändert. Das ist der ganze Sinn des vorherigen Lernens der Grundform: Streaming ist ein zusätzliches Flag, keine zweite API.
Was zurückkommt
Mit aktiviertem stream ist die Antwort kein einzelnes JSON-Objekt mehr. Es ist eine Reihe von Server-Sent Events (SSE). Jedes Ereignis trägt eine data:-Zeile, deren Payload ein JSON-Fragment derselben Form wie eine normale Antwort ist, nur dass choices[0] ein delta-Objekt statt einer vollständigen message enthält. Frühe Fragmente können nur die Rolle enthalten; mittlere Fragmente tragen Inhaltsfragmente; der Stream endet mit der Sentinel-Zeile data: [DONE].
Als Client ist deine Aufgabe, die delta.content-Strings der Reihe nach zu verketten und am Sentinel zu stoppen. Behandle jedes Fragment ohne content als No-Op und nicht als Fehler.
Datenblöcke in Python konsumieren
import json
import os
import requests
with requests.post(
f"{os.environ['HIAPI_BASE_URL']}/v1/chat/completions",
headers={"Authorization": f"Bearer {os.environ['HIAPI_API_KEY']}"},
json={
"model": "grok-4.7",
"stream": True,
"messages": [{"role": "user", "content": "Count from one to five."}],
},
stream=True,
timeout=60,
) as response:
response.raise_for_status()
for line in response.iter_lines():
if not line:
continue
line = line.decode("utf-8")
if not line.startswith("data: "):
continue
data = line[len("data: "):]
if data == "[DONE]":
break
delta = json.loads(data)["choices"][0].get("delta", {})
text = delta.get("content")
if text:
print(text, end="", flush=True)
Zwei Details entscheiden, ob Streaming ordnungsgemäß funktioniert oder scheinbar hängt. Übergib stream=True an den HTTP-Client, damit er nicht den gesamten Response-Body puffert, und iteriere zeilenweise statt die Antwort auf einmal zu lesen. Das flush=True bei print betrifft nur, was du auf dem Bildschirm siehst; ohne es kann die Ausgabe scheinbar erst am Ende auf einmal erscheinen, obwohl die Datenblöcke bereits beim Eintreffen verarbeitet werden.
Streaming separat verifizieren
Verifiziere Streaming und Tool-Aufrufe nicht im selben Test gleichzeitig. Bestätige zuerst, dass der verkettete Text bei einem einfachen Prompt eine sinnvolle Antwort ergibt, und füge dann Funktionen einzeln hinzu. Wenn der Stream ohne Sentinel endet, ist das ein Signal, die Verbindung zu prüfen, nicht das Modell.
Optionen für Tool-Aufrufe
Tool-Aufrufe ermöglichen es dem Modell, Funktionen anzufordern, die in deinem Code definiert sind, statt nur Text zu erzeugen. Auf der Anfrageseite werden sie genauso ergänzt wie Streaming.
Wo die Optionen hingehören
Tool-Definitionen sind ein tools-Array im Request-Body. Jeder Eintrag beschreibt ein aufrufbares Element: einen Namen, eine Beschreibung, wann es zu verwenden ist, und eine JSON-Schema-Beschreibung seiner Parameter. Die Beschreibung ist wichtiger, als sie aussieht – sie ist die einzige Anleitung des Modells, wann das Tool passt.
{
"model": "grok-4.7",
"messages": [
{ "role": "user", "content": "What is the weather in Lisbon right now?" }
],
"tools": [
{
"type": "function",
"function": {
"name": "get_weather",
"description": "Return the current weather for a named city.",
"parameters": {
"type": "object",
"properties": {
"city": { "type": "string", "description": "City name, e.g. Lisbon" }
},
"required": ["city"]
}
}
}
]
}
Die zu merkende Form ist type plus function, wobei darin name, description und parameters verschachtelt sind. Wenn du bereits JSON-Schema-Definitionen hast, gehören sie in den parameters-Block.
Wie das Modell antwortet
Wenn das Modell entscheidet, dass ein Tool benötigt wird, ist die Assistant-Nachricht in choices[0] kein normaler Text. Ihr content ist meist leer, und sie trägt ein tool_calls-Array. Jeder Eintrag hat eine Kennung, einen Funktionsnamen, der zu einer deiner Definitionen passt, und einen arguments-String, der JSON enthält. Parse diesen arguments-String – es ist ein String und kein Objekt; ihn als Objekt zu behandeln ist eine häufige Fehlerquelle.
Dein Code führt dann die Funktion aus und sendet eine Folgeanfrage: das ursprüngliche Gespräch, die Assistant-Nachricht mit tool_calls und eine neue Nachricht mit der Rolle tool, die die Aufruf-Kennung und das Ergebnis enthält. Das Modell nutzt dieses Ergebnis, um die endgültige Antwort zu erzeugen. Die tool_call_id muss mit der Kennung in der Assistant-Nachricht übereinstimmen; ohne sie ist die Folgeanfrage mehrdeutig.
Praktische Schutzmaßnahmen
- Validiere die geparsten Parameter mit demselben Schema, das du gesendet hast. Das Modell wird vom Schema geleitet, ist aber nicht daran gebunden.
- Behandle den zurückgegebenen Funktionsnamen als nicht vertrauenswürdige Eingabe und leite nur zu einer expliziten Funktions-Allowlist weiter.
- Aktiviere beim ersten Test nicht gleichzeitig
streamund Tools. Bestätige zuerst den nicht-streamenden Tool-Roundtrip von Ende zu Ende und kombiniere beides erst, wenn dein Anwendungsfall beides erfordert.
Antworten vor dem Go-live verifizieren
Ein Aufruf, der im Terminal funktioniert, ist noch keine verifizierte Integration. Gehe diese Checkliste vollständig durch und behalte das Skript als Smoke-Test.
Die Transportschicht bestätigen
Prüfe den HTTP-Status auf 200, bevor du irgendetwas parsst. Ein Client, der zuerst parst, erzeugt einen verwirrenden KeyError, wenn das eigentliche Problem ein 401 ist. Stelle den Status explizit fest und protokolliere bei einem Fehler den Response-Body mit – der Server erklärt meist, was schiefgelaufen ist.
Die Antwortstruktur bestätigen
Stelle fest, statt anzunehmen. Bei einem erfolgreichen nicht-streamenden Aufruf prüfe drei Dinge: choices existiert und ist nicht leer, choices[0].message.content ist ein nicht-leerer String, und das in der Antwort zurückgegebene Modell entspricht dem, das du gesendet hast. Die letzte Prüfung erkennt eine erstaunliche Zahl von Konfigurationsfehlern – ein Standardmodell hat das von dir angeforderte Modell überschrieben.
Fehlerpfade bewusst durchspielen
Warte nicht auf einen Ausfall, um das Verhalten deines Codes zu verstehen. Führe drei schnelle Negativtests durch:
- Rufe ohne Authentifizierungs-Header auf und bestätige, dass dein Code einen eindeutigen Authentifizierungsfehler preisgibt und nicht endlos wiederholt.
- Sende einen Request-Body ohne
model-Feld und bestätige, dass du einen Client-Fehler erhältst statt eines Hängens. - Sende einen absichtlich sehr langen Prompt und bestätige, dass dein Timeout- und Truncation-Verhalten wie erwartet funktioniert.
Jeder dieser Fälle sollte einen konkreten, protokollierten Fehler erzeugen – nicht ein allgemeines „Etwas ist schiefgelaufen“.
Erweiterungen separat verifizieren
Wenn du Streaming aktiviert hast, bestätige, dass die verketteten Datenblöcke eine zusammenhängende Antwort ergeben und der Sentinel die Schleife beendet. Wenn du Tools aktiviert hast, bestätige den Roundtrip: Der Tool-Aufruf wird geparst, die Funktion ausgeführt, das Ergebnis mit passender Kennung zurückgesendet und eine endgültige Textantwort erzeugt. Halte jede Verifikation in einem eigenen kleinen Skript, sodass ein Fehler auf genau eine Funktion zeigt.
Prüfungen wiederholbar gestalten
Fasse die gesamte Sequenz in einer Datei zusammen, die bei jeder fehlgeschlagenen Zusicherung mit einem Nicht-Null-Code beendet wird, und führe sie vor jedem Deployment gegen deine Staging-Konfiguration aus. Sie sollte nur wenige Sekunden dauern und den Basisaufruf, einen Streaming-Aufruf und, wenn du Tools verwendest, einen Tool-Roundtrip abdecken. Wenn sie besteht, kannst du darauf vertrauen, dass Fehler in der Produktion an der von dir gesendeten Anfrage liegen und nicht an der zugrunde liegenden Infrastruktur.
Führe nach bestandener Prüfung den curl-Aufruf noch einmal aus. Wenn das rohe JSON mit deiner Anwendungsausgabe übereinstimmt, ist die Integration abgeschlossen.
Ä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