# Hinzufügen und Aktualisieren von Gast-Daten (push)

**Swagger-Referenz:** [Operation und Antwortschema öffnen](https://gwatch.events/ext-api#//post_ext_api_push).

## Worum es geht

Mit `push` übertragen Sie bis zu **100 Gast-Datensätze pro Anfrage**. Das Portal legt neue Gäste an oder aktualisiert bestehende Gäste anhand von `GUEST_TICKET_CODE`.

**Dieser Aufruf verändert Daten.** Prüfen Sie Hauptschlüssel und Veranstaltungsnamen zunächst über `metadata` und beginnen Sie mit abgestimmten Testdaten.

## Aufruf und Header

Speichern Sie den JSON-Body in einer lokalen Datei `push.json`. Senden Sie ihn beispielsweise so:

```bash
curl --request POST 'https://gwatch.events/ext-api/push' \
  --header 'x-api-key: IHR_HAUPTSCHLUESSEL' \
  --header 'x-api-push: IHR_IMPORTSCHLUESSEL' \
  --header 'Accept: application/json' \
  --header 'Content-Type: application/json' \
  --data-binary '@push.json'

```

Swagger weist für `push` sowohl `x-api-key` als auch `x-api-push` als erforderlich aus. Fordern Sie beide Schlüssel für die Anbindung an. Ein Flavor-Schlüssel wird bei `push` nicht verwendet.

Für Imports muss die Administration einen Import-Schlüssel für die Veranstaltung vergeben. Übertragen Sie diesen im Header `x-api-push`. Ohne eingerichteten Import-Schlüssel sowie bei fehlendem, leerem oder falschem Schlüssel wird der Import mit HTTP `401` abgewiesen.

## Aufbau der Anfrage

<table id="bkmrk-feld-vorgabe-meta.fa" style="width:100%;"><thead><tr><th style="width:18.711%;">Feld</th><th style="width:81.2691%;">Vorgabe</th></tr></thead><tbody><tr><td style="width:18.711%;">`meta.failIfExists`</td><td style="width:81.2691%;">Erforderlicher Boolean: `true` weist vorhandene Ticketcodes ab; `false` erlaubt Aktualisierungen.</td></tr><tr><td style="width:18.711%;">`meta.insertAs`</td><td style="width:81.2691%;">Erforderliche Ganzzahl: `1` für bereits bestätigte neue Gäste, `2` für neue Gäste mit ausstehender Bestätigung. Wird nur bei Neuanlage berücksichtigt.</td></tr><tr><td style="width:18.711%;">`guests`</td><td style="width:81.2691%;">Array mit `1` bis `100` Gastobjekten. Jedes Objekt verwendet Schlüssel aus `metadata.guest`.</td></tr></tbody></table>

Vollständiges Beispiel für `push.json` aus dem Swagger-Modell `pushBody`:

```json
{
  "meta": {
    "failIfExists": false,
    "insertAs": 2
  },
  "guests": [
    {
      "GUEST_TICKET_CODE": "ABC123",
      "GUEST_FIRST_NAME": "Max",
      "GUEST_LAST_NAME": "Mustermann",
      "GUEST_EMAIL": "max@example.com",
      "gates": [
        1,
        3
      ]
    },
    {
      "GUEST_FIRST_NAME": "Simone",
      "GUEST_LAST_NAME": "Pfeifer",
      "GUEST_EMAIL": "simone@example.com"
    }
  ]
}

```

Die benutzerdefinierten Namens- und E-Mail-Felder sowie die Gate-IDs `1` und `3` sind Beispiele. Sie müssen in Ihren [Metadaten](https://doc.gwatch.events/books/externes-api/page/abruf-der-metadaten-metadata) vorkommen. Wenn keine Gate-Zuordnung geändert werden soll, lassen Sie `gates` weg.

**Feldnamen aus den Metadaten übernehmen:** In der geprüften Testveranstaltung heißen die Namensfelder beispielsweise `GUEST_VORNAME` und `GUEST_NACHNAME`, während das Swagger-Beispiel `GUEST_FIRST_NAME` und `GUEST_LAST_NAME` verwendet. Diese Namen sind nicht automatisch austauschbar. Maßgeblich ist die `key`-Angabe Ihrer tatsächlichen `metadata`-Antwort.

## Neuanlage oder Aktualisierung?

<table id="bkmrk-situation-verarbeitu"><thead><tr><th>Situation</th><th>Verarbeitung</th></tr></thead><tbody><tr><td>Ticketcode fehlt</td><td>Das Portal erzeugt einen neuen Code und legt einen Gast an.</td></tr><tr><td>Ticketcode vorhanden, aber kein bestehender Gast mit diesem Code gefunden</td><td>Ein neuer Gast wird mit diesem Code angelegt, sofern die Validierung erfolgreich ist.</td></tr><tr><td>Ticketcode gefunden und `failIfExists=false`</td><td>Der vorhandene Gast wird aktualisiert.</td></tr><tr><td>Ticketcode gefunden und `failIfExists=true`</td><td>Der Datensatz schlägt fehl; es wird kein zweiter Gast mit diesem Code angelegt.</td></tr></tbody></table>

Die Zuordnung erfolgt über den Ticketcode innerhalb der Veranstaltung, nicht über E-Mail-Adresse, Name oder die Datenbank-ID. Übermitteln Sie den Ticketcode als Zeichenfolge. Er muss den Restriktionen aus `metadata` entsprechen.

Bei einem Update werden die gesendeten Felder verarbeitet. **Weglassen und `null` sind nicht dasselbe:** Weggelassene Felder werden nicht gezielt überschrieben; ein ausdrücklich übergebenes `null` kann bei zulässigen Feldern einen Wert leeren. Bei `nullable=false` ist `null` ungültig. Prüfen Sie beabsichtigtes Leeren je Feldtyp zunächst mit Testdaten.

`insertAs` setzt keinen bestehenden Gast nachträglich auf einen anderen Teilnahmestatus. Dafür ist dieser Parameter nicht vorgesehen.

## Gate-Zuordnungen bewusst ersetzen

<table id="bkmrk-inhalt-im-gastobjekt"><thead><tr><th>Inhalt im Gastobjekt</th><th>Wirkung nach erfolgreicher Gastverarbeitung</th></tr></thead><tbody><tr><td>Kein `gates`-Schlüssel</td><td>Vorhandene Zuordnungen bleiben erhalten.</td></tr><tr><td>`"gates": [6398, 6399]`</td><td>Die Auswahl wird durch diese IDs ersetzt. Bereits zugeordnete Gates, die fehlen, werden entfernt.</td></tr><tr><td>`"gates": []`</td><td>Alle vorhandenen Gate-Zuordnungen werden entfernt.</td></tr></tbody></table>

Verwenden Sie ausschließlich freigegebene Gate-IDs aus `metadata.gates`. Wenn dort keine Gates verfügbar sind, lassen Sie den Schlüssel weg; im aktuellen API-Verhalten ist er dann kein freigegebenes Eingabefeld.

**Die Ersetzung betrifft auch vorhandene Zuordnungen, die in Ihrer übermittelten Auswahl nicht vorkommen.** Sie ist kein reines Hinzufügen. Soll nur ein Gate ergänzt werden, muss die vollständige gewünschte Auswahl abgestimmt sein. Eine Gate-Zuordnung über `push` ist kein Ein- oder Ausgangsscan.

## Antwort und Einzelergebnisse

Bei verarbeiteten Anfragen enthält die Antwort `summary` und `results`, ohne zusätzliches oberstes `error`-Feld.

<table id="bkmrk-feld-bedeutung-summa"><thead><tr><th>Feld</th><th>Bedeutung</th></tr></thead><tbody><tr><td>`summary.total`</td><td>Zahl der übergebenen Gastobjekte.</td></tr><tr><td>`summary.created`</td><td>Zahl erfolgreich neu angelegter Gäste.</td></tr><tr><td>`summary.updated`</td><td>Zahl erfolgreich aktualisierter Gäste.</td></tr><tr><td>`summary.failed`</td><td>Zahl fehlgeschlagener Gastobjekte.</td></tr><tr><td>`results[].index`</td><td>Position in Ihrem Eingabearray, beginnend bei `0`.</td></tr><tr><td>`results[].status`</td><td>`created`, `updated` oder `failed`.</td></tr><tr><td>`results[].ticketCode` / `id`</td><td>Zugeordneter Ticketcode und Gast-ID; bei Fehlern gegebenenfalls `null`.</td></tr><tr><td>`results[].message`</td><td>Bei Erfolg `null`, bei Fehlern eine Zeichenfolge oder ein Objekt mit Feldmeldungen.</td></tr></tbody></table>

Beispiel einer erfolgreichen Verarbeitung mit HTTP 200 aus dem Swagger-Modell `pushSuccess` (eigenständiges Antwortbeispiel, keine Zuordnung zum obigen Request):

```json
{
  "summary": {
    "total": 2,
    "created": 1,
    "updated": 1,
    "failed": 0
  },
  "results": [
    {
      "index": 0,
      "ticketCode": "223344",
      "id": 3247987,
      "status": "updated",
      "message": null
    },
    {
      "index": 1,
      "ticketCode": "223323",
      "id": 2343234,
      "status": "created",
      "message": null
    }
  ]
}

```

### HTTP 207: Ergebnisse einzeln behandeln

Sobald mindestens ein Datensatz fehlschlägt, lautet der HTTP-Status **207**, auch wenn alle Datensätze fehlschlagen. Erfolgreiche Datensätze werden dadurch nicht insgesamt zurückgerollt.

Beispiel einer Anfrage mit einem erfolgreichen Update und einem nicht freigegebenen Eingabeschlüssel:

```json
{
  "summary": {"total": 2, "created": 0, "updated": 1, "failed": 1},
  "results": [
    {"index": 0, "ticketCode": "TEST0001", "id": 12345, "status": "updated", "message": null},
    {"index": 1, "ticketCode": null, "id": null, "status": "failed", "message": "The following keys are not available: TICKET_CODE"}
  ]
}

```

`TICKET_CODE` ist kein Ersatz für `GUEST_TICKET_CODE`. Nutzen Sie `index`, um Fehler eindeutig dem gesendeten Datensatz zuzuordnen; bei einem Fehler muss `ticketCode` nicht den ursprünglich übergebenen Wert enthalten.

### HTTP 422: Anfrage korrigieren

Fehlende Steuerparameter, ein unzulässiges `insertAs`, eine leere Gästeliste oder mehr als 100 Datensätze führen zur Ablehnung der äußeren Anfrage. Beispiel:

```json
{
  "error": true,
  "message": {"meta.insertAs": ["The value may not be greater than 2."]}
}

```

Der Meldungstext ist beispielhaft. Verwenden Sie Feldschlüssel und HTTP-Status für die Auswertung. Fehler innerhalb einzelner Gastobjekte werden dagegen in der Regel über `results` und HTTP 207 gemeldet. Senden Sie stets echte Gastobjekte; andere Array-Inhalte sind kein unterstütztes Eingabeformat.

## Wiederholungen und Teiländerungen

- Speichern Sie das Ergebnis einschließlich `index`, Ticketcode und ID.
- Wiederholen Sie eine fehlgeschlagene Anfrage ohne eigene Ticketcodes nicht blind: Bereits angelegte Gäste könnten erneut angelegt werden.
- Auch eine Fehlermeldung bei einem Update garantiert nicht, dass sämtliche Felder des Gastes unverändert geblieben sind. Die Speicherung vorhandener Gäste ist nicht als atomarer Gesamtvorgang abgesichert. Prüfen Sie den aktuellen Stand, bevor Sie korrigiert erneut senden.
- Korrigieren Sie fehlgeschlagene Datensätze gezielt. Ein Timeout auf Ihrer Seite beweist nicht, dass der Server nichts gespeichert hat.

## Häufige Fehler

<table id="bkmrk-problem-pr%C3%BCfung-http"><thead><tr><th>Problem</th><th>Prüfung</th></tr></thead><tbody><tr><td>HTTP 401</td><td>Hauptschlüssel, Archivstatus, allgemeinen IP-Filter und exakt passenden Import-Schlüssel prüfen.</td></tr><tr><td>Unbekannter Feldschlüssel</td><td>Aktuelle `metadata.guest` verwenden, nicht die frei vereinbarten Lesefelder.</td></tr><tr><td>Listenwert abgewiesen</td><td>`items[].key` senden, nicht `value` oder `values`.</td></tr><tr><td>Bild wird abgewiesen</td><td>Gültige eingebettete Bild-Data-URI und freigegebenes Bildfeld prüfen.</td></tr><tr><td>Gate-ID ungültig</td><td>ID muss für diese Veranstaltung in `metadata.gates` vorkommen.</td></tr><tr><td>Bestehender Gast abgewiesen</td><td>`failIfExists` prüfen. Nur bei gewolltem Update auf `false` setzen.</td></tr><tr><td>Werte nach Update unerwartet leer</td><td>Gesendete `null`- oder Leerwerte prüfen. Unveränderte Felder weglassen.</td></tr><tr><td>Alte Gate-Zuordnungen fehlen</td><td>`gates` ersetzt die gesamte Auswahl. Vollständige gewünschte Zuordnung abstimmen.</td></tr></tbody></table>

## Vor dem produktiven Einsatz prüfen

1. Veranstaltung und Feldliste über `metadata` bestätigen.
2. Einen Testgast anlegen und zurückgegebenen Ticketcode speichern.
3. Denselben Gast mit `failIfExists=false` gezielt aktualisieren.
4. Fehlerfall mit `failIfExists=true` sowie Feldvalidierung prüfen.
5. Gate-Ersetzung nur mit abgestimmten Testzuordnungen testen.
6. Antwortauswertung für HTTP 200, 207, 401 und 422 vorsehen.

**Zurück:** [Einzelabruf](https://doc.gwatch.events/books/externes-api/page/abruf-von-daten-eines-einzelnen-gastes-fetch).  
**Zum Einstieg:** [Übersicht](https://doc.gwatch.events/books/externes-api/page/ubersicht).