aisplice

API-Referenz

Doppelbelastung vermeiden

Idempotenz bedeutet, dass eine wiederholte Anfrage nur einmal ausgeführt wird: Senden Sie bei der Wiederholung denselben Idempotency-Key, dann wird Ihnen nur einmal etwas berechnet, auch wenn der erste Versuch nur verloren schien.

Eine Anfrage mit Timeout ist keine fehlgeschlagene Anfrage. Die Generierung läuft womöglich schon, und eine blinde Wiederholung startet — und berechnet — eine zweite. Senden Sie einen Idempotency-Key, dann führt das Gateway die Anfrage einmal aus und liefert 24 Stunden lang dieselbe Antwort erneut.

#Wann Sie einen Schlüssel senden sollten

Senden

  • Jede asynchrone Einreichung — Video, Bild-Task, Musik, 3D. Das sind die teuren.
  • Jeder Aufruf ohne Streaming, den Ihr Worker automatisch wiederholt.
  • Aufrufe hinter einer Queue, die einen Job nach einem Absturz erneut zustellen kann.

Weglassen

  • Streaming-Anfragen — der Header wird mit 400 abgelehnt, ein Stream lässt sich nicht erneut ausliefern.
  • GET-Abfragen und Metadaten-Lesezugriffe — sie zu wiederholen ist ohnehin kostenlos und sicher.
  • Interaktiver Chat, bei dem eine doppelte Antwort weniger kostet als die Buchführung.
submit.sh
curl https://www.aisplice.store/v1/videos \
  -H "Authorization: Bearer sk-YOUR_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
    "model": "doubao-seedance-2.5",
    "prompt": "A drone shot of a lighthouse at dawn"
  }'

Leiten Sie den Schlüssel aus Ihrem eigenen Datensatz ab

Eine UUID, die innerhalb der Wiederholungsschleife erzeugt wird, verfehlt den Zweck — jeder Versuch bekommt eine neue Identität. Leiten Sie sie aus dem Geschäftsdatensatz ab, den Sie bearbeiten (Bestell-ID, Job-ID), damit jede Wiederholung dieses Jobs denselben Schlüssel trägt.

#Wie Schlüssel abgeglichen werden

Opt-in, nie automatisch

Ohne den Header ändert sich nichts. Eine Wiederholung ohne Schlüssel ist eine zweite kostenpflichtige Anfrage.

Nur schreibende Methoden

GET, HEAD und OPTIONS ignorieren den Header — das Abfragen eines Tasks lässt sich ohnehin gefahrlos wiederholen.

Gilt pro Nutzer + Schlüssel + Methode + Route

Derselbe Wert unter einem anderen API-Schlüssel oder an einem anderen Endpunkt ist eine andere Operation.

Der Body gehört zur Identität

Pfad, Query und Body werden gemeinsam gehasht. Wird ein Schlüssel mit geändertem Payload wiederverwendet, kommt 409 zurück — nichts wird überschrieben.

Nicht mit Streaming kompatibel

Eine gestreamte Antwort lässt sich nicht für eine Wiederholung speichern, daher wird stream:true zusammen mit einem Schlüssel mit 400 abgelehnt.

Blockiert im Zweifel

Ist das Register nicht verfügbar, wird die Anfrage mit 503 abgelehnt, statt ungeschützt ausgeführt zu werden.

Schlüssel haben höchstens 255 Zeichen. Längere werden mit 400 abgelehnt, bevor die Anfrage ausgeführt wird.

#Ergebnisse und Statuscodes

Eine erneut ausgelieferte Antwort enthält X-Idempotent-Replayed: true und den ursprünglichen Status — behandeln Sie sie als die Antwort, nicht als abzugleichendes Duplikat. Jede Ablehnung nutzt die flache Struktur der Vorprüfungen.

HTTPCodeBedeutungWas tun
400IDEMPOTENCY_STREAM_UNSUPPORTEDIdempotency-Key wurde bei einer Streaming-Anfrage gesendet.Lassen Sie den Header bei Streaming-Aufrufen weg, oder setzen Sie stream:false, wenn Sie Replay-Schutz brauchen.
400IDEMPOTENCY_BODY_UNREADABLEDer Body konnte für das Idempotenz-Register nicht gehasht werden.Senden Sie einen normalen JSON- oder Multipart-Body — Chunked-Bodys, die sich nicht puffern lassen, werden abgelehnt.
409IDEMPOTENCY_PAYLOAD_CONFLICTDieser Schlüssel wurde bereits mit einem anderen Body, Pfad oder Query verwendet.Erzeugen Sie einen neuen Schlüssel. Ein Schlüssel kennzeichnet genau eine Anfrage, nicht eine ganze Wiederholungsschleife.
409IDEMPOTENCY_IN_PROGRESSDie erste Anfrage mit diesem Schlüssel läuft noch.Warten Sie Retry-After (2 s) ab und versuchen Sie es mit demselben Schlüssel erneut — Sie erhalten die ursprüngliche Antwort.
409IDEMPOTENCY_RESULT_UNREPLAYABLEDie ursprüngliche Anfrage ist abgeschlossen, ihre Antwort wurde jedoch versiegelt und kann nicht erneut ausgeliefert werden.Nicht blind erneut senden. Gleichen Sie zuerst über den Task-Endpunkt oder Ihre eigenen Aufzeichnungen ab.
503IDEMPOTENCY_UNAVAILABLEDas Idempotenz-Register ist nicht verfügbar, daher blockiert die Prüfung lieber, statt eine doppelte Belastung zu riskieren.Mit Backoff erneut versuchen — die Anfrage wurde nicht ausgeführt.

#Wiederholungsschleife

Ein Schlüssel pro Job, bei jedem Versuch wiederverwendet, wobei 409 in-progress als „warten“ behandelt wird, nicht als „fehlgeschlagen“.

submit_once.py
import time, uuid, requests

def submit_once(job_id: str, body: dict, api_key: str, tries: int = 5):
    # Same key for every attempt of this job — that is what makes it safe.
    key = str(uuid.uuid5(uuid.NAMESPACE_URL, f"video-job:{job_id}"))

    for attempt in range(tries):
        response = requests.post(
            f"https://www.aisplice.store/v1/videos",
            headers={
                "Authorization": f"Bearer {api_key}",
                "Idempotency-Key": key,
            },
            json=body,
            timeout=60,
        )

        if response.status_code == 409:
            code = response.json().get("code", "")
            if code == "IDEMPOTENCY_IN_PROGRESS":
                time.sleep(int(response.headers.get("Retry-After", 2)))
                continue
            # PAYLOAD_CONFLICT or RESULT_UNREPLAYABLE: a human decision,
            # never a silent resubmit.
            raise RuntimeError(response.text)

        if response.status_code >= 500:
            time.sleep(2 ** attempt)
            continue

        response.raise_for_status()
        replayed = response.headers.get("X-Idempotent-Replayed") == "true"
        return response.json(), replayed

    raise TimeoutError(f"submit for {job_id} did not settle")

Speichern Sie die Task-ID, bevor Sie irgendetwas wiederholen

Schreiben Sie task_id in derselben Transaktion in Ihre Datenbank, in der Sie den Job als eingereicht markieren. Der Schlüssel schützt das Einreichen; geht die Antwort verloren, schützt Sie nur Ihr eigener Datensatz.

Lebenszyklus asynchroner Tasks →

Immer noch nicht gelöst?

Senden Sie uns die Anfrage-ID oder die Fehlermeldung, und wir sehen uns das an.