API-Zugriff erhalten
- Last verified
- Last verified 30. Aug. 2026
KORONA Event stellt zwei versionierte GraphQL-Verträge bereit. Wählen Sie den Vertrag, bevor Sie Zugangsdaten anfordern oder Abfragen entwickeln.
API auswählen
| API | Verwendungszweck | Endpunkt | Authentifizierung |
|---|---|---|---|
| Booking v1 | Kundenseitige Angebotssuche, Warenkorb, Checkout, Kontakte und Zahlungsabsichten | /api/graphql/booking/v1 | Je nach Operation öffentliche Suche, Kunden-Token oder Anfrage-Token |
| Management v1 | Begrenzter Datensatzindex und Änderungsfeed für acht Event- und Katalogressourcen | /api/graphql/management/v1 | Eigene Management-API-Zugangsdaten mit events:read und/oder catalog:read |
| Legacy GraphQL | Bestehende Integrationen mit den Berechtigungen des verknüpften Backoffice-Nutzers | /graphql | Kontogebundener Nutzer-API-Schlüssel und X-Tenant-Domain |
Der bisherige Endpunkt /graphql bleibt für bestehende Integrationen unverändert. Neue Integrationen sollten einen versionierten Endpunkt verwenden.
Bevor Sie beginnen
Klären Sie:
- zu welchem Konto (Tenant) die Integration gehört
- ob Sie Buchungsabläufe oder eine Backoffice-Synchronisierung benötigen
- welche Management-Berechtigungsbereiche erforderlich sind
- ob ein Kontoinhaber oder Plattformadministrator den Legacy-API-Schlüssel für den Integrationsnutzer erstellen kann; eine Rolle mit der Berechtigung zur Nutzerverwaltung kann nur einen eigenen Schlüssel erstellen
- welches Anfragevolumen erwartet wird und wer die Zugangsdaten verantwortet
- dass Ihr Client Geheimnisse außerhalb von Quellcode und Browser-Speicher ablegt
- dass
curlundjqfür die folgenden Beispiele verfügbar sind
Management-Zugriff anfordern
Die Verwaltung von Management-Zugangsdaten erfolgt derzeit ausschließlich durch den Support. Es gibt keine kundenseitige Seite dafür. Bitten Sie den KORONA Event-Support, Metadaten aufzulisten oder eigene Management-v1-Zugangsdaten auszustellen, zu rotieren oder zu widerrufen. Geben Sie Konto, Integrationsname, Berechtigungsbereiche, Ablaufdatum und erwartetes Volumen an.
Das vollständige Token wird nur in der erfolgreichen Antwort auf die Ausstellung oder Rotation zurückgegeben und kann danach nicht erneut angezeigt werden. Der Support erfasst dieses einmalige Token und übermittelt es Ihnen über einen freigegebenen sicheren Kanal. Speichern Sie es unmittelbar nach Erhalt in Ihrem Secret Manager, stellen Sie es bereit und bestätigen Sie dem Support die erfolgreiche Bereitstellung. KORONA Event speichert nur einen Digest und kann ein verlorenes Geheimnis nicht wiederherstellen.
Bitten Sie den Support bei einem verlorenen oder offengelegten aktiven Geheimnis um Rotation. Wenn das vorherige Token sofort ungültig werden muss, bitten Sie den Support um Widerruf, statt die Übergangsfrist abzuwarten. Name und Berechtigungsbereiche bleiben bei einer Rotation erhalten. Das vorherige Token bleibt bis zum früheren Zeitpunkt aus seinem bisherigen Ablauf und einer Stunde nach der Rotation gültig. Nachdem Sie die Bereitstellung des Ersatzes bestätigt haben, widerruft der Support das vorherige Token umgehend. Für andere Berechtigungsbereiche lassen Sie einen Ersatz ausstellen, stellen ihn bereit, bestätigen die Bereitstellung und lassen die bisherigen Zugangsdaten anschließend vom Support widerrufen. Abgelaufene oder widerrufene Zugangsdaten können nicht rotiert werden und müssen ersetzt werden.
Management-Anfragen authentifizieren
Senden Sie das Token ausschließlich im Authorization-Header. Das Token bestimmt bereits das Konto; senden Sie keinen widersprüchlichen X-Tenant-Domain-Header.
export KORONA_EVENT_API_ORIGIN='https://<api-host>'
export KORONA_EVENT_MANAGEMENT_TOKEN='<token-aus-dem-secret-manager>'
curl -X POST "$KORONA_EVENT_API_ORIGIN/api/graphql/management/v1" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $KORONA_EVENT_MANAGEMENT_TOKEN" \
-d '{"query":"{ events(first: 10) { nodes { id number name updatedAt discardedAt tombstone } pageInfo { endCursor hasNextPage } } }"}'events, eventTemplates und admissions erfordern events:read. Die fünf Katalog-Abfragen erfordern catalog:read. Zugangsdaten laufen innerhalb eines Jahres ab. Ungültige, abgelaufene und widerrufene Tokens liefern dieselbe nicht autorisierte Antwort; prüfen Sie den Metadatenstatus.
Management v1 stellt für jeden unterstützten Datensatz ausschließlich id, name, number, updatedAt, discardedAt und tombstone bereit. Vollständige Event- oder Katalogobjekte, private verschachtelte Beziehungen, Kontakte, Bestellungen, Zahlungen und Tenant-Konfigurationen gehören nicht zu diesem Vertrag. Verwenden Sie ihn für einen lokalen Index oder zur Änderungserkennung. Stimmen Sie einen anderen unterstützten Integrationsweg ab, wenn diese sechs Felder nicht ausreichen.
Verwenden Sie das inklusive Argument updatedSince und den zurückgegebenen Cursor zur Synchronisierung. Eine Seite enthält höchstens 100 Datensätze und ist nach updatedAt und id sortiert. Verworfene Datensätze bleiben mit discardedAt und tombstone enthalten. Behandeln Sie jeden Datensatz als Upsert mit id als Schlüssel. Wenn ein überlappendes Zeitfenster dieselbe id mehrfach liefert, wenden Sie die Version mit dem größten updatedAt einschließlich ihres Tombstone-Status an. Verwenden Sie den opaken endCursor nur innerhalb des aktuellen Seitendurchlaufs, solange hasNextPage wahr ist. Nutzen Sie einen Cursor nicht als Prüfpunkt für einen späteren Durchlauf, sondern starten Sie diesen mit einer inklusiven updatedSince-Zeitmarke.
Kontogebundenen Legacy-API-Schlüssel verwenden
Verwenden Sie einen Legacy-API-Schlüssel nur für eine bestehende /graphql-Integration, die dieselben Berechtigungen wie ein Backoffice-Nutzer benötigt.
Nur Kontoinhaber und Plattformadministratoren können einen Schlüssel für einen anderen Nutzer erstellen. Niemand kann einen Schlüssel für einen Nutzer mit höheren Berechtigungen erstellen. Eine Rolle ohne Inhaberstatus kann mit der Berechtigung zur Nutzerverwaltung nur einen Schlüssel für sich selbst erstellen.
- Erstellen oder wählen Sie einen dedizierten Integrationsnutzer. Verwenden Sie kein persönliches Mitarbeiterkonto, damit die Integration Personalwechsel übersteht und nur die benötigten Berechtigungen erhält.
- Öffnen Sie im Backoffice Admin > Benutzer und wählen Sie den Integrationsnutzer aus.
- Wählen Sie unter API-Schlüssel die Option API-Schlüssel erstellen.
- Kopieren Sie den Schlüssel aus Neuer API-Schlüssel und speichern Sie ihn sofort in einem Secret Manager. Der vollständige Schlüssel wird nur einmal angezeigt; anschließend zeigt die Nutzerseite nur noch die letzten vier Zeichen an.
Senden Sie den Schlüssel als Authorization: Bearer <token> und die Konto- oder Shop-Domain im Header X-Tenant-Domain:
curl -X POST "https://<api-host>/graphql" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer <your-api-key>" \
-H "X-Tenant-Domain: <your-account-domain>" \
-d '{"query":"{ tenant { name } }"}'Der Schlüssel kann nur mit den Berechtigungen des Integrationsnutzers in dem Konto handeln, in dem er erstellt wurde. Erstellen Sie bei Verlust einen Ersatz und widerrufen Sie den alten Schlüssel. Einige ältere Schlüssel sind mit In allen Konten verfügbar, denen dieser Benutzer zugeordnet ist gekennzeichnet. Ersetzen Sie einen solchen Schlüssel vor dem Widerruf durch einen Schlüssel pro Konto, wenn die Integration weiterhin Zugriff auf mehrere Konten benötigt.
Booking v1 verwenden
Booking v1 behält den bestehenden Authentifizierungsablauf des Online-Shops bei. Der API-Ursprung ist umgebungsspezifisch; übernehmen Sie ihn aus Ihrer KORONA Event-Bereitstellung oder erfragen Sie ihn beim Support. Die Dokumentationswebsite ist nicht automatisch der API-Host. Die öffentliche Angebotssuche benötigt keine Kunden-Zugangsdaten, aber die Shop-Domain und Operationskennungen wie die POS-ID des Shops. Senden Sie nach Anmeldung oder Kontakterstellung das zurückgegebene authToken des Kontakts als Authorization: Bearer <token> für kontakt-authentifizierte Operationen. requestCreate gibt das accessToken der Anfrage zurück; übergeben Sie es bei Operationen, die Anfragezugriff erfordern, im Argument id oder requestId. Behandeln Sie es nicht wie Management-Zugangsdaten. Geschützte Shops und andere Shop-Regeln gelten weiterhin.
Verwenden Sie offers für die Angebotssuche in Booking v1. Die veraltete Abfrage offersUnion bleibt mit denselben Argumenten und Ergebnissen für bestehende Integrationen verfügbar.
export KORONA_EVENT_API_ORIGIN='https://<api-host>'
export KORONA_EVENT_SHOP_DOMAIN='<shop-domain>'
export KORONA_EVENT_SHOP_POS_ID='<shop-pos-id>'Ermitteln Sie zuerst ein Angebot, das für die angegebene Shop-POS-ID sichtbar ist:
DISCOVERY_RESPONSE="$(
curl -sS -X POST "$KORONA_EVENT_API_ORIGIN/api/graphql/booking/v1" \
-H "Content-Type: application/json" \
-H "X-Tenant-Domain: $KORONA_EVENT_SHOP_DOMAIN" \
--data "$(jq -n \
--arg query 'query DiscoverOffers($posId: ID!) { offers(posId: $posId, first: 1) { edges { node { __typename ... on Admission { id } ... on Event { id } ... on EventDesc { id } ... on EventTemplate { id } ... on Product { id } ... on VoucherConfiguration { id } } } } }' \
--arg posId "$KORONA_EVENT_SHOP_POS_ID" \
'{query: $query, variables: {posId: $posId}}')"
)"
printf '%s\n' "$DISCOVERY_RESPONSE" | jq .Eine erfolgreiche Suchantwort enthält die Angebots-ID und den GraphQL-Typ. Die genauen Werte hängen vom Shop ab:
{
"data": {
"offers": {
"edges": [{ "node": { "__typename": "Event", "id": "offer-id" } }]
}
}
}Wandeln Sie den zurückgegebenen GraphQL-Typ in den passenden OfferableTypeEnum um und rufen Sie anschließend dieses Angebot ab:
export KORONA_EVENT_OFFER_ID="$(printf '%s\n' "$DISCOVERY_RESPONSE" | jq -r '.data.offers.edges[0].node.id')"
export KORONA_EVENT_OFFER_TYPE="$(printf '%s\n' "$DISCOVERY_RESPONSE" | jq -r '
.data.offers.edges[0].node.__typename as $type |
{Admission: "ADMISSION", Event: "EVENT", EventDesc: "EVENT_DESC", EventTemplate: "EVENT_TEMPLATE", Product: "PRODUCT", VoucherConfiguration: "VOUCHER_CONFIGURATION"}[$type]
')"
curl -sS -X POST "$KORONA_EVENT_API_ORIGIN/api/graphql/booking/v1" \
-H "Content-Type: application/json" \
-H "X-Tenant-Domain: $KORONA_EVENT_SHOP_DOMAIN" \
--data "$(jq -n \
--arg query 'query GetOffer($id: ID!, $type: OfferableTypeEnum!, $posId: ID!) { offer(id: $id, type: $type, posId: $posId) { __typename ... on Admission { id } ... on Event { id } ... on EventDesc { id } ... on EventTemplate { id } ... on Product { id } ... on VoucherConfiguration { id } } }' \
--arg id "$KORONA_EVENT_OFFER_ID" \
--arg type "$KORONA_EVENT_OFFER_TYPE" \
--arg posId "$KORONA_EVENT_SHOP_POS_ID" \
'{query: $query, variables: {id: $id, type: $type, posId: $posId}}')" | jq .Die erwartete Erfolgsantwort hat folgende Form:
{
"data": { "offer": { "__typename": "Event", "id": "offer-id" } }
}Typ und ID stimmen mit dem Suchergebnis überein. Enthält die Antwort "offer": null, ist das Angebot für diesen Shop und diese POS-ID nicht sichtbar oder ID und Typ passen nicht zusammen. Ermitteln Sie das Angebot mit demselben Shop-Kontext erneut, bevor Sie fortfahren.
Öffnen Sie über die Auswahl der GraphQL-API-Referenzen das genaue Schema für Booking v1 oder Management v1. Die generierten Referenzen sind auf Englisch verfügbar und enthalten außerdem normalisiertes Markdown, SDL und ein maschinenlesbares Manifest.
Booking-Zugangsdaten und Fehler behandeln
Verwenden Sie die drei Booking-Zugangsdaten getrennt:
| Zugangsdaten | Platzierung |
|---|---|
Kontakt-authToken | Authorization: Bearer <token> für kontakt-authentifizierte Operationen wie contactWhoAmI |
Auftrags-accessToken | id der Auftragsabfrage, input.id einer Auftragsmutation oder input.requestId einer Positionsmutation, wie in der jeweiligen Operation definiert |
Rechnungs-accessToken | id der Rechnungsabfrage oder input.invoiceToken von paymentIntentCreate |
Das Feld input.id einer Positionsmutation identifiziert die Position; es ersetzt nicht input.requestId. Auftrags- und Rechnungstoken gelten jeweils für ihren Ressourcentyp und sind nicht austauschbar.
Wählen Sie bei Mutationen neben den Ergebnisfeldern der Operation errors { key message messageTranslated } aus. message ist der maschinenlesbare Fehlercode für Anwendungsentscheidungen; key kennzeichnet den betroffenen Eingabepfad. Zeigen Sie messageTranslated als lokalisierte Erklärung an. Verwenden Sie eine eigene lokalisierte Ersatzmeldung, wenn diese Erklärung fehlt. Die veralteten Arrays messages und messagesTranslated stehen für bestehende Clients weiterhin zur Verfügung.
Eine erfolgreiche HTTP-Antwort garantiert keinen erfolgreichen Vorgang: Prüfen Sie zuerst die GraphQL-errors auf oberster Ebene und dann die errors im Mutations-Payload, bevor Sie das Ergebnis verwenden. Die Payloads sind operationsspezifisch: requestCreate gibt request zurück, requestItemCreate gibt request und requestItem zurück, und paymentIntentCreate gibt payment zurück. Ein allgemeines Feld result gibt es nicht. Fehlt nach einem Schreibvorgang die Antwort, bleibt dessen Ergebnis ungewiss. Wiederholen Sie Checkout- oder Zahlungsschreibvorgänge nicht automatisch, ohne die Wiederholungsregeln der Operation zu prüfen.
Erwartetes Ergebnis
Ihre Integration verwendet den passenden Endpunkt, speichert ihr Geheimnis sicher, besitzt nur die erforderlichen Berechtigungsbereiche oder Nutzerberechtigungen und kann eine erste Anfrage abschließen.
Fehlerbehebung
| Problem | Was Sie überprüfen sollten |
|---|---|
| Management meldet „nicht autorisiert“ | Das Bearer-Token ist unverändert, nicht abgelaufen und nicht widerrufen. Bitten Sie den Support bei einem verlorenen Geheimnis um Rotation der aktiven Zugangsdaten. |
| Eine Management-Abfrage wird abgelehnt | Das Token enthält events:read oder catalog:read für diese Abfrage. |
| Der Tenant-Header widerspricht dem Token | Entfernen Sie X-Tenant-Domain; der Tenant des Management-Tokens ist maßgeblich. |
| Ein Legacy-API-Schlüssel wird abgelehnt | Prüfen Sie, ob der Schlüssel nicht widerrufen wurde, X-Tenant-Domain zu seinem Konto passt und der verknüpfte Nutzer weiterhin die erforderlichen Berechtigungen besitzt. |
| Booking lehnt eine Anfrage ab | Shop-Domain, Anfrage-/Kontakt-Token und operationsspezifische Shop-Regeln. |
| Entfernungen fehlen in der Synchronisierung | Speichern Sie updatedAt, folgen Sie den Cursorn und verarbeiten Sie Datensätze mit tombstone: true. |
Eine API antwortet mit 429 | Warten Sie die Dauer aus Retry-After ab und verwenden Sie danach exponentielles Backoff mit Jitter. Reduzieren Sie die Parallelität und vermeiden Sie enge Wiederholungsschleifen. |