spicyapiDokumentation
Referenz
Hauptinhalt

Spicy-Schema-Vertrag

Gemeinsame Anfragestruktur, einheitliche Felder, Formularschema, asynchroner Lebenszyklus, Fehler, Ergebnisspeicher und Kompatibilität.

Spicy Schema ist der öffentliche Vertrag für jedes neue Medienmodell. Ein hinzugefügtes Modell ändert model, inputSchema und Kundenpreis; Authentifizierung, Tasks, Ergebnisse, Fehler und Downloads bleiben gleich.

Dies ist eine Referenzseite. Für die meisten Integrationen reicht Modellkatalog und Schemas. Lesen Sie weiter, wenn Sie aus inputSchema Formular, Validator oder Codegenerator erstellen und genau wissen möchten, worauf Sie sich verlassen können.

Nur der Livekatalog belegt Aufrufbarkeit

Diese Seite definiert die Vertragsstruktur, behauptet aber nicht, ein Modell sei live. Lesen Sie vor bezahlter Arbeit die authentifizierte Antwort von GET /api/v1/models und verlangen enabled: true sowie available: true. Geplante und deaktivierte Einträge sind nicht aufrufbar.

Öffentliche Grenze

Eine öffentliche Modell-ID bezeichnet eine stabile Fähigkeit im Format <publisher>/<model>/<task>. Publisher ist der Modellhersteller: Autor oder Forschungsorganisation hinter dem Modell. Bildbearbeitung verwendet immer den Suffix edit; früher veröffentlichte Kennungen bleiben akzeptiert. Kopieren Sie echte IDs immer aus dem Livekatalog; MODEL_ID_FROM_CATALOG ist hier ein Platzhalter.

Öffentliche Antworten, Webhooks, Fehler und Downloads verwenden nur eigene SpicyAPI-Kennungen, Fehlercodes und URLs. Sie enthalten nie interne Verarbeitungsdetails, Rohantworten, Rohfehler oder interne Geschäftsdaten. Ergebnisse werden vor Rückgabe in SpicyAPIs eigenen Speicher kopiert.

Einheitliche Erstellungsstruktur

{
  "model": "MODEL_ID_FROM_CATALOG",
  "input": {
    "prompt": "slow camera push-in",
    "image_url": "spicy://f/fil_01k3m8x9q2z4v7n5p6r8s0t1w3",
    "duration_seconds": 8,
    "resolution": "1080p",
    "generate_audio": true
  },
  "callBackUrl": "https://your-app.example.com/hooks/spicy"
}
FeldRegel
modelExakter aktuell aufrufbarer Wert aus authentifiziertem Livekatalog
inputMuss dem aktuellen inputSchema desselben Eintrags entsprechen; unbekannte Felder werden abgelehnt
callBackUrlOptionale öffentliche HTTPS-Adresse für abgeschlossenen Task, mit genau dieser Schreibweise. Siehe Webhooks

Der input oben ist illustrativ. Nur das jeweilige inputSchema bestimmt, welche Felder ein Modell akzeptiert.

Einheitliche Felder

Dasselbe Konzept verwendet über alle neuen Endpunkte einen snake_case-Namen. Die Tabelle zeigt häufige Felder, nicht sämtliche; vollständig ist stets das inputSchema eines Modells.

KonzeptFeldTyp
Positiver PromptpromptString
Negativer Promptnegative_promptString
Erstes / letztes Bildimage_url / last_image_urlBildreferenz, siehe unten
Mehrere Eingabebilderimage_urlsArray von Bildreferenzen
Bearbeitungsmaskemask_urlBildreferenz
Primäres Video / Audiovideo_url / audio_urlÖffentliche HTTPS-URL oder bestätigte spicy://-URI
Referenzmedienreference_image_urls / reference_video_urls / reference_audio_urlsArray von Referenzen
Ausgabedauerduration_secondsZahl oder Ganzzahl
Auflösung / Seitenverhältnisresolution / aspect_ratioDokumentiertes Enum
Exakte Ausgabegrößesize als Vorgabe oder width / heightDokumentiertes Enum / Ganzzahl
BildratefpsGanzzahl
Natives Audiogenerate_audioBoolescher Wert
ZufallsseedseedGanzzahl
Adaptergewichteloras oder high_noise_loras / low_noise_loras bei separat verfügbaren StufenArray von Objekten
Ausgabeanzahlnum_outputsPositive Ganzzahl
Kodierungoutput_formatDokumentiertes Enum
ChatgesprächmessagesArray
Ausgabelänge / Samplingmax_tokens / temperatureGanzzahl / Zahl

Eine Bildreferenz ist eine öffentliche HTTPS-URL, eine bestätigte spicy://-URI aus einem Upload oder eine kleine data:image/…;base64,…-URI. Video und Audio dürfen nicht inline gesendet werden. Siehe Medien.

Ein Adaptergewichteintrag nennt einen Gewichtssatz und seine Anwendungsstärke. Der Feldname ist fest, die Eintragsstruktur nicht: Ob ein Endpunkt für die Gewichtsdatei URL oder Bibliotheksschlüssel akzeptiert, begrenzt sein eigenes items-Teilschema. Lesen Sie dieses, statt ein Format anzunehmen. Dasselbe gilt für maximale Eintragszahl und erforderliche Unterfelder.

Ein modellspezifisches Feld existiert nur für eine echte Fähigkeit, die kein einheitliches Feld abdeckt, und wird danach benannt. Ältere Endpunkte können frühere Feldnamen in ihrem Live-inputSchema behalten; neue kopieren sie nicht.

inputSchema und UI-Annotationen

Jedes Modell verwendet JSON Schema 2020-12 in inputSchema. Dasselbe Schema steuert Servervalidierung, Playground-Formulare, Beispiele und Preisabfragen. Das offizielle TypeScript-SDK typisiert gemeinsame Anfrage- und Antwortstrukturen statisch. Modellspezifischer input bleibt Record<string, unknown> und muss gegen das Liveschema validiert werden; generierte Modellfelder dürfen nicht angenommen werden.

Diese Website hält keine Parametertabellen je Modell vor. Die einzige Quelle ist inputSchema aus GET /api/v1/models?includeSchema=1, das auch der Playground darstellt. Statische Kopien veralten durch Modelländerungen, ohne dass dies sicher erkannt wird. Für eigene Tabellen siehe Modellkatalog und Schemas.

Jedes gelieferte Schema:

  • hat eine object-Wurzel und lehnt unbekannte Felder ab (additionalProperties: false);
  • nennt required, Typen, Enums, Bereiche, Längen, Arraygrenzen, URI-Formate, Standards und geprüfte Bedingungen;
  • gibt jeder Eigenschaft eine nicht leere englische description;
  • lässt ungeprüfte Felder und Standards weg, statt sie zu erraten;
  • definiert Bedingungen durch anyOf / allOf an der Wurzel, siehe unten, nie allein durch UI-Sichtbarkeit;
  • enthält keine Schalter für ausschließlich interne Verarbeitung und keine Inhaltsfilter-Schalter.

Darstellungsannotation x-ui

Darstellungsmetadaten sind kein zweites Validierungsschema. Sie stehen im eigenen x-ui-Objekt der Eigenschaft, dessen snake_case-Schlüssel aus einem geschlossenen Satz stammen:

SchlüsselBedeutung
widgetDarzustellendes Bedienelement, Werte unten
orderDie Feldreihenfolge, absteigend, je Endpunkt eindeutig
label / placeholderStandardbeschriftung ersetzen; Eingabeplatzhalter
rowsZeilenzahl des Textfelds
step / unitZahlenschritt und Einheitensuffix wie s, px
accept / max_size_mbMIME-Filter und maximale Einzeldateigröße für Uploads
advancedGehört in eingeklappten erweiterten Abschnitt
primaryHaupteingabe, oben fixiert und nie eingeklappt
affects_priceWertänderung verlangt neue Preisabfrage
visible_whenAusdruck für bedingte Sichtbarkeit
enum_labelsEnum-Wert zu sichtbarer Beschriftung

x-ui.widget hat dreizehn mögliche Werte: textarea, text, upload, multi-upload, select, radio, slider, number, switch, json, object-list, chat-messages, hidden. Widgets passen immer zur Datenstruktur, sodass Renderer direkt unterscheiden können: select und radio enthalten immer enum; slider enthält minimum und maximum, nie nur exclusiveMinimum / exclusiveMaximum; switch ist boolean; multi-upload ist ein Array mit items.type: string; object-list ist ein Array mit items.type: object und items.properties, dessen Unterfelder jeweils type und description haben; chat-messages ist ein Array; hidden wird weiter gesendet, hat aber kein Bedienelement.

Bei jedem Array bestimmen eigene minItems / maxItems und items Grenzen, die die Wurzel-required-Liste nicht nennt. Der Server setzt sie wie alle anderen Schemaregeln durch. items einer object-list ist ein vollständiges Objektschema mit eigenem required, eigenem additionalProperties: false sowie Typ, Bereich und default je Unterfeld. Standards reichen in diese Einträge: Ein weggelassenes Unterfeld wird vor Validierung aus default ergänzt. Ein erforderliches Unterfeld mit Standard ist daher effektiv optional; ohne Standard wird Fehlen abgelehnt, ebenso unbekannte Unterfelder und Werte außerhalb des Bereichs.

Ein 400 für einen Wert im Array verweist auf den konkreten Eintrag – Feld, nullbasierter Index und Unterfeld – statt auf die ganze Anfrage. Geben Sie diesen Zeiger an die korrigierende Person weiter: Bei mehreren Einträgen entscheidet er zwischen einer einzeiligen Korrektur und aufwendiger Eingrenzung.

Clients müssen unbekannte Darstellungsschlüssel ignorieren. Ein neuer x-ui-Schlüssel ist rückwärtskompatibel.

{
  "type": "object",
  "required": ["prompt", "duration_seconds"],
  "additionalProperties": false,
  "properties": {
    "prompt": {
      "type": "string",
      "minLength": 1,
      "description": "Describes the scene and its motion.",
      "x-ui": { "widget": "textarea", "order": 100, "primary": true, "rows": 4 }
    },
    "duration_seconds": {
      "type": "integer",
      "enum": [5, 8, 10],
      "description": "Output duration in seconds.",
      "x-ui": { "widget": "radio", "order": 90, "unit": "s", "affects_price": true }
    }
  },
  "x-pricing": { "variantFields": ["duration_seconds"], "billingMode": "variant_matrix" }
}

Jede description ist englische Prosa und kann unverändert als Hilfetext dargestellt werden.

x-ui.affects_price: true fordert die UI zur Preisaktualisierung nach Änderung auf. Es ist keine Preisformel und ersetzt weder Katalog-pricing noch quantityField. Wurzel-x-pricing bildet denselben Sachverhalt serverseitig ab: variantFields nennt preisbestimmende Stufenfelder und ist immer eine Teilmenge der affects_price: true-Felder; billingMode beschreibt die Abrechnung des Endpunkts. Beides sind Hinweise. Maßgeblich ist der Betrag aus Katalog, Preisabfrage und Task. Stufen in pricing erklärt Preise lesen.

Bedingte Felder

Bedingungen haben genau zwei Formen, beide an der Wurzel:

{
  "anyOf": [{ "required": ["image_url"] }, { "required": ["image_urls"] }],
  "allOf": [
    { "if": { "required": ["last_image_url"] }, "then": { "required": ["image_url"] } },
    { "if": { "properties": { "resolution": { "const": "4k" } } }, "then": { "required": ["seed"] } }
  ]
}

Jeder anyOf-Zweig enthält nur required und bedeutet mindestens eines davon angeben. Jeder allOf-Zweig ist ein if → then: if prüft required oder properties.<field>.const, then nennt nur required; bei A muss B angegeben werden.

oneOf, not, dependentSchemas und dependentRequired erscheinen nie im inputSchema. Sie können Bedingungen ausdrücken, sind aber nicht als Formular darstellbar; der Nutzer würde erst nach Absenden durch unerklärbares 400 davon erfahren. Die zwei Formen oben decken alle bedingten Endpunkte ab.

Asynchroner Lebenszyklus

queued -> running -> succeeded
                  -> failed
                  -> expired

createTask liefert eine Spicy-Task-ID. Fragen Sie recordInfo ab oder empfangen einen signierten Spicy-Webhook. queued und running sind nicht abgeschlossen; die anderen Zustände sind abgeschlossen. Historische canceled-Datensätze bleiben aus Kompatibilitätsgründen lesbar, neue Tasks bieten keine Abbruchaktion. Asynchrone Tasks ist maßgeblich für Zustände.

Ein unbekannter nicht abgeschlossener Modellzustand wird bis zu bekanntem Endzustand oder absoluter Plattformfrist als running abgebildet. Eine nicht idempotente Einreichung mit ungewisser Bestätigung wird nicht blind wiederholt, um doppelte Generierung und Belastung zu vermeiden.

Einheitliche Antworten und Fehler

Jede native JSON-API (/api/v1) nutzt dieselbe Struktur; /v1- und /v1beta-Kompatibilität nutzt die eigenen Protokollformate:

{
  "code": 200,
  "msg": "success",
  "data": {},
  "request_id": "req_01k3m8x9q2z4v7n5p6r8s0t1w2"
}

Bei synchronem Fehler fehlt data. Verzweigen Sie nach code, nie nach veränderlichem msg; verwenden Sie request_id für Support. Fehler nach Taskerstellung verwenden data.state: "failed" und stabilen errorCode. errorMessage ist lesbar: Ein konkreter modellseitiger Grund erscheint auf Englisch ohne interne Namen, Adressen und Kontodetails; andernfalls eine Plattformmeldung in Ihrer Fehlersprache. Verzweigen Sie nach errorCode, nie nach errorMessage.

Ergebnisse und Downloads

Ein erfolgreicher Task führt seine Dateien in output.assets[]. Jede bereite Datei enthält bereits einen Downloadlink:

{
  "assets": [
    {
      "key": "tasks/2026/08/31/job_01k3m8x9q2z4v7n5p6r8s0t1w3/asset_01.mp4",
      "url": "https://example.r2.cloudflarestorage.com/results/asset_01.mp4?X-Amz-Signature=SIGNATURE_FROM_RESPONSE",
      "expiresAt": "2026-08-31T10:20:00Z",
      "mime": "video/mp4",
      "durationSeconds": 8,
      "bytes": 1234567
    }
  ]
}

Laden Sie url direkt ohne API-Key herunter. Sie gilt normalerweise 20 Minuten. Lesen Sie den Task für einen neuen Link erneut, solange das Ergebnis aufbewahrt wird, höchstens 14 Tage. Während Speicherung hat die Datei pending: true ohne url; nach endgültigem Speicherfehler unavailable: true. key kennzeichnet die Datei für optionales download-url; zum Herunterladen ist er nicht nötig. Alle Links verweisen auf SpicyAPIs eigenen Speicher.

Kundenabrechnung

Katalog-pricing, startingPrice, quantityField und Task-estimatedCost / cost beschreiben nur Kundenpreise. Beträge sind dezimale USD-Strings. Interne Geschäftsdaten gehören nicht zum öffentlichen Vertrag und erscheinen nie in Katalogen, Tasks, Webhooks oder exportierten Logs.

Kompatibilität und Ablösung

Folgende Änderungen sollten Sie ohne Funktionsbruch tolerieren: neues optionales Feld, ignorierbares Antwortfeld oder unbekannter x-ui-Hinweis.

Neues Pflichtfeld, entfernter Enum-Wert, Bedeutungs- oder Typänderung, engeres Limit und geänderte öffentliche Modell-ID erhalten eine neue Modellversion oder angekündigte Ablösungsfrist. Veröffentlichte IDs bleiben unveränderlich; Migration verwendet Kompatibilitätsalias oder ausdrückliche Weiterleitung.

Speichern Sie den authentifizierten Katalog wie unter Katalog zwischenspeichern beschrieben zwischen. Behalten Sie nie eine dauerhafte Schemakopie und verwenden keine statische Seite als Ersatz für einen Livekatalog ohne aufrufbaren Eintrag.

Auf dieser Seite