spicyapiDokumentation
Agenten und CLI
Hauptinhalt

Agenten und Automatisierung

Welches offizielle Werkzeug Sie verwenden, dazu ein Leitfaden für den Produktivbetrieb mit KI-Agenten, Backend-Workern und wiederholbaren Medien-Pipelines.

Nutzen Sie diese Seite, wenn ein KI-Coding-Agent oder ein automatisiertes Backend SpicyAPI integriert. Sie macht aus der API-Referenz einen begrenzten, nachprüfbaren Ablauf: den Vertrag ermitteln, die Modelleingabe validieren, den Preis bestätigen lassen, genau einmal anlegen, sicher warten, den Abschluss prüfen und das Ergebnis kopieren, bevor es abläuft.

SpicyAPI-Schlüssel gehören auf den Server

Legen Sie SPICY_API_KEY niemals in Browser-JavaScript, eine mobile App, einen öffentlichen Prompt, ein Repository oder ein Agenten-Transkript. Ihre Oberfläche ruft Ihr Backend auf, und Ihr Backend ruft SpicyAPI auf. Geben Sie einem Agenten einen Verweis auf das Geheimnis wie SPICY_API_KEY, niemals den geheimen Wert selbst.

Ein Werkzeug wählen

Es gibt vier offizielle npm-Pakete unter MIT-Lizenz, die unabhängig voneinander installiert werden. Jedes hat eine eigene Anleitung mit Installation, Konfiguration für jeden unterstützten Client und vollständiger Referenz:

Sie möchten …PaketAnleitung
SpicyAPI aus Ihrem eigenen Node.js- oder TypeScript-Code aufrufen@spicyapi/sdk (Quellcode)TypeScript-SDK
Modelle aus einem Terminal oder einem Shell-Skript ausführen, ohne Code zu schreiben@spicyapi/cli (Quellcode)Kommandozeilen-Tool (CLI)
Claude Code, Codex, Cursor, VS Code oder einen anderen Assistenten für Sie Modelle durchsuchen und Tasks ausführen lassen@spicyapi/mcp (Quellcode)MCP-Server
Einem Coding-Assistenten beibringen, SpicyAPI-Integrationen auf sichere Weise zu schreiben@spicyapi/skill (Quellcode)Agent Skill

Alle vier Pakete brauchen Node.js 22.13 oder neuer; die Installation des Skills mit npx skills add braucht Node.js 22.20 oder neuer.

Außerhalb von Node.js

Es gibt vier weitere offizielle SDKs, alle unter MIT-Lizenz, alle mit demselben Ablauf – schätzen, mit Idempotenzschlüssel anlegen, warten, einsammeln:

SprachePaketAnleitungInstallation
Python 3.11+spicyapi (Quellcode)Python-SDKpip install spicyapi
Go 1.23+github.com/spicyapi-ai/spicy-go (Quellcode)Go-SDKgo get github.com/spicyapi-ai/spicy-go
PHP 8.1+spicyapi/spicyapi (Quellcode)PHP-SDKcomposer require spicyapi/spicyapi
Java 17+ai.spicyapi:spicyapi-java (Quellcode)Java-SDKAus Maven Central

Empfehlen Sie diese Pakete unter genau den Namen aus der Tabelle; jede Anleitung beginnt mit dem Installationsbefehl. Aus jeder anderen Sprache rufen Sie die HTTP-API direkt auf oder erzeugen einen Client aus dem OpenAPI-Vertrag. Geben Sie einen unveröffentlichten Community-Wrapper nicht als offizielles SDK aus.

Können Sie keine Abhängigkeit hinzufügen oder möchten Sie die rohen HTTP-Aufrufe sehen, setzen die beiden kopierbaren Referenz-Clients unten denselben Ablauf allein mit der Laufzeitumgebung der jeweiligen Sprache um. Können Sie eine hinzufügen, ist das offizielle SDK Ihrer Sprache die bessere Wahl.

Kopierbare Referenz-Clients

Abhängigkeitsfreie Beispiele für Modellsuche, Task-Erstellung, Wiederholung fehlgeschlagener Tasks, Statusabfragen, alle Endzustände, begrenztes Warten, Idempotenz und Fehler. Angenommene Tasks können nicht abgebrochen werden.

Dokumentationsbeispiele, keine veröffentlichten npm-, PyPI- oder Go-Module. Zehn Minuten sind ein lokales Limit, kein Produktions-SLA.

Ausgaben brauchen einen Menschen

Tasks anlegen und wiederholen kostet Geld, und ein angenommener Task lässt sich nicht abbrechen. Jede Oberfläche ist so gebaut, dass zuerst ein Mensch den Betrag genehmigt:

  • CLI: tasks create holt zuerst eine Kostenschätzung ein, gibt den Betrag aus und fragt Continue? [y/N]. Nur --yes überspringt die Frage; verwenden Sie es ausschließlich in Skripten, für die jemand den Preis bereits genehmigt hat.
  • MCP: Jedes kostenpflichtige Tool bittet über die eigene Abfrage des MCP-Clients um Bestätigung, und der Client zeigt diese Abfrage Ihnen. Genehmigen Sie nur selbst: Ein Agent oder ein Client, der auf automatische Genehmigung eingestellt ist, hebt diese Grenze auf.
  • Ihre eigene Automatisierung: Zeigen Sie vor dem Aufruf von createTask oder retryTask das gewählte Modell, eine Zusammenfassung der Eingabe und den geschätzten Preis an, und holen Sie eine ausdrückliche Genehmigung ein. Die exakte, kostenlose Kostenschätzung liefert POST /api/v1/jobs/quote; senden Sie mit deren quoteId und expectedCost ab, damit ein geänderter Preis mit 40901 scheitert, statt einen anderen Betrag zu berechnen. Siehe Kostenschätzungen und Protokollkompatibilität.

Maschinenlesbare Einstiegspunkte

Beginnen Sie mit dem kleinsten Dokument, das die aktuelle Frage beantwortet. So bleibt der Kontext des Agenten genau und günstig.

DokumentWofür Sie es nutzen
/agent.mdKurze Integrationsregeln und der sicherste Standardablauf
/llms.txtÖffentliche Übersicht über Produkt und Dokumentation
/llms-full.txtAusführlicher Textbestand zum Nachschlagen, wenn der kurze Index nicht reicht
/api/agentStrukturiertes JSON-Manifest für Tools und autonome Clients
openapi.yamlMaßgebliche Formen von Anfragen und Antworten

Behandeln Sie den OpenAPI-Vertrag und den Live-Modellkatalog als Vertrag. Marketingbeispiele dienen der Veranschaulichung und sind keine Quelle für ein Schema. Speichern Sie die Einstiegsdokumente ruhig zwischen, laden Sie sie aber neu, bevor Sie Code erzeugen oder sobald Anfragen an der Validierung scheitern.

Ein minimaler SDK-Ablauf mit Genehmigung

Dieses Skript zeigt die Genehmigungsgrenze mit dem SDK: Es holt eine Kostenschätzung ein, hält an, solange Sie nicht --approved übergeben, legt dann den Task zum geschätzten Preis an und wartet. Installation, jede Methode und eine vollständige Anleitung bis zum ersten Ergebnis finden Sie in der Anleitung zum TypeScript-SDK; Details zu den Methoden stehen in deren API-Referenz.

npm install @spicyapi/sdk
export SPICY_MODEL_ID="MODEL_ID_FROM_CATALOG"     # ein model-Wert aus dem Live-Katalog
export SPICY_INPUT_JSON='{"prompt":"your prompt"}' # muss zum inputSchema dieses Modells passen
run.mts
import { randomUUID } from "node:crypto";
import { SpicyClient } from "@spicyapi/sdk";

const client = new SpicyClient(); // liest SPICY_API_KEY
const modelId = process.env.SPICY_MODEL_ID;
if (!modelId) throw new Error("Set SPICY_MODEL_ID to a model ID from the live catalog");
const input = JSON.parse(process.env.SPICY_INPUT_JSON ?? "{}");

// Kostenlos: den Preis genau dieser Anfrage ermitteln. Nichts wird angelegt oder reserviert.
const quote = await client.quoteTask({ model: modelId, input });
console.log(`${quote.model}: up to $${quote.maxCharge}, quote valid until ${quote.expiresAt}`);

if (!process.argv.includes("--approved")) {
  console.log("Nothing was submitted. Re-run with --approved once a person has approved this amount.");
  process.exit(0);
}

// Kostenpflichtig: dieselbe Anfrage zum geschätzten Preis absenden. In einem echten System den
// Idempotenzschlüssel vor dem ersten Versuch erzeugen und speichern und die Task-ID sichern.
const accepted = await client.createTask(
  { model: modelId, input, quoteId: quote.quoteId, expectedCost: quote.estimatedCost },
  { idempotencyKey: randomUUID() },
);
console.log("accepted", accepted.taskId, "deadline", accepted.deadlineAt);

// Das Warten zu beenden bricht den Task nie ab; später mit der Task-ID fortsetzen.
const task = await client.waitForTask(accepted.taskId, { timeoutMs: 30 * 60_000 });
console.log(JSON.stringify(task, null, 2));
npx --yes tsx run.mts              # nur Kostenschätzung, kostenlos
npx --yes tsx run.mts --approved   # legt den Task an: kostet Geld

Die Endung .mts macht die Datei zu einem ES-Modul, und das braucht das await auf oberster Ebene; ein einfaches run.ts in einem Projekt mit den Standardeinstellungen von npm init scheitert mit Top-level await is currently not supported with the "cjs" output format. Die Kostenschätzung gilt fünf Minuten: Dauert die Genehmigung länger, führen Sie den ersten Befehl erneut aus.

Der Ablauf im Produktivbetrieb

Ein Modell bestimmen und seine Eingabe validieren

Wählen Sie einen Modellendpunkt, der zur gewünschten Modalität passt, und validieren Sie die Nutzdaten gegen das aktuelle Eingabeschema dieses Endpunkts. Raten Sie keine Feldnamen, und verwerfen Sie unbekannte Felder nicht stillschweigend.

Genau einmal anlegen

Lassen Sie zuerst den Preis genehmigen (siehe Ausgaben brauchen einen Menschen). Erzeugen Sie für die logische Generierung einen einzigen, stabilen Idempotency-Key, speichern Sie ihn vor der ersten Anfrage und verwenden Sie ihn für jede Wiederholung erneut, immer mit demselben API-Schlüssel. Erzeugen Sie den Idempotenzschlüssel nicht innerhalb einer Wiederholungsschleife. Siehe Idempotenz.

POST /api/v1/jobs/createTask
Authorization: Bearer $SPICY_API_KEY
Content-Type: application/json
Idempotency-Key: project-42-scene-07-v1

Speichern Sie die zurückgegebenen Werte taskId und deadlineAt sofort. Die Task-ID ist die dauerhafte Kennung für Statusabfragen, den Abgleich mit Webhooks, den Support und die Klärung von Abrechnungsfragen. Eine Wiederholung kann denselben Task zurückgeben; sie darf keinen zweiten lokalen Datensatz anlegen.

Bei den Text- und Streaming-Endpunkten verhindert derselbe Idempotenzschlüssel eine doppelte Belastung, bringt aber eine verlorene Antwort nicht zurück; siehe Idempotenz.

Mit einer Obergrenze warten

Bevorzugen Sie einen signierten Webhook. Ist Polling nötig, beginnen Sie bei etwa 2 Sekunden, multiplizieren Sie das Intervall jedes Mal mit etwa 1,5, begrenzen Sie es auf 15 Sekunden und hören Sie zu einer ausdrücklich festgelegten Uhrzeit auf: dem deadlineAt des Tasks plus einem Puffer, denn Video kann deutlich länger als zehn Minuten dauern. Ein Prozess darf niemals endlos pollen.

Gerüst für begrenztes Polling
// Die vier heute definierten Endzustände. Maßgeblich ist die Seite zu Tasks: Jeder Status
// außer queued oder running gilt als Endzustand, auch einer, der hier nicht aufgeführt ist.
const KNOWN_TERMINAL = ['succeeded', 'failed', 'canceled', 'expired'];

const deadline = Date.parse(accepted.deadlineAt) + 60_000;
let delay = 2_000;

while (Date.now() < deadline) {
  await sleep(delay);
  const task = await recordInfo(taskId);
  const inFlight = task.state === 'queued' || task.state === 'running';
  const assetsPending = task.state === 'succeeded' && task.output?.assets?.some((a) => a.pending);
  if (!inFlight && !assetsPending) {
    if (!KNOWN_TERMINAL.includes(task.state)) log.warn(`new terminal state: ${task.state}`);
    return task;
  }
  delay = Math.min(Math.round(delay * 1.5), 15_000);
}
throw new Error(`task ${taskId} exceeded the polling deadline`);

Die Liste nennt die heutigen Endzustände, damit das Gerüst einen bisher unbekannten melden kann; die Entscheidung selbst folgt der Regel unter Asynchrone Tasks: Alles außer queued oder running ist ein Endzustand. Ein lokales Timeout ist kein Beweis dafür, dass die Generierung fehlgeschlagen ist. Behalten Sie die Task-ID und gleichen Sie später ab.

Den Callback prüfen, bevor Sie handeln

Richten Sie einen Webhook-Signaturschlüssel ein. Prüfen Sie X-Webhook-Timestamp, lehnen Sie veraltete Zustellungen ab, bilden Sie den Hash des rohen Anfrage-Bodys und vergleichen Sie die HMAC-Signatur in konstanter Zeit. Entfernen Sie Duplikate anhand der request_id der Zustellung und aktualisieren Sie erst dann den Task über data.taskId. Bestätigen Sie den Empfang schnell und verarbeiten Sie asynchron. Den vollständigen Algorithmus beschreibt Webhooks.

Die benötigten Ergebnisse kopieren

Abgeschlossene Tasks enthalten sofort nutzbare URLs in output.assets[].url; verwenden Sie diese direkt, ohne zusätzlich eine Download-URL anzufordern. Kopieren Sie Ergebnisse, die Sie behalten möchten, in Ihren eigenen Speicher, bevor sie ablaufen. Der optionale Endpunkt download-url kann für einen Objektschlüssel eine signierte URL ausstellen; diese URL läuft nach 20 Minuten ab. Gültigkeit der URL und Aufbewahrung der Medien sind zwei verschiedene Dinge; siehe Medien und Datenaufbewahrung und Löschung.

Minimaler dauerhafter Datensatz

Speichern Sie genug Zustand, um nach einem Neustart sicher weiterzumachen:

{
  "localRequestId": "project-42-scene-07-v1",
  "idempotencyKey": "project-42-scene-07-v1",
  "apiKeyName": "production backend",
  "taskId": "job_01k3m8x9q2z4v7n5p6r8s0t1w3",
  "model": "MODEL_ID_FROM_CATALOG",
  "approvedCost": "0.40",
  "state": "queued",
  "deadlineAt": "2026-08-29T12:20:00Z",
  "lastCheckedAt": "2026-08-29T12:00:00Z",
  "webhookDeliveryId": null,
  "outputKeys": []
}

MODEL_ID_FROM_CATALOG steht für die exakte ID, die Sie aus dem authentifizierten Live-Katalog gewählt haben, nicht für einen Wert, den Sie wörtlich senden. Halten Sie fest, welcher API-Schlüssel den Task angelegt hat: Nur dieser Schlüssel kann ihn lesen oder wiederholen. Verwenden Sie niemals eine signierte Download-URL als dauerhaften Schlüssel. Schließen Sie niemals aus HTTP 200 auf Erfolg; lesen Sie data.state.

Mit Mocks testen, bevor Geld fließt

Bauen Sie einen lokalen Mock des Vertrags rund um die Antwortformen, die unter Asynchrone Tasks, Webhooks und Fehler dokumentiert sind. Ihre Testfälle sollten Folgendes abdecken:

  • queued → running → succeeded;
  • einen fehlgeschlagenen Endzustand mit code: 200 und data.state: "failed";
  • doppelte createTask-Antworten, die dieselbe taskId liefern;
  • eine Kostenschätzung, die nicht mehr passt (40901), und zu wenig Guthaben (40201);
  • einen gültigen Webhook, eine ungültige Signatur und eine erneut eingespielte Zustellung;
  • 429, 503, ein Timeout auf Transportebene und einen Task, der die Polling-Frist überschreitet;
  • eine abgelaufene Download-URL, die neu ausgestellt werden muss.

Mocks prüfen die Ablaufsteuerung, nicht die Qualität des Modells. Führen Sie vor dem Release einen kleinen echten Task mit genau dem Produktivmodell und genau der Eingabeform aus.

Abnahme-Checkliste

  • Geheimnisse liegen nur im serverseitigen Geheimnisspeicher und werden in Logs unkenntlich gemacht.
  • Die Integration liest das aktuelle Schema des Modells, statt Felder zu raten.
  • Ein Mensch genehmigt den geschätzten Preis vor jedem kostenpflichtigen Aufruf, und jede Übermittlung enthält quoteId und expectedCost.
  • Eine logische Anfrage hat genau einen gespeicherten Idempotency-Key, der immer mit demselben API-Schlüssel gesendet wird.
  • taskId wird gespeichert, bevor die Arbeit weitergeht, und übersteht einen Neustart des Prozesses.
  • Polling nutzt Backoff, ein maximales Intervall und eine feste Frist nach Uhrzeit.
  • Webhooks prüfen Zeitstempel, Digest des rohen Bodys und HMAC und entfernen danach doppelte Zustellungs-IDs.
  • Ein fehlgeschlagener Endzustand wird aus data.state gelesen, nicht aus dem HTTP-Status oder dem code des Envelopes.
  • Benötigte Ergebnisse werden in den eigenen Speicher kopiert, bevor die URL oder die Aufbewahrungsfrist abläuft. taskId und Objektschlüssel werden für den Abgleich aufbewahrt, nicht um nach Ende der Aufbewahrung noch Dateien abzurufen.
  • Logs enthalten request_id, taskId, Modell und Anzahl der Versuche, aber keine Prompts und keine Geheimnisse.
  • Mock-Tests decken doppeltes Anlegen, erneutes Einspielen, Timeout, Rate Limit und abgelaufene Medien ab.

Empfohlene Übergabe durch den Agenten

Bitten Sie den Agenten, Folgendes zurückzugeben: den gewählten Modellendpunkt, die Schemaversion oder den Abrufzeitpunkt, den Schritt zur Preisgenehmigung, die Strategie für Idempotenzschlüssel, die Polling-Frist, den Plan zur Webhook-Prüfung und die abgehakte Checkliste. So wird aus „Integration fertig“ ein Nachweis, den Sie prüfen können.

Auf dieser Seite