Ticketing über die Content API
Tickets, Sitzplätze, Lounges und Location-Buchungen direkt auf der eigenen Website verkaufen: Voraussetzungen, Endpunkte, Reservierung, Kasse, Bestellstatus und Fehlercodes.
Worum es geht
Tickets, die Sie im Eventmanager anlegen, verkaufen Sie normalerweise über Ihren Ticketshop. Mit der Content API von Inhalte verkaufen Sie dieselben Tickets zu denselben Preisen direkt auf Ihrer eigenen Website – mit eigenem Aussehen und ohne Weiterleitung auf eine fremde Seite. Dasselbe gilt für Sitzplätze, Lounges und buchbare Bereiche einer Location. Wie Sie Events, Tickets und Shops einrichten, steht unter Ticketshop im Überblick.
Die Vorlagen club-nightlife und veranstaltungshaus bringen alle Bausteine dafür mit (siehe Eigene Website anbinden).
Voraussetzungen
- Freischaltung: Der Ticketverkauf über die Content API ist nicht in jeder Organisation freigeschaltet. Antworten alle Endpunkte mit
403 API_DISABLED, wenden Sie sich an Ihre Administratorin oder an den Support. - Shop freigeben: Im Eventmanager muss beim Ticketshop unter Verkaufskanäle der Schalter Verkauf auf der eigenen Webseite eingeschaltet und der Shop aktiv sein. Bestehende Shops sind zunächst gesperrt.
- Token: In Inhalte unter API-Tokens ein Token mit Lesen erstellen und unter Herkünfte die Adresse Ihrer Website eintragen. Ohne erlaubte Herkunft werden Reservierung und Kauf mit
403 ORIGIN_NOT_ALLOWEDabgewiesen. Siehe API-Tokens und erlaubte Herkünfte. - Zahlungsanbieter: mindestens ein aktiver Anbieter, siehe Einstellungen, Zahlungsanbieter und Nutzung.
Alle Endpunkte nehmen ein Token in der Kopfzeile oder den öffentlichen Präfix ?site=<präfix> an. Aus dem Browser verwenden Sie immer den Präfix, nie das ganze Token.
Drei Regeln
- Beträge sind ganze Rappen. Alle Betragsfelder enden auf
Minor(12000= 120.00 CHF). Einzige Ausnahme istvatRate, ein Prozentsatz (z.B.8.1). - Die Sprache steht in der Adresse (
?locale=de), nicht in einer Kopfzeile. - Eine Lounge ist ein Platz.
loungeUnits[].unitSeatIndexist der Sitzplatz, über den Sie eine Lounge wie einen normalen Platz reservieren.
Events und Verfügbarkeit
| Methode | Pfad | Zweck |
|---|---|---|
| GET | /ticketing/events |
Veröffentlichte Events; from, to (Kalendertage), timezone (Standard Europe/Zurich). Gefiltert wird nach dem Ende des Events. |
| GET | /ticketing/events/{slug} |
Event mit Tickettypen, Käuferfeldern und Saalinformation |
| GET | /ticketing/events/{slug}/availability |
Live-Verfügbarkeit: freie Stehplätze je Tickettyp, Sitzstatus, Lounges |
| GET | /ticketing/seatmaps/{versionId}/geometry |
Unveränderliche Geometrie eines Saalplans (lange zwischenspeicherbar) |
Der Sitzstatus in seats.statuses ist Base64 mit einem Byte je Platz: 0 frei, 1 gehalten, 2 verkauft, 3 gesperrt. Bei Sitzplatz- und Lounge-Tickets steht in der Event-Antwort keine Verfügbarkeitszahl – die kommt nur aus /availability.
Reservieren
| Methode | Pfad | Zweck |
|---|---|---|
| POST | /ticketing/events/{slug}/hold |
Plätze { "seatIndexes": [12, 13] } oder eine Lounge { "loungeUnitIndex": 812 } halten |
| GET | /ticketing/events/{slug}/hold |
Was dieser Warenkorb gerade hält |
| DELETE | /ticketing/events/{slug}/hold |
Gehaltene Plätze freigeben (nicht solche, die schon zu einer Bestellung gehören) |
Der Warenkorb wird über die Kopfzeile X-Cart-Token erkannt. Beim ersten Aufruf dürfen Sie sie weglassen; Scorebase liefert sie in der Antwort mit. Speichern Sie sie im sessionStorage des Browsers. Reservierungen gelten ganz oder gar nicht und laufen nach 15 Minuten ab. Wie viele Plätze ein Warenkorb und eine IP halten dürfen, ist begrenzt.
Kaufen
POST /ticketing/checkout
X-Cart-Token: <warenkorb>
Idempotency-Key: <eigener eindeutiger Schlüssel>
{
"eventSlug": "herbstnacht",
"items": [ { "ticketTypeId": "tt_1", "quantity": 2 } ],
"useHeldSeats": true,
"cartToken": "<warenkorb>",
"buyer": { "firstName": "Anna", "lastName": "Beispiel", "email": "anna@beispiel.ch", "language": "de" },
"marketingOptIn": false,
"returnUrls": {
"successUrl": "https://www.beispiel.ch/tickets/{accessToken}?result=success",
"cancelUrl": "https://www.beispiel.ch/tickets/abgebrochen",
"errorUrl": "https://www.beispiel.ch/tickets/fehler"
},
"_hp": ""
}- Die Preise rechnet Scorebase; die Anfrage nennt nur Tickettyp und Menge.
- Die Rückkehr-Adressen müssen auf eine erlaubte Herkunft des Tokens oder eine bestätigte Domain Ihres Ticketshops zeigen; eine leere Herkunftsliste erlaubt hier nichts.
{accessToken}wird durch die Kennung der Bestellung ersetzt. - Die Antwort enthält
nextCartToken(auch inX-Cart-Token). Verwenden Sie ab dann nur noch diesen – der alte Warenkorb hält nichts mehr. payment.kindistREDIRECT(Browser anpaymentUrlschicken),CLIENT_SECRET(Zahlungsformular des Anbieters einbetten) oderNONE(kostenlose Bestellung, bereits abgeschlossen).- Ist der Andrang gross, antwortet die Kasse mit
WAITING_ROOMund einer WartenummerqueueTicket. Senden Sie diesen Wert unverändert beim nächsten Versuch mit, sonst verliert der Gast seinen Platz in der Warteschlange.
Nach dem Kauf
| Methode | Pfad | Zweck |
|---|---|---|
| GET | /ticketing/orders/{accessToken} |
Bestellstatus; während der Zahlung alle drei Sekunden abfragen. E-Mail maskiert, Ticketcodes erst nach Zahlung |
| GET | /ticketing/orders/{accessToken}/pdf |
Tickets als PDF |
| POST | /ticketing/orders/{accessToken}/cancel |
Unbezahlte Bestellung stornieren |
| POST | /ticketing/orders/{accessToken}/refund-request |
Rückerstattung einer bezahlten Bestellung beantragen – geprüft nach den Stornobedingungen |
Location-Buchungen
| Methode | Pfad | Zweck |
|---|---|---|
| GET | /ticketing/locations/{key} |
Location mit buchbaren Bereichen |
| GET | /ticketing/locations/{key}/resources/{resourceKey}/availability |
Buchungskalender (from, to, höchstens 62 Tage) |
| POST | /ticketing/locations/{key}/resources/{resourceKey}/hold |
Zeitfenster halten; liefert einen holdToken (kein Warenkorb) |
| POST | /ticketing/bookings |
Buchung anlegen – sofort oder als Anfrage, je nach Einstellung des Bereichs |
| GET | /ticketing/bookings/{cancelToken} |
Status mit Stornierbarkeit und Frist |
| POST | /ticketing/bookings/{cancelToken}/cancel |
Buchung durch den Gast stornieren |
| GET | /ticketing/bookings/{cancelToken}/pdf |
Buchungsbestätigung mit Code zum Scannen |
Zwei Hinweise zum Kalender: Eine Nacht gehört zu ihrem Anfang (Freitag 23:00 bis 04:00 steht ganz unter Freitag). Und hängen Sie den Kaufknopf an bookable, nicht an „frei“ – der letzte Abschnitt einer Nacht kann frei, aber zu kurz für die Mindestdauer sein. Bei einer Anfrage folgt der Zahlungslink erst nach der Bestätigung; eine Stornierung gibt den Termin frei, Geld wird dabei nicht über Scorebase zurückerstattet.
Fehlercodes
Die Liste ist abschliessend. Werten Sie error.code aus, nicht die Meldung:
UNAUTHORIZED, ORIGIN_NOT_ALLOWED, RATE_LIMIT_EXCEEDED, NOT_FOUND, NOT_PUBLISHED, API_DISABLED, VALIDATION_ERROR, SOLD_OUT, SEAT_HOLD_MISSING, HOLD_LIMIT, LOCATION_CONFLICT, NOT_BOOKABLE, PAYMENT_INIT_FAILED, WAITING_ROOM, IDEMPOTENT_REPLAY.
error.details nennt die betroffene Stelle, z.B. fields bei Validierungsfehlern, ticketTypeId bei SOLD_OUT, max bei HOLD_LIMIT, retryAfterSeconds und queueTicket bei WAITING_ROOM.
Wenn etwas nicht klappt
| Fehler | Ursache | Lösung |
|---|---|---|
403 API_DISABLED |
Nicht freigeschaltet, oder beim Shop ist Verkauf auf der eigenen Webseite aus | Schalter im Eventmanager prüfen; sonst Support |
403 ORIGIN_NOT_ALLOWED |
Adresse der Website nicht als Herkunft eingetragen | Unter API-Tokens eintragen |
NOT_PUBLISHED |
Event nicht veröffentlicht | Event im Eventmanager veröffentlichen |
SEAT_HOLD_MISSING |
Reservierung abgelaufen oder alter Warenkorb verwendet | Plätze neu reservieren; nach dem Kauf nextCartToken verwenden |