spicyapiDokumentation
Anleitungen
Hauptinhalt

Personen austauschen

Ein Toolkit, zwei Formen. Modelle mit einem Aufruf tauschen Gesicht oder Kopf in einer einzigen Anfrage; Modelle mit zwei Aufrufen analysieren zuerst den Clip, damit Sie auswählen können, wer ausgetauscht wird.

Manche Modelle erzeugen keine neue Szene, sondern ersetzen eine Person: ein Gesicht, das von einem Foto auf ein anderes wandert, ein ganzer Kopf oder eine komplette Figur in einem Videoclip. Der Katalog fasst sie unter einem Label zusammen, toolkit: "subject-swap", und es gibt sie in zwei Formen — ein Aufruf oder zwei Aufrufe mit einer Entscheidung dazwischen.

Sonst ist nichts Besonderes an ihnen. Es sind gewöhnliche asynchrone Tasks, ihre Parameter stehen im jeweils eigenen inputSchema, und ihre Ergebnisse kommen in output.assets[] an.

toolkit verrät, dass ein Modell dazugehört

toolkit ist ein Klassifizierungslabel an einem Katalogeintrag und steht sowohl in der authentifizierten Antwort von GET /api/v1/models als auch im öffentlichen Katalog. Heute gibt es genau einen Wert, subject-swap, und bei Modellen ohne Toolkit fehlt das Feld ganz — prüfen Sie also auf den Wert, nie auf den Schlüssel.

Das Feld ist rein informativ. Es entscheidet weder darüber, welcher Schlüssel ein Modell aufrufen darf, noch wie eine Anfrage bepreist wird oder was das Modell annimmt. Behandeln Sie einen unbekannten Wert wie einen unbekannten Eintrag in badges: ignorieren Sie ihn.

curl -s "https://api.spicyapi.ai/api/v1/models?modality=video" \
  -H "Authorization: Bearer $SPICY_API_KEY" \
  | jq -r '.data.items[]
      | select(.toolkit == "subject-swap" and .enabled and .available)
      | [.model, (.tasks | join(",")), .family] | @tsv'

Jede Zeile ist ein aufrufbarer Endpunkt. Über den Rest dieser Seite entscheidet die Spalte tasks: Eine family mit einem video-analyze-Endpunkt ist eine family mit zwei Aufrufen, und ihr zugehöriger video-edit-Endpunkt lässt sich nicht allein aufrufen.

Welche Form liegt vor?

Ein AufrufZwei Aufrufe
EndpunkteEin einzelner Bearbeitungsendpunktvideo-analyze, dann video-edit, in derselben family
Wer ersetzt wirdWas das Modell findet. Die Anfrage hat kein Feld, das eine Person benenntDie Ziele, die Sie über ihre Position gewählt haben
Was Sie sendenZielbild oder Zielclip plus Ihr Referenzbild, in einer AnfrageIm ersten Aufruf den Clip; im zweiten die gewählten Positionen mit je eigenen Referenzbildern
Was Sie zahlenEinen TaskZwei Tasks, getrennt bepreist
Geeignet fürEin offensichtliches Motiv im BildMehrere Personen im Bild, oder wenn ein Fehlgriff teuer wird

Beide Formen sind async: true: Sie erstellen einen Task und holen das Ergebnis per Polling oder Webhook ab.

Ein Aufruf

Hier unterscheidet sich nichts von anderen Bearbeitungsmodellen. Lesen Sie das inputSchema des Endpunkts, füllen Sie es aus, erstellen Sie den Task:

const created = await fetch('https://api.spicyapi.ai/api/v1/jobs/createTask', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.SPICY_API_KEY}`,
    'Content-Type': 'application/json',
    'Idempotency-Key': 'order-8814-swap-1',
  },
  body: JSON.stringify({
    model: swap.model, // ein Eintrag aus der Katalogabfrage oben
    input: {
      image_url: 'spicy://f/fil_01k3m8x9q2z4v7n5p6r8s0t1w3',
      reference_image_url: 'spicy://f/fil_01k3m8xb2c3d4e5f6g7h8j9k0m',
    },
  }),
});

Die Feldnamen unterscheiden sich von Endpunkt zu Endpunkt: Manche nehmen einen prompt, einen seed oder ein Ausgabeformat, manche nichts außer den beiden Bildern. Maßgeblich ist allein das Schema; übernehmen Sie Feldnamen nicht von einem Endpunkt auf den nächsten. Referenzen können eine öffentliche HTTPS-URL sein, ein kleines Bild direkt als Base64 oder eine hochgeladene spicy://-URI; siehe Medien.

Zwei Aufrufe

Der erste Aufruf sieht sich Ihren Clip an und meldet, was er gefunden hat — als geordnete Folge von Vorschau-Standbildern. Sie entscheiden, welche davon ersetzt werden. Die eigentliche Arbeit macht der zweite Aufruf.

Ihr Clip ──▶ video-analyze ──▶ output.assets[0], [1], [2] …   (ein Standbild je Ziel)
                                          │
                Sie wählen die Positionen │ 0 und 2
                                          ▼
           video-edit (analysis_task_id + swap_targets) ──▶ der fertige Clip

Warum nicht in einem Aufruf? Weil ein einzelner Aufruf bei vier Personen im Bild raten müsste, wen Sie meinen — und ein falscher Tipp ergibt ein fertiges, abgerechnetes Video, in dem die falsche Person ersetzt wurde. Die Aufteilung macht die Wahl ausdrücklich und überprüfbar.

Den Clip analysieren

Senden Sie den Clip an den video-analyze-Endpunkt. Setzen Sie resolution ausdrücklich, sofern der Endpunkt das Feld hat — der zweite Aufruf muss mit demselben Wert laufen, wählen Sie hier also die Auflösung, die der fertige Clip haben soll. Auf diesen Endpunkten hängt der Preis der Analyse nicht davon ab.

const analysis = await createTask({
  model: analyze.model, // der Eintrag, dessen tasks "video-analyze" enthält
  input: {
    video_url: 'spicy://f/fil_01k3m8x9q2z4v7n5p6r8s0t1w3',
    resolution: '720p',
  },
});
const analysisTaskId = analysis.taskId;

Lesen, was gefunden wurde

Warten Sie wie gewohnt auf den Task. Eine erfolgreiche Analyse liefert ein Vorschau-Standbild je verfolgtem Ziel in output.assets[]:

{
  "state": "succeeded",
  "output": {
    "assets": [
      { "url": "https://…", "expiresAt": "2026-09-20T09:32:11Z", "mime": "image/jpeg" },
      { "url": "https://…", "expiresAt": "2026-09-20T09:32:11Z", "mime": "image/jpeg" }
    ]
  },
  "settled": true
}

Die Reihenfolge dieses Arrays ist der Vertrag. Der Index eines Eintrags ist der object_index, den Sie im zweiten Aufruf zurücksenden: Das erste Standbild ist 0, das zweite 1 und so weiter. Zeigen Sie die Standbilder der Person, die auswählt, oder ordnen Sie sie selbst zu — die zurückgesendeten Positionen stammen in jedem Fall aus genau diesem Array.

Eine Analyse, die nichts zum Verfolgen findet, endet nicht erfolgreich mit leerem Array: Sie endet als failed mit errorCode: "generation_failed", und die Reservierung wird vollständig freigegeben. Eine Analyse mit succeeded hat also immer mindestens ein Standbild, und Ihr Code muss nur noch eines entscheiden: welches.

Die gewählten Ziele austauschen

Senden Sie die Task-ID der Analyse und je ein swap_targets-Element pro Ziel, das ersetzt werden soll. Nicht genannte Ziele bleiben unangetastet.

const swapped = await createTask({
  model: edit.model, // der "video-edit"-Eintrag derselben family
  input: {
    analysis_task_id: analysisTaskId,
    resolution: '720p', // derselbe Wert, mit dem die Analyse lief
    swap_targets: [
      { object_index: 0, image_urls: ['spicy://f/fil_01k3m8xb2c3d4e5f6g7h8j9k0m'] },
    ],
  },
});

Das Ergebnis ist ein Clip in output.assets[], wie bei jedem anderen Video-Task.

Was der zweite Aufruf vor der Annahme prüft

Diese Prüfungen laufen beim Erstellen, eine abgelehnte Anfrage erzeugt also nichts und reserviert nichts.

RegelWarum
Die Analyse muss zu Ihrem Konto gehören und erfolgreich gewesen seinEine wartende oder fehlgeschlagene Analyse hat nichts, worauf sie verweisen könnte
Verwenden Sie für beide Aufrufe denselben API-SchlüsselEine Analyse lässt sich nur mit dem Schlüssel zurücklesen, der sie erstellt hat; mit jedem anderen sehen Sie die Standbilder gar nicht, aus denen Sie wählen
Jeder object_index muss im gültigen Bereich liegen und genau einmal vorkommenAußerhalb des Bereichs würde stillschweigend die falsche Person ersetzt, doppelt genannt dieselbe zweimal. Beides liefe durch und würde normal abgerechnet
Preiswirksame Felder wie resolution müssen zur Analyse passenWürden sie geerbt, bliebe verborgen, in welcher Preisstufe Sie abgerechnet werden
Der Quellclip muss derselbe seinLassen Sie video_url weg, wird der analysierte Clip verwendet; senden Sie es, muss es identisch sein
Die Analyse ist nach ihrem Ende 24 Stunden nutzbarDanach sind die Tracking-Daten dahinter fort, und oft auch der Quellclip

Setzen Sie `resolution` in beiden Aufrufen — oder lesen Sie den Standardwert genau

Weggelassene Felder erhalten den default-Wert aus dem Schema, bevor die beiden Anfragen verglichen werden. Eine Analyse im Standard und ein Austausch im Standard passen also zusammen — eine Analyse mit gesetztem Wert und ein Austausch ohne Angabe jedoch nicht, und diese Abweichung wird abgelehnt statt stillschweigend korrigiert. Wer den Wert in beiden Aufrufen ausdrücklich sendet, hat die Frage nicht.

Wenn der zweite Aufruf abgelehnt wird

Alle Fälle sind HTTP 400 mit dem Geschäftscode code: 400. msg ist einer der folgenden Werte:

msgWas passiert istWas zu tun ist
The referenced analysis task was not found.Kein solcher Task in diesem Konto, oder analysis_task_id ist keine Task-IDNehmen Sie die taskId aus Ihrer eigenen Analyse. Ein Task aus einem fremden Konto wird absichtlich genauso gemeldet
The referenced task belongs to a different model.Die ID zeigt auf einen anderen Task — oft auf den Austausch-Task selbst oder auf die Analyse einer anderen familyLassen Sie sie auf den video-analyze-Task derselben family zeigen
The referenced analysis did not complete successfully.Die Analyse läuft noch oder endete als failed / expiredWarten Sie sie ab oder starten Sie sie erneut
That analysis has no reusable result. Run the analysis step again.Die Analyse war erfolgreich, hat aber nichts hinterlassen, was der Austausch nutzen kannFühren Sie die Analyse mit demselben Clip erneut aus
That analysis result has expired. Run the analysis step again.Es sind mehr als 24 Stunden vergangenFühren Sie die Analyse erneut aus
"resolution" must match the analysis step.Die beiden Aufrufe widersprechen sich in einem preiswirksamen FeldSenden Sie den Wert der Analyse, oder starten Sie eine neue Analyse mit dem gewünschten Wert
"video_url" must match the analysis step.Sie haben einen anderen Clip gesendetSenden Sie dieselbe URI oder lassen Sie das Feld weg
That analysis found N target(s); "object_index" is out of range.Eine Position liegt jenseits dessen, was die Analyse geliefert hatPositionen beginnen bei null und enden bei assets.length - 1
"object_index" is listed more than once.Zwei Einträge benennen dasselbe ZielGeben Sie jedem Ziel einen Eintrag und legen Sie alle seine Referenzbilder in dessen image_urls

Was die beiden Aufrufe kosten

Analyse und Austausch sind zwei getrennte Tasks mit zwei getrennten Preisen, jeder für sich reserviert und abgerechnet. Ein abgelehnter zweiter Aufruf kostet nichts; eine erfolgreiche Analyse wird berechnet, auch wenn Sie danach auf den Austausch verzichten.

  • Die Analyse wird meist per_request bepreist — eine Abrechnung je Aufruf, gleich wie lang der Clip ist und wie viele Ziele sie findet.
  • Der Austausch wird meist per_second bepreist, in ganzen Blöcken, und die Länge kommt aus dem Clip statt aus einem Feld, das Sie setzen. Der vorab genannte Betrag gilt deshalb für den längsten Clip, den der Endpunkt annimmt: Der genannte Betrag ist der reservierte Betrag, die endgültige Abrechnung entsteht aus der aufgerundeten Dauer und übersteigt die Reservierung nie, und die Differenz kehrt beim Abrechnen in Ihr Guthaben zurück. Eine Reservierung, die größer ist als die spätere Abrechnung, ist hier zu erwarten. Lesen Sie Abrechnung, bevor Sie damit planen.

Lesen Sie beide Preise aus dem Katalog, statt sie anzunehmen, und holen Sie für jeden Aufruf eine Kostenschätzung ein, wenn es auf den genauen Betrag ankommt.

Nächste Schritte

Auf dieser Seite