Eine Tour in go~mus ist eine geführte Veranstaltung, die nicht zu festen Terminen stattfindet, sondern auf Anfrage oder Buchung angesetzt wird - klassische Führungen, Schulworkshops, Privatführungen, Kindergeburtstage. Anders als bei Events gibt es kein vorbelegtes Date pro Termin; stattdessen fragst du ab, wann eine Tour grundsätzlich verfügbar wäre, und der konkrete Termin entsteht erst mit der Anfrage oder Buchung.
Die zwei häufigsten Use-Cases dieser Resource sind:
1. Tour-Übersicht auf der Webseite mit Filterung nach Sprache, Zielgruppe, Sonderausstellung
2. Anfrage- oder Buchungsformular auf der Webseite, das in go~mus landet (Pattern Museumsdienst Berlin, Hamburg, viele andere)
Vollständige Endpoint- und Schema-Referenz: Swagger.
Tour vs Event - der Unterschied
| Tour | Event | |
|---|---|---|
| Termine | flexibel, vom/von der Kund:in vorgeschlagen | im Backoffice vordefiniert (Dates) |
| Buchungs-Primitiv | die Tour selbst plus Wunsch-Datum/Zeit | das Date |
| Hauptflow | Anfrage oder Direktbuchung | Direktbuchung |
| Verfügbarkeits-Endpoint | start_times | dates / calendar |
Ein Date pro Tour gibt es technisch trotzdem - sobald eine Tour gebucht ist, entsteht intern ein Booking mit konkretem Termin. Für die API-Sicht von außen ist die Resource aber die Tour, nicht das Date.
Anatomie eines Tour-Objekts
Im Index- und Show-Response findest du je Tour:
id- stabil, nutzt das in Items von Anfragen und Bestellungentitle,sub_title,description- übersetzbar via?locale=demuseum_id,exhibition_id- Zuordnungcategory- eingebettete Kategorie (Führung, Workshop, Vortrag, Kindergeburtstag, ...)bookable,registerable- kontextabhängige Flags für deine Auth-Stufefeatured- Boolean, Highlight-Flagmin_persons,max_persons,max_participants- Bestellgrenzen und Gruppenobergrenzeduration- Dauer in Minutenequipment- Liste benötigter Hilfsmittel (z.B. Kopfhörer, Beamer)entry_fee- Modus für Eintrittsgebühr-Anzeige
Im Show-Response zusätzlich: tickets, quotas, limitations, validities, content (Langtexte), documents (Anhänge), sellabilities.
Komplette Feldliste: Swagger.
Endpoints im Überblick
| Endpoint | Wofür | Wann nutzen |
|---|---|---|
GET /api/v4/tours | Tour-Liste | Übersichtsseite mit Filtern |
GET /api/v4/tours/:id | Tour-Detail | Volle Beschreibung, Konfiguration |
GET /api/v4/tours/:id/start_times | Verfügbare Startzeiten | "Wann kann ich diese Tour buchen?" |
GET /api/v4/tours/:id/prices | Preisermittlung | Was kostet die Tour mit X Personen am Datum Y |
GET /api/v4/tours/:id/categories | Kategorien einer Tour | für Filter-UI |
GET /api/v4/tours/:id/languages | Verfügbare Sprachen | für Filter-UI |
GET /api/v4/tours/:id/audiences | Zielgruppen | für Filter-UI |
GET /api/v4/tours/:id/age_groups | Altersgruppen | für Filter-UI |
POST /api/v4/requests | Anfrage anlegen | Kund:in fragt Termin an, Museum bestätigt manuell |
POST /api/v4/orders | Direktbuchung anlegen | Kund:in bucht sofort verbindlich |
Häufige Aufgaben
Tours auflisten
curl "https://demo.gomus.de/api/v4/tours?by_museum_ids[]=20&by_audience_ids[]=4&locale=de"
Die Filter sind dieselben wie bei Events - alle optional, alle kombinierbar:
by_museum_ids[]=20- nur Touren eines Hausesby_exhibition_ids[]=2057- nur Touren zu einer Sonderausstellung (-1für "ohne Ausstellungsbezug")by_category_ids[]=12oderby_categories[]=fuehrung- Kategorie-Filterby_audience_ids[]=4- z.B. nur Touren für Familienby_age_group_ids[]=2- z.B. nur Touren für Erwachseneby_grade_ids[]=8- Schulklassen-Stufeby_language_ids[]=1- nur deutschsprachige Tourenby_catch_word_ids[],by_disablement_ids[],by_proposal_category_ids[]- weitere Klassifikationenby_featured=true- nur Highlights
Filter-UI mit den verfügbaren Werten füllen
Wie bei Events liefern Sub-Resource-Endpoints die in der Instance tatsächlich genutzten Werte:
curl "https://demo.gomus.de/api/v4/tours/categories?locale=de"
curl "https://demo.gomus.de/api/v4/tours/audiences?locale=de"
curl "https://demo.gomus.de/api/v4/tours/languages?locale=de"
Verfügbare Startzeiten ermitteln
curl "https://demo.gomus.de/api/v4/tours/512/start_times?start_at=2026-05-01&end_at=2026-05-31&participants=15&language_ids[]=1"
Parameter:
start_at,end_at- Zeitfenster (Default: heute bis Ende des Monats). Maximaler Range: 60 Tage - größere Spannen gibt der Server mit einem Validierungsfehler zurück. Für ein 12-Monats-Datepicker machst du also mehrere Calls in 60-Tage-Buckets.participants- Teilnehmerzahl, beeinflusst Verfügbarkeit (Default: 1 oder dasmin_personsder Tour)language_ids[],age_group_ids[]- Filter, die in die Verfügbarkeitsberechnung einfließendepth-any(mindestens ein Slot pro Tag, Boolean-Antwort) oderall(alle buchbaren Slots, Liste); Defaultany
depth=any ist der typische Datepicker-Use-Case ("welche Tage sind buchbar"). depth=all ist der Slot-Picker-Use-Case ("welche Uhrzeiten am gewählten Tag").
Preis ermitteln
Tour-Preise sind kontextabhängig - sie hängen ab von Datum, Uhrzeit, Personenzahl, Sprache und der Preisgruppe (PriceTargetAudience, z.B. "Privatkunde", "Schulklasse", "Reseller"). Der Endpoint berechnet das in einem Call:
curl "https://demo.gomus.de/api/v4/tours/512/prices?date=2026-05-15&time=14:00&participants=15&language_id=1"
Parameter:
date(Default: heute)timealsHH:MM(Default:12:00)participants(Default: 1)language_id(Default: erste für die Tour hinterlegte Sprache)price_target_audience_id(Default: aus dem Auth-Kontext, sonst die instance-weite Default-PTA)
Die Antwort enthält die Einzelpositionen und den Gesamtpreis - genau das, was im Buchungsformular angezeigt wird.
Tour-Detail
curl "https://demo.gomus.de/api/v4/tours/512?locale=de"
Show-Response liefert die Beschreibung, eingebundene Tickets/Quotas, Validity-Regeln und Anhänge - genug für eine vollständige Detailseite.
Vom Wunsch zur Buchung - die zwei Wege
Weg 1: Anfrage (POST /api/v4/requests)
Die typische Lösung für Schul-Anfragen, Gruppenführungen und alles, was das Museum vor Bestätigung redaktionell prüfen will (Disposition, Guide-Auswahl, Sondervereinbarungen). Die Anfrage landet in go~mus mit Status registered, geht durchs Anfragen-Postfach, das Backoffice antwortet manuell.
curl -X POST "https://demo.gomus.de/api/v4/requests" \
-H "Authorization: Bearer YOUR_API_USER_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"request": {
"participants": 25,
"companions": 2,
"date": "2026-06-15",
"notes": "Klasse 7a, Geschichts-LK, Schwerpunkt 19. Jahrhundert",
"language": "Deutsch",
"age_group": "Schulklasse",
"grade": "Sekundarstufe II",
"items": [
{ "tour_id": 512, "time": "10:00" },
{ "tour_id": 519, "time": "13:00" }
],
"customer": {
"name": "Müller", "surname": "Anna",
"email": "lehrer@beispielschule.de",
"phone": "+49 30 12345",
"street": "Schulweg 1", "zip": "10115", "city": "Berlin"
}
}
}'
Wichtig:
- Authentifizierung über einen API-User-Token mit Permission. Public-Token reicht hier nicht.
itemsist Pflicht und muss mindestens einetour_idplus gewünschtetimeenthalten. Mehrere Items in einer Anfrage = Mehrfachführung am selben Tag.payment_mode,language,age_group,grade,proposal_category,categorylassen sich entweder als ID oder als übersetzter Name angeben.skip_confirmation_email: trueunterdrückt die automatische Bestätigungsmail (z.B. wenn dein System die Bestätigung selbst versendet).
Die Response liefert id, created_at, updated_at. Validierungsfehler kommen als 422 mit Feld-Details.
Weg 2: Direktbuchung (POST /api/v4/orders)
Wenn die Tour direkt verkauft werden soll - Privatführung, Workshop mit Festpreis, Tickets-on-Demand - geht das wie bei Events über Order plus Finalize.
Order anlegen mit der Tour als Item:
curl -X POST "https://demo.gomus.de/api/v4/orders" \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"order": {
"items": [
{
"tour_id": 512,
"date": "2026-06-15",
"start_time": "14:00",
"participants": 8,
"language_id": 1
}
],
"customer": { "email": "kund@example.com", "..." : "..." }
}
}'
Dann finalisieren:
curl -X POST "https://demo.gomus.de/api/v4/orders/ORDER_TOKEN/finalize" \
-H "Authorization: Bearer YOUR_TOKEN"
Genaue Payload-Strukturen, Validierungen und Payment-Optionen: Swagger und Best Practices.
Anfrage vs Direktbuchung - wann was
| Kriterium | Anfrage | Direktbuchung |
|---|---|---|
| Sofort verbindlich? | Nein, Bestätigung manuell | Ja |
| Preis bei Submit fix? | Optional (Group-Prices kommen automatisch) | Ja |
| Bezahlung sofort? | Nein | Ja, im Finalize-Schritt |
| Typische Nutzung | Schulklassen, Gruppenführungen, Sonderwünsche | Privatführungen, Workshop-Tickets |
| Auth | API-User-Token mit Permission | Public-Token, Reseller-Token oder API-User |
Wenn du beides anbietet, ist das Pattern: Formular auf der Webseite mit "Anfragen"-Button für Schulen/Gruppen und "Direkt buchen"-Button für Privatpersonen.
Beziehungen
Tour
├── Category ............ z.B. Führung, Workshop, Vortrag
├── Museum .............. Haus
├── Exhibition (0..1) ... Sonderausstellung
├── Audience (0..n) ..... z.B. Familien, Schulklassen
├── AgeGroup (0..n) ..... z.B. Kinder, Erwachsene
├── Language (0..n) ..... welche Sprachen werden angeboten
├── Guide (0..n) ........ welche Guides sind qualifiziert
├── Equipment (0..n) .... benötigte Hilfsmittel
├── Request (über items) wenn als Anfrage eingegangen
└── OrderItem .......... wenn direkt gebucht
Stolperdrahte
- Anfragen brauchen API-User-Token. Anders als Tour-Listing oder Preisberechnung (Public-Token reicht) erfordert
POST /requestseinen authentifizierten API-User mit Permission. Token im Frontend nicht offenlegen - die Anfrage muss serverseitig durchgereicht werden. start_timesmitparticipantsaufrufen. Wer die Teilnehmerzahl weglässt, bekommt Verfügbarkeit für diemin_personsder Tour. Das ist nicht falsch, aber bei großen Gruppen oft optimistisch - am Tag der Buchung kann die Gruppe nicht mehr passen.pricesist kontextabhängig. Ohneprice_target_audience_idfällt der Endpoint auf die Default-PTA (z.B. "Privatkunde") zurück. Für Reseller, Schulklassen oder Mitglieder unbedingt explizit angeben, sonst rechnest du mit den falschen Tarifen.depthbeistart_timesmacht den Unterschied.anyist deutlich günstiger und ausreichend für Datepicker-Logik.alllohnt sich erst, wenn Slots auf einem Tag angezeigt werden.start_timeshat ein 60-Tage-Limit. Für längere Vorschau-Zeiträume mehrere Calls. In der Praxis selten ein Problem, weil Datepicker ohnehin meist nur den aktuellen oder kommenden Monat zeigen.- Translated names statt IDs. Die Anfrage akzeptiert
language: "Deutsch"zusätzlich zur ID. Praktisch für Formulare ohne ID-Lookup, aber dann muss der Wert exakt mit der hinterlegten Übersetzung übereinstimmen.
Verwandte Seiten
- Events - das Pendant mit fixen Terminen
- Tickets - das andere Buchbar-Primitiv
- Konzepte - Quota, Order, Order Finalize, Anfragen
- Authentifizierung - Token-Typen, Permissions
- Best Practices - Caching, Errors, Idempotenz
- Szenario: Webseiten-Integration - Anfrage-Formular und Buchungsstrecke end-to-end