> ## Documentation Index
> Fetch the complete documentation index at: https://docs.querying.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Idempotenz

> Einreichungen mit idempotencyKey deduplizieren. Einzel- und Batch-Endpunkt behandeln Duplikate unterschiedlich.

`idempotencyKey` ist ein optionaler, vom Aufrufer gelieferter String, der eine Einreichung deduplizierend macht.
Senden Sie denselben Schlüssel zweimal, wird die zweite Einreichung dem Task zugeordnet, den die erste erstellt hat,
statt neue Arbeit einzureihen.

```json theme={null}
{
  "taskType": "GEMINI",
  "idempotencyKey": "job-42:prompt-7:gemini",
  "payload": { "prompt": "best wireless earbuds 2026" }
}
```

Ohne ihn gibt es **keine Deduplizierung**: Jede Einreichung erzeugt einen neuen Task. Für einmalige Abfragen ist das
eine legitime Wahl, für alles, was ein Cronjob oder ein wiederholender Worker doppelt einreichen könnte, die falsche.

<Tip>
  Ein guter Schlüssel ergibt sich deterministisch aus der Arbeit selbst, nicht aus dem Versuch. Setzen Sie ihn aus den
  Kennungen der Arbeitseinheit zusammen, etwa `"{jobId}:{promptId}:{engine}"`, dann erzeugt eine Wiederholung ganz
  natürlich denselben Schlüssel.
</Tip>

## Einzel und Batch unterscheiden sich bewusst

Das ist die einzige Stelle, an der sich die beiden Endpunkte unterscheiden, und sie führt oft zu Fehlern.

<CodeGroup>
  ```json Single — duplicate is an error theme={null}
  POST /v1/async/task
  → 409 Conflict

  {
    "success": false,
    "error": {
      "code": "RESOURCE_ALREADY_EXISTS",
      "message": "Task already exists.",
      "timestamp": "2026-07-09T04:12:00.000Z"
    }
  }
  ```

  ```json Batch — duplicate is a success theme={null}
  POST /v1/async/task/batch
  → 200 OK

  {
    "success": true,
    "summary": { "total": 1, "succeeded": 1, "failed": 0 },
    "results": [
      {
        "success": true,
        "index": 0,
        "task": { "id": "8f2c1e40-...", "status": "QUEUED", "...": "..." }
      }
    ]
  }
  ```
</CodeGroup>

Der Einzel-Endpunkt behält die Semantik der expliziten Erstellung: Sie wollten einen Task erstellen, der Task
existiert bereits, das ist ein Konflikt, und Sie sollten davon erfahren.

Der Batch-Endpunkt **wertet Duplikate als Erfolg**. Sein Aufrufer ist typischerweise ein Worker, der nach einem
Neustart einen ganzen Job erneut einreicht. Einen Batch mit 500 Einträgen als fehlgeschlagen zu werten, weil ein
Schlüssel bereits in der Warteschlange war, würde den Sinn von Idempotenzschlüsseln zunichtemachen. Das
zurückgegebene `results[i].task` ist der *bestehende* Task, sodass Ihre Task-Zuordnung weiter aufgeht.

## Ergebnisse den Einreichungen zuordnen

Es gibt zwei unabhängige Anker, und Sie brauchen beide:

<ResponseField name="results[].index" type="integer">
  Entspricht positionsgenau 1:1 Ihrem Eingabe-Array. Damit ordnen Sie die Batch-Antwort den gesendeten Tasks zu.
</ResponseField>

<ResponseField name="task.idempotencyKey" type="string">
  Wird unverändert zurückgegeben. Damit ordnen Sie den *Webhook* zu, der Minuten später, ungeordnet und ohne Bezug
  auf Ihr ursprüngliches Array eintrifft.
</ResponseField>

<Note>
  Wenn Sie keinen `idempotencyKey` angegeben haben, wird das Feld im Task-Objekt **weggelassen** statt als `null`
  zurückgegeben. Intern nutzt der Task seine eigene uuid als Schlüssel, die per Konstruktion eindeutig ist und daher
  nie dedupliziert.
</Note>

## Lebensdauer von Schlüsseln

Schlüssel dauerhaft aufbewahrter Tasks bleiben nach Abschluss, Fehlschlag und dem 24-stündigen öffentlichen
Polling-Fenster reserviert. Ein 404 beim Polling gibt den Schlüssel nicht frei. Verwenden Sie für
Übertragungswiederholungen einer Einreichung denselben Schlüssel und für einen separaten Lauf einen neuen
Ausführungsschlüssel (zum Beispiel mit dem Suffix `:r1`). Ein UUID-Format ist nicht erforderlich. Datensätze, die vor
Aktivierung der dauerhaften Aufbewahrung bereits in die Altdaten verschoben wurden, reservieren nachträglich keine Schlüssel.
