Go-SDK
Das offizielle Go-SDK für SpicyAPI (github.com/spicyapi-ai/spicy-go) – installieren, die erste Generierung schätzen und ausführen, eine lokale Datei hochladen, den Task-Verlauf durchgehen und jeden Fehlercode behandeln.
spicy-go ist das offizielle Go-SDK für SpicyAPI. Es legt die Erzeugung von Bildern, Videos und Audio hinter einen einzigen *spicy.Client: Er hängt Ihren API-Schlüssel an, dekodiert den Antwort-Envelope in typisierte Structs, wartet mit begrenztem Back-off auf einen Task, lädt lokale Dateien in einem Aufruf hoch und gibt jedem Fehlschlag einen einzigen Fehlertyp, den Sie mit errors.As abfangen.
Es setzt Go 1.23 oder neuer voraus und kommt allein mit der Standardbibliothek aus. Das ist Absicht: Dieses Paket landet in Ihrem Abhängigkeitsgraphen, und jedes Modul, das es mitzieht, müssen Sie mit prüfen.
Ist das das richtige Werkzeug?
| Sie möchten … | Verwenden Sie |
|---|---|
| SpicyAPI aus Ihrem eigenen Go-Code aufrufen | Dieses SDK |
| Es aus Node.js oder TypeScript aufrufen | Das TypeScript-SDK |
| Es aus Python, PHP oder Java aufrufen | Das Python-, PHP- oder Java-SDK |
| Ohne Code aus einem Terminal heraus generieren | Die CLI |
| Einen KI-Assistenten SpicyAPI für Sie aufrufen lassen | Den MCP-Server und den Agent Skill |
| Ein Chat- oder Textmodell nutzen | Einen etablierten Go-Client für die Formate von OpenAI, Anthropic oder Gemini – siehe Text und Streaming |
Installieren
Go löst Module direkt aus ihrem Repository auf, es gibt also keinen Umweg über eine Registry und nichts, worauf Sie warten müssten. Dieser Befehl funktioniert schon heute:
go get github.com/spicyapi-ai/spicy-goLegen Sie Ihren Schlüssel danach in die Umgebung, damit er weder in Ihrem Code noch in der History-Datei Ihrer Shell auftaucht:
export SPICY_API_KEY="sk-spicy-..."Ihr erstes Ergebnis
Preis erfragen, entscheiden, Task anlegen, warten, Dateien lesen. Eine Kostenschätzung ist kostenlos und reserviert nichts.
client, err := spicy.New(spicy.Options{}) // liest SPICY_API_KEY aus der Umgebung
if err != nil {
return err
}
request := spicy.CreateTaskInput{
Model: "MODEL_ID_FROM_CATALOG",
Input: map[string]any{"prompt": "a lantern in fog"},
}
quote, err := client.Quote(ctx, request)
if err != nil {
return err
}
log.Printf("this will cost at most %s", quote.MaxCharge)
// Legen Sie ihn vor dem Absenden neben Ihren eigenen Datensatz zum Auftrag: Sein
// ganzer Zweck ist, den Absturz zu überleben, der die Antwort verschluckt hat.
key, err := spicy.NewIdempotencyKey()
if err != nil {
return err
}
request.Model = quote.Model
request.QuoteID = quote.QuoteID
request.ExpectedCost = quote.EstimatedCost
task, err := client.CreateTask(ctx, request, key, spicy.CreateTaskOptions{})
if err != nil {
return err
}
final, err := client.WaitForTerminal(ctx, task.TaskID, spicy.WaitOptions{})
if err != nil {
return err
}
for _, asset := range final.ReadyAssets() {
log.Println(asset.URL)
}MODEL_ID_FROM_CATALOG ist ein Platzhalter. Holen Sie sich eine echte ID aus dem authentifizierten Katalog – client.ListModels, also GET /api/v1/models – und nie aus dem Gedächtnis oder von einer alten Seite: Modelle kommen hinzu, werden pausiert und eingestellt. Bauen Sie Input aus dem inputSchema genau dieses Modells, das ListModels zurückgibt; jedes Modell nimmt andere Felder an.
Beträge sind Dezimalzeichenketten in US-Dollar, nie Floats, denn binäre Gleitkommazahlen können die meisten Dezimalbeträge nicht exakt speichern. Credits oder Punkte gibt es in dieser API nirgends.
Ein Endzustand ist kein erfolgreicher Zustand: failed, canceled und expired beenden das Warten genauso. Prüfen Sie final.State.
Die erste Abfrage überspringen
WaitSeconds bittet den Dienst, die Verbindung offen zu halten, bis der Task fertig ist; bei einem schnellen Modell kommt das Ergebnis dadurch bereits mit dem Absenden zurück.
seconds := 30
task, err := client.CreateTask(ctx, request, key, spicy.CreateTaskOptions{WaitSeconds: &seconds})
if err != nil {
return err
}
// Task ist nil, sobald die Wartezeit abgelaufen ist. Das ist der normale Ausgang,
// kein Fehler – die Generierung läuft weiter, fragen Sie also ab hier nach.
final := task.Task
if final == nil {
final, err = client.WaitForTerminal(ctx, task.TaskID, spicy.WaitOptions{})
if err != nil {
return err
}
}
log.Println(final.State, final.Cost)Das ist eine Optimierung, nie eine Zusage. Code, der task.Task ohne die Nil-Prüfung liest, funktioniert genau bis zur ersten Generierung, die länger dauert als das Budget – und läuft dann im Produktivbetrieb in einen Panic.
Mit einer lokalen Datei beginnen
Bild-zu-Video, Motivtausch und Bildbearbeitung brauchen Ihr Material zuerst auf unserer Seite. UploadFile erledigt den dreistufigen Upload – Ticket, PUT in den Speicher, Commit – in einem Aufruf und gibt eine spicy://-URI zurück. Diese URI kommt in Input.
uploaded, err := client.UploadFile(ctx, "/path/to/reference.png", "")
// uploaded.URI -> "spicy://f/fil_..."Eine öffentlich erreichbare HTTPS-Adresse können Sie direkt in die Eingabe schreiben; dafür ist gar kein Upload nötig. Bilder werden bis 10 MiB angenommen, Audio und Video bis 90 MiB; siehe Medien.
Guthaben, Verbrauch und Verlauf
Alle drei beziehen sich auf den aufrufenden API-Schlüssel: Andere Schlüssel desselben Kontos und Generierungen, die in der Konsole gestartet wurden, sind nicht enthalten, und dass sie fehlen, ist kein Fehler.
balance, err := client.GetBalance(ctx)
if err != nil {
return err
}
log.Printf("%s available, %s held by accepted tasks", balance.Available, balance.Held)
usage, err := client.GetUsage(ctx, spicy.UsageOptions{From: "2026-09-01", To: "2026-09-08"})
if err != nil {
return err
}
log.Printf("%d calls, %s settled over [%s,%s)", usage.TotalCalls, usage.TotalSpend, usage.From, usage.To)
// EachTask wiederholt jeden Filter auf jeder Seite und bewegt nur den Cursor.
if err := client.EachTask(ctx, spicy.ListTasksOptions{From: "2026-09-01", To: "2026-09-08"},
func(task spicy.TaskListItem) bool {
log.Println(task.TaskID, task.State, task.Cost)
return true // false beendet den Durchlauf vorzeitig
}); err != nil {
return err
}Datumsangaben sind UTC-Kalendertage in einem halboffenen Intervall [from, to) von höchstens 92 Tagen. Setzen Sie From und To fest, sobald ein Durchlauf Mitternacht UTC überschreiten kann. Leer gelassen, berechnet der Server sein eigenes Fenster – to ist der morgige Tag in UTC – auf jeder Seite neu; ein Durchlauf, der um 23:59 beginnt und um 00:01 weitergeht, stellt also zwei verschiedene Fragen und klebt die Antworten aneinander. Gemeldet wird das nirgends.
GetUsage ist für den Abgleich gedacht, nicht für den Fortschritt. Dahinter steht ein kontoweites Budget, das sich alle Schlüssel teilen, und dieser Begrenzer sperrt im Zweifelsfall: Wer ihn ständig abfragt, kann jeden anderen Schlüssel von seinen eigenen Auswertungen aussperren. Verfolgen Sie einen Task stattdessen mit WaitForTerminal. Abrechnungen können außerdem verspätet eintreffen, sodass sich eine heute gelesene Zahl morgen noch ändert.
Fehler
Fehlschläge kommen als *spicy.APIError zurück, erreichbar über errors.As:
var apiErr *spicy.APIError
if errors.As(err, &apiErr) {
log.Println(apiErr.Status, apiErr.Code, apiErr.RequestID, apiErr.RetryAfter)
}Verzweigen Sie über Code, nie über die Meldung – Meldungen werden übersetzt, Codes nicht. HTTP 503 teilen sich drei verschiedene Business-Codes, der Status allein genügt also nicht, um zu entscheiden, was zu tun ist:
| Code | Bedeutung | Was zu tun ist |
|---|---|---|
40003 | Hochgeladene Bytes passen nicht zum Ticket | Mit einem frischen Ticket neu beginnen |
40004 | Keine Bereitstellung bedient diese Parameterkombination | Den in der Meldung genannten Parameter ändern |
40201 | Guthaben reicht nicht | Guthaben aufladen |
40901 | Der Preis hat sich vor dem Anlegen geändert | Neu schätzen, denselben Idempotenzschlüssel behalten |
503 | Eine Abhängigkeit ist kurz nicht erreichbar | Gemäß RetryAfter warten |
50301 | Gerade keine nutzbare Bereitstellung und kein Preis | Katalog neu laden, nicht dauerhaft nachfragen |
50302 | Synchrone Generierung bei der Ausführung fehlgeschlagen, erstattet | Mit einem neuen Idempotenzschlüssel wiederholen |
Jeder Code steht unter Fehler. Nennen Sie RequestID, wenn Sie den Support kontaktieren.
Zwei Dinge, die Ihnen Geld sparen
Bleiben Sie pro Absendung bei einem Idempotenzschlüssel. Verwenden Sie ihn für jedes erneute Senden wieder, auch nach einem Timeout. Eine verlorene Antwort ist kein Beweis dafür, dass der Task nicht angelegt wurde – ein frischer Schlüssel macht aus einem unbekannten Ausgang einen zweiten kostenpflichtigen Task. Genau deshalb verlangt CreateTask den Schlüssel. Siehe Idempotenz.
Ein erfolgreicher Task wird berechnet, auch wenn das Ergebnis enttäuscht. Quote reserviert nichts, holen Sie also zuerst eine Kostenschätzung ein, wenn es auf den Preis ankommt.
Was dieses Paket nicht tut
- Textmodelle. Sie sprechen die Formate von OpenAI, Anthropic und Gemini – die etablierten Go-Clients dafür funktionieren mit demselben Schlüssel bereits gegen
https://api.spicyapi.ai/v1. Siehe Text und Streaming. - Anwendungen auf der Clientseite. Liefern Sie diesen Schlüssel niemals in einer Binärdatei aus, die Sie verteilen. Rufen Sie von Ihrem Server aus auf.
- Ein Modell auswählen oder seine Felder ausfüllen. Es reicht Ihnen den Katalog und das Schema jedes Modells; was Sie senden, entscheiden Sie.
- Einen Task abbrechen. Ist ein Task erst angenommen, läuft er bis zum Ende. Den
contextabzubrechen, stoppt nur Ihr Warten.
Quellcode
Das Modul steht unter MIT-Lizenz und wird offen unter github.com/spicyapi-ai/spicy-go entwickelt. Sein README ist die kürzeste vollständige Führung durch den Client; diese Seite ergänzt die Konzepte drumherum.
Nächste Schritte
Modellkatalog und Schemas
Wie Sie das inputSchema eines Modells lesen und gültige Eingaben wählen
Asynchrone Tasks
Task-Status, Polling und was jedes Feld bedeutet
Kostenschätzungen und Kompatibilität
Den exakten Preis einer Anfrage sehen, bevor Sie ihn zahlen
Webhooks
Zustellformat, Wiederholungsplan und Signaturprüfung
Fehler
Jeder Fehlercode und welche sich zu wiederholen lohnen
Python-SDK
Derselbe Ablauf in Python, ganz ohne Laufzeitabhängigkeiten
Python-SDK
Das offizielle Python-SDK für SpicyAPI (spicyapi) – installieren, die erste Generierung schätzen und ausführen, eine lokale Datei hochladen, Webhooks prüfen und jeden Fehlercode nachschlagen.
PHP-SDK
Das offizielle PHP-SDK für SpicyAPI (spicyapi/spicyapi) – mit Composer installieren, die erste Generierung schätzen und ausführen, eine lokale Datei hochladen, Webhooks sicher prüfen und jeden Fehlercode behandeln.

