spicyapiDokumentation
Mit der API entwickeln
Hauptinhalt

Modellkatalog und Schemas

Wählen Sie aufrufbare Modelle im authentifizierten Livekatalog, lesen Sie Preise und erstellen Sie Anfragen aus ihrem aktuellen JSON Schema.

createTask.model benötigt exakt den model-Wert aus der authentifizierten Antwort von GET /api/v1/models. Dessen input wird durch das aktuelle inputSchema desselben Eintrags definiert. Diese Laufzeitantwort ist die einzige maßgebliche Quelle für aufrufbare IDs.

Kopieren Sie keine ID von einer statischen Seite

Veröffentlichungsschnappschüsse, Modellfamilienseiten und Herstellerkataloge dienen der Entdeckung. Sie können geplante, deaktivierte oder umbenannte Einträge enthalten und sind nie Ersatz für einen leeren Livekatalog. Lesen Sie vor bezahlter Arbeit den authentifizierten Katalog und verlangen sowohl enabled: true als auch available: true.

In diesen Beispielen ist MODEL_ID_FROM_CATALOG ein Platzhalter, kein reales Modell. Ersetzen Sie ihn durch einen model-Wert aus Ihrem eigenen Livekatalog. Kataloglesen ist kostenlos.

Modell und validierte Eingabe auswählen

Anfrageschemas unterscheiden sich je Modell. Der sichere ausführbare Weg wählt daher gemeinsam ein Livemodell und eines seiner serverseitig validierten Beispiele:

const response = await fetch(
  'https://api.spicyapi.ai/api/v1/models?includeSchema=1&includeExamples=1',
  { headers: { Authorization: `Bearer ${process.env.SPICY_API_KEY}` } },
);
const envelope = await response.json();
if (!response.ok || envelope.code !== 200) throw new Error(envelope.msg);

const selected = envelope.data.items.find(
  (item) => item.enabled && item.available && item.examples?.length,
);
if (!selected) throw new Error('No callable model with a validated example');

const createTaskBody = {
  model: selected.model,
  input: selected.examples[0].input,
};

Jedes Beispiel ist ein vollständiger input, den der Server bereits gegen das aktuelle Schema geprüft hat. Sie können ihn unverändert einreichen.

Katalog programmgesteuert lesen

GET /api/v1/models
GET /api/v1/models/{model}
curl "https://api.spicyapi.ai/api/v1/models?modality=video" \
  -H "Authorization: Bearer $SPICY_API_KEY"

Die Liste hat keine Paginierung. Eine Antwort enthält alle für Ihren Key sichtbaren Modelle, die zu den Filtern passen. Alle Parameter sind optional.

ParameterBedeutung
modalityimage, video, audio oder text
providerModellhersteller, exakt und mit Groß-/Kleinschreibung abgeglichen, etwa ByteDance. Aus provider eines Eintrags kopieren
taskEine Aufgabe, etwa text-to-image, edit (Bildbearbeitung), image-to-video, text-to-video, reference-to-video, speech-to-text, video-analyze, video-edit, video-extend, character-animation oder chat. Aktuelle Auswahl unter tasks lesen. Bildbearbeitung akzeptiert zwei Schreibweisen: Modelle werden als .../edit veröffentlicht, tasks ordnet sie als image-to-image ein; der Filter akzeptiert beide
searchTextsuche in Modell-ID oder Anzeigename, ohne Groß-/Kleinschreibung, bis 128 Zeichen
includeSchematrue oder 1 ergänzt inputSchema je Eintrag
includeExamplestrue oder 1 ergänzt gegen aktuelles Schema validierte examples

Der Einzelmodellendpunkt GET /api/v1/models/{model} enthält immer inputSchema und examples; includeSchema und includeExamples betreffen nur die Liste. Schrägstriche der ID können unverändert bleiben. Prozentkodieren Sie sie nur, wenn Ihr HTTP-Client einen Pfadparameter als einzelnes Segment behandelt. Ein nicht existierendes oder aktuell nicht angebotenes Modell liefert 404.

Eine gekürzte Listenantwort:

{
  "code": 200,
  "msg": "success",
  "data": {
    "total": 1,
    "items": [
      {
        "model": "MODEL_ID_FROM_CATALOG",
        "family": "…",
        "displayName": "…",
        "provider": "…",
        "modality": "video",
        "tasks": ["image-to-video"],
        "async": true,
        "enabled": true,
        "available": true,
        "availability": "available",
        "taskTimeoutSeconds": 1200,
        "maxOutputDurationSeconds": 10,
        "quantityField": "duration_seconds",
        "pricing": [
          { "variant": "generate_audio=false;resolution=720p", "unit": "per_second", "price": "0.05", "currency": "USD" },
          { "variant": "generate_audio=true;resolution=720p", "unit": "per_second", "price": "0.08", "currency": "USD" }
        ],
        "startingPrice": { "variant": "generate_audio=false;resolution=720p", "unit": "per_second", "price": "0.05", "currency": "USD" },
        "badges": ["audio_output"],
        "relatedModels": [],
        "version": "v1",
        "updatedAt": "2026-09-16T16:47:57Z"
      }
    ]
  },
  "request_id": "req_01k3m8x9q2z4v7n5p6r8s0t1w2"
}

Die Preise oben dienen als Beispiel. inputSchema und examples erscheinen in Listeneinträgen nur auf Anforderung.

Für Clients relevante Felder

FeldZweck
modelExakter Wert für createTask.model im Format publisher/model/task
familyStabile Produktfamilienkennung zur Gruppierung verwandter Endpunkte
displayNameLesbarer Name dieses Endpunkts
providerModellhersteller, etwa das entwickelnde Labor
modality / tasksKatalogmedium des Endpunkts und ausgeführte Aufgabe. modality steuert Auswahl und modality-Filter, garantiert aber keinen Dateityp: Ein speech-to-text-Endpunkt gehört zu audio und antwortet mit Text. Siehe Ausgabestruktur
toolkitWerkzeugfamilie dieses Endpunkts, aktuell nur subject-swap. Fehlt, wenn kein Toolkit zugeordnet ist; prüfen Sie den Wert statt den Schlüssel. Wie badges ist dies eine Klassifikation ohne Einfluss auf Annahme, Preis oder Validierung. Siehe Motivtausch
asynctrue: Task erstellen und per Polling oder Webhook abholen. false: Antwort kommt direkt zurück
inputSchemaJSON Schema 2020-12 für Formularerzeugung und Anfragevalidierung
examplesGegen aktuelles Schema validierte Eingaben; in der Liste nur auf Anforderung
enabledOb der Eintrag aktuell aufrufbar ist. Noch nicht geöffnete veröffentlichte und von der Plattform pausierte Einträge erscheinen ebenfalls, mit false. Vor Einreichung zusammen mit available prüfen
availableOb das Modell aktuell aufrufbar ist. false bedeutet scheiternden Aufruf, etwa ohne aktuellen Preis
availabilityAngegebene Phase: planned, available, preview (Felder und Ausgaben können sich ändern) oder maintenance (vorübergehend gestört, Rückkehr erwartet)
pricing / startingPriceIhre Preise; siehe Preise lesen
quantityFieldEingabefeld für abrechenbare Menge, bei Video häufig duration_seconds. Leer bedeutet eine Einheit je Aufruf. Immer aus Katalog lesen
taskTimeoutSecondsAusführungsfrist der Plattform je Task, keine Medienlänge
maxOutputDurationSecondsMaximale Ausgabelänge aus maximum der Eigenschaft duration_seconds; fehlt ohne definiertes Maximum
badgesFähigkeits- und Lizenzkennzeichen wie commercial_use oder no_watermark. Unbekannte Werte ignorieren
relatedModelsAusgewählte Alternativen oder nächste Schritte als aufrufbare Modell-IDs
version / updatedAtÄnderungsverfolgung; durch Vergleich erkennen, ob spätere Abfrage verändert wurde

mature und policyTier sind Informationskennzeichen. Sie entscheiden nicht über die Annahme einer Anfrage.

Preise lesen

Jeder Eintrag in pricing ist eine Preisstufe:

FeldBedeutung
unitper_image, per_second der Ausgabemedien, per_request oder per_1k_tokens
priceIhr Preis je Einheit in US-Dollar als Dezimalstring. Kontokonditionen sind enthalten und können sich zwischen Konten unterscheiden
variantEinstellungen zur Stufenwahl. Leer bei nur einem Preis; reiner Wert wie 720p, wenn ein Feld entscheidet; mit ; verbundene, nach Feldname sortierte field=value-Paare bei mehreren Feldern, etwa generate_audio=false;resolution=480p
currencyImmer USD
regularPrice, offerLabel, offerPercent, offerEndsAtNur bei aktivem Kundenangebot: vorheriger Preis, Angebotsname, Prozentsatz und Ende

startingPrice ist der günstigste Eintrag, nicht der Preis Ihrer Einstellungen. Stufenwählende Felder stehen, sofern vorhanden, unter inputSchema["x-pricing"].variantFields; sonst sind es mit x-ui.affects_price: true markierte Felder, außer quantityField. Weggelassene Felder verwenden ihr Schema-default.

  • Medienmodelle: Kosten sind price × quantity; Menge ist der Wert von quantityField in Ihrer Eingabe, bei leerem quantityField eine Einheit. Manche Endpunkte berechnen danach jede weitere Eingabe separat, meist je Referenzbild. Das ist ein echter Rechnungsbestandteil, keine Rundungsabweichung: Bei einem Bearbeitungsendpunkt mit Referenzarray kann dessen Füllung den Betrag vervielfachen, obwohl unit, quantity, variant und Stufen-price unverändert wie bei einem Bild bleiben. Die Rechnung oben unterschätzt dann ohne sichtbaren Hinweis. Maschinenlesbar ist dies ein Feld mit x-ui.affects_price: true, das weder quantityField noch in x-pricing.variantFields ist: Es verändert den Betrag ohne Stufenwahl. Lesen Sie pricing bei solchen Endpunkten als Untergrenze und verwenden den Betrag einer Preisabfrage.
  • Textmodelle (per_1k_tokens): Eine Zahl beschreibt die Belastung nicht. price ist nur der Ausgabetokenpreis je 1000 Tokens. Eingabe und gecachte Eingabe haben eigene, meist niedrigere Preise und werden nach gemessenem Verbrauch je Aufruf berechnet. Multiplizieren Sie price nicht mit Ihrer Gesamttokenzahl. Preise je Million Tokens für Eingabe, Cacheeingabe und Ausgabe stehen auf der Modellseite und im öffentlichen Katalog unter price.perMillionTokens.

Für den Betrag einer exakten nativen API-Anfrage vor Bezahlung verwenden Sie POST /api/v1/jobs/quote. Endgültige Kosten stehen im Taskdatensatz, cost mit settled: true, und unter Abrechnung.

Katalog zwischenspeichern

  • Die Katalogantwort darf bis 60 Sekunden zwischengespeichert werden (Cache-Control: private, max-age=60). Verwenden Sie ausschließlich einen privaten Cache je Konto: Preise sind kontospezifisch und gehören nie in geteilten oder öffentlichen CDN-Cache.
  • Lesen Sie ihn nicht vor jedem Task erneut. Katalogabfragen nutzen das Lesekontingent des Kontos unabhängig von der Task-Einreichung. Eine Abfrage vor jedem Aufruf verschwendet weiterhin Lesekapazität. Siehe Ratenbegrenzungen.
  • Aktualisieren Sie zeitgesteuert, etwa alle paar Minuten, nach einem 400-Validierungsfehler und nach abgelehnter Einreichung für dieses Modell.
  • Bewahren Sie version und updatedAt des verwendeten Eintrags zur späteren Änderungsprüfung.
  • Liefern Sie niemals eine fest codierte Schemakopie aus und verwenden keine statische Seite als Ersatz für einen Livekatalog ohne aufrufbaren Eintrag.

Gemeinsame Schema- und Playground-Regeln

inputSchema verwendet JSON Schema 2020-12. Standardkeywords steuern Servervalidierung; das x-ui-Objekt einer Eigenschaft beschreibt nur Playground-Reihenfolge, Darstellung und Hinweise zur Preisaktualisierung. Clients müssen unbekannte Darstellungserweiterungen ignorieren. Sie ersetzen nie required, Enums, Grenzen oder Bedingungen. Siehe den vollständigen Spicy-Schema-Vertrag.

Eigene Parametertabellen je Modell darstellen

Diese Website liefert keine Parametertabelle je Modell. Modelle und Felder ändern sich wöchentlich, statische Kopien veralten, und ein alter Parameter verursacht 400 oder falschen Preis. Parameter haben genau eine Quelle: inputSchema des Katalogs. Playground stellt dasselbe Dokument dar und das SDK validiert dagegen.

Was jeder Schemateil in der Tabelle wird

SchemaParametertabelle
Schlüssel von propertiesParametername; Feldnamen sind modellübergreifend einheitlich: eine Bedeutung, ein Name
Mitgliedschaft in requiredErforderlich oder optional
anyOf / allOfBedingt erforderlich. anyOf: mindestens eines angeben. allOf mit if → then: Bei A muss B mitgeliefert werden
typeTyp
descriptionHilfetext in englischer Prosa, unverändert anzeigbar; kein eigener Text nötig
enumAkzeptierte Werte; bei vorhandenem x-ui.enum_labels lesbare Beschriftungen verwenden
minimum / maximumAkzeptierter Bereich; x-ui.step bestimmt Schrittweite und x-ui.unit Suffix wie s oder px
minItems / maxItemsAnzahl akzeptierter Arrayeinträge. Ohne diese Angaben erfährt der Leser die Grenze nicht
itemsStruktur eines Arrayeintrags. Bei items.type gleich object ist das Teilschema ein vollständiges Objektschema: required, additionalProperties sowie type, description, Bereich und default jedes Unterfelds lesen und als verschachtelte Tabelle statt Freitextfeld darstellen
defaultBei weggelassenem Feld angewendeter Standard
x-ui.orderSortierschlüssel, absteigend. Nicht nach Schlüsselreihenfolge von properties sortieren; JSON-Objektreihenfolge ist kein Vertragsbestandteil
x-ui.primaryAls Haupteingabe oben fixieren
x-ui.advancedIn einklappbarem erweiterten Abschnitt darstellbar
x-ui.affects_priceAls preisbeeinflussend markieren; Änderung verlangt neue Preisabfrage
x-ui.widgetBedienelement für bearbeitbares Formular, dreizehn Werte, siehe Spicy Schema

Bedingungen stehen nur an der Wurzel von inputSchema in zwei Formen: anyOf mit nur required je Zweig für mindestens eine Eingabe und allOf mit if → then für A erfordert B. Leiten Sie diese nicht aus der Familie ab und erwarten keine oneOf, not oder dependentSchemas. Neue Endpunkte folgen kanonischen Feldern von Spicy Schema; ältere folgen ihrem Liveschema.

Schema abrufen

const modelId = 'MODEL_ID_FROM_CATALOG'; // the exact `model` value from GET /api/v1/models
const res = await fetch(`https://api.spicyapi.ai/api/v1/models/${modelId}`, {
  headers: { Authorization: `Bearer ${process.env.SPICY_API_KEY}` },
});
const { data } = await res.json();
const schema = data.inputSchema;

const rows = Object.entries(schema.properties)
  .sort(([, a], [, b]) => (b['x-ui']?.order ?? 0) - (a['x-ui']?.order ?? 0))
  .map(([name, prop]) => ({
    name,
    required: (schema.required ?? []).includes(name),
    type: prop.type,
    description: prop.description,
    values: prop.enum
      ? prop.enum.map((v) => prop['x-ui']?.enum_labels?.[v] ?? v)
      : prop.minimum !== undefined || prop.maximum !== undefined
        ? [`${prop.minimum ?? ''}–${prop.maximum ?? ''}${prop['x-ui']?.unit ?? ''}`]
        : [],
    default: prop.default,
    affectsPrice: prop['x-ui']?.affects_price === true,
    advanced: prop['x-ui']?.advanced === true,
  }));

Die Skizze endet bewusst bei skalaren Werten: Für Arrays bleibt values leer, weil Anforderungen unter items, minItems und maxItems statt in enum oder einem Bereich stehen. Erweitern Sie sie vor Auslieferung. Ein bloßes array ohne Eintragsstruktur und Längenlimit ist für Leser nicht nutzbar.

Der Einzelmodelldatensatz liefert auch examples. Jedes ist eine vollständige bereits serverseitig gegen das aktuelle Schema validierte Eingabe. Es eignet sich als minimales ausführbares Dokumentationsbeispiel und unverändert einreichbarer Anfrageinhalt. Das ist sicherer als manuelle Erstellung, deren Beispiel nach Schemaänderung veraltet, während examples aktuell bleibt.

Derselbe Code funktioniert durch Änderung von modelId für jedes Modell und veraltet nicht durch neue Modelle. Für den gesamten Katalog iterieren Sie über items aus GET /api/v1/models?includeSchema=1 und speichern wie unter Katalog zwischenspeichern beschrieben zwischen.

Längere Hilfe als description

description ist ein für Formularbeschriftungen dimensionierter Satz. Benötigt ein Parameter mehr, führt der öffentliche Katalog eine zusätzliche Notiz je Parameter:

curl "https://api.spicyapi.ai/console/v1/catalog/models/MODEL_ID_FROM_CATALOG?locale=en"

Der Einzelmodelldatensatz gibt paramNotes als Objekt mit Parameternamen als Schlüssel zurück, über locale in einer der zehn Dokumentationssprachen. Dort stehen Informationen, die nicht in eine Beschriftung passen: Bezugsgröße eines Werts, merklich verlangsamende Einstellung und schemaseitig akzeptierte Eingaben mit dennoch enttäuschendem Ergebnis. Bei einem Feld für eine selbst gehostete Datei erklärt oft nur diese Notiz, ob und wann sie abgerufen wird und was bei Unbrauchbarkeit passiert.

Zwei Grenzen: paramNotes gehört zum öffentlichen Katalog ohne Key, nicht zu authentifiziertem GET /api/v1/models. Lesen Sie es separat und speichern neben dem Schema zwischen. Außerdem ist es Prosa, nie eine Regel: Nur inputSchema bestimmt die Annahme einer Anfrage.

Auf dieser Seite