Events

Events with concrete dates. How to build a calendar, apply filters, and turn a date into a booking.

In go~mus, an Event is a happening like a workshop, a guided lecture or a children's programme - anything that takes place at a concrete time and can be booked. A Date is one execution of that event. An event usually has many dates over time; on a website you typically display dates, not events.

The most common use case for this resource is the event calendar on a museum website: a list of all bookable dates, optionally filtered by house, special exhibition, audience or language, with a link from each entry into the booking flow.

Full endpoint and schema reference: Swagger.

Event vs Date - the mental model

TermWhatExample
EventEvent template"Sunday tour through the collection"
DateConcrete execution with date and time"Sunday 18 May at 11:00"

On the website you list dates, the visitor clicks through, and ends up booking a specific date. An event by itself is not bookable - always the date.

Anatomy of an event object

The index and show responses contain per event:

  • id - stable, use it everywhere
  • title, sub_title, description - translatable via ?locale=de
  • museum_id, exhibition_id - assignment
  • category - embedded category object (see filters below)
  • bookable, registerable - context-dependent flags for your auth context
  • featured - boolean, whether to highlight in the frontend
  • min_persons, max_persons, max_participants - per-booking limits and total capacity
  • duration - duration in minutes
  • entry_fee - mode for entry-fee display (auto / included / excluded / none)
  • upcoming_bookings_start_times - embedded list of the next free start times for this event. Very handy for listings: you can show "Next: Sat 18 May at 11:00" right in the event overview without a second roundtrip to dates or calendar per event.

The show response additionally embeds: dates (upcoming dates), tickets (related ticket configurations), quotas, content (long descriptions), documents (attachments).

Full field list: Swagger.

Anatomy of a date object

The date resource is intentionally lean - most display data comes from the underlying event:

  • id - stable, use it in the order item
  • event_id - back reference to the event
  • status - booked (confirmed and taking place) or cancelled
  • language - embedded, with code and label
  • location - embedded, if the event is location-specific
  • prices - list of price variants for this date
  • start, ende - start and end time (ISO 8601)
  • category, duration, entry_fee - inherited from the event

Endpoints at a glance

EndpointWhatWhen to use
GET /api/v4/eventsEvent listOverview of all events, with filters
GET /api/v4/events/:idEvent detailFull description including upcoming dates
GET /api/v4/events/:event_id/calendarCalendar for one event"Which dates does this one event have?"
GET /api/v4/events/:event_id/datesDates of an eventList of executions with detail
GET /api/v4/events/:event_id/dates/:idSingle dateTime, language, prices for one execution
GET /api/v4/datesGlobal calendarEvent calendar across all events
GET /api/v4/events/:event_id/categoriesEvent categoriesfor filter UI
GET /api/v4/events/:event_id/languagesAvailable languagesfor filter UI
GET /api/v4/events/:event_id/audiencesAudiencesfor filter UI
GET /api/v4/events/:event_id/age_groupsAge groupsfor filter UI

Common tasks

Build an event calendar (the main use case)

The endpoint built for this: GET /api/v4/dates. It returns dates across all events in a time window, using the same filters as for events.

curl "https://demo.gomus.de/api/v4/dates?start_at=2026-05-01&end_at=2026-05-31&locale=de"

Default for start_at is today, default for end_at is end of the start month.

Combinable filters (all optional):

  • by_museum_ids[]=20 - only dates of one house
  • by_exhibition_ids[]=2057 - only dates for a special exhibition (-1 for "no exhibition link")
  • by_event_ids[]=843 - only dates for specific events
  • by_category_ids[]=12 or by_categories[]=tour - category filter
  • by_audience_ids[]=4 - e.g. only dates for families
  • by_age_group_ids[]=2 - e.g. only dates for adults
  • by_grade_ids[]=8 - e.g. school grade
  • by_language_ids[]=1 - only German-language dates
  • by_catch_word_ids[], by_disablement_ids[], by_proposal_category_ids[] - further classifications
  • by_bookable=true - only actually bookable dates

The response contains per date: status, time, event reference, language and prices - enough for a list view. For detail clicks, link to the date or the event.

Event list with filters

curl "https://demo.gomus.de/api/v4/events?by_museum_ids[]=20&by_audience_ids[]=4&with_bookings_in_future=true&locale=de"

with_bookings_in_future=true is useful to only show events that actually have upcoming dates.

Populate a filter UI with available values

Instead of hard-coded dropdowns, fetch the currently relevant filter values:

curl "https://demo.gomus.de/api/v4/events/categories?locale=de"
curl "https://demo.gomus.de/api/v4/events/audiences?locale=de"
curl "https://demo.gomus.de/api/v4/events/languages?locale=de"

These endpoints return only the values actually used in the instance - clean for a filter sidebar.

Event detail with embedded dates

curl "https://demo.gomus.de/api/v4/events/843?locale=de"

The show response delivers description and upcoming dates in one go, so a detail page does not need a second roundtrip.

Dates of one specific event

curl "https://demo.gomus.de/api/v4/events/843/dates?start_at=2026-05-01&end_at=2026-12-31"

Use this when you build a per-event date overview.

From date to booking - four paths

Once a visitor clicks on a date, depending on setup there are four options:

If the museum runs a go~mus shop, every event/date has a canonical shop URL. The simplest solution: link from the calendar straight there. The shop handles selection, headcount, options and payment.

2. Web components in your own frontend

If you want the booking flow inside the museum website's layout, without jumping to a shop: the go~mus web components cover date selection, headcount, checkout and payment. Full CSS control, no iframe.

3. Direct booking via the API (POST Order + Finalize)

If you implement the full booking flow yourself (e.g. how Museumsdienst Berlin does it on their website): two calls suffice.

First create an order with the date as an item:

curl -X POST "https://demo.gomus.de/api/v4/orders" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "order": {
      "items": [
        { "date_id": 91234, "quantity": 2 }
      ],
      "customer": { "email": "user@example.com", "..." : "..." }
    }
  }'

Then finalize - this triggers confirmation email, barcode generation and the backoffice entry:

curl -X POST "https://demo.gomus.de/api/v4/orders/ORDER_TOKEN/finalize" \
  -H "Authorization: Bearer YOUR_TOKEN"

Exact payload structures, validation rules and payment options: Swagger and Best Practices.

4. Iframe widget

For simple cases there are iframe-based widgets - faster to integrate, less layout control.

Relationships

Event
 ├── Date (1..n) ......... concrete executions
 │    ├── Language ....... language of the date
 │    ├── Location ....... location if different from the event
 │    └── Prices ......... price variants for this date
 ├── Museum .............. house
 ├── Exhibition (0..1) ... special exhibition
 ├── Category ............ e.g. tour, workshop, lecture
 ├── Audience (0..n) ..... e.g. families, school classes
 ├── AgeGroup (0..n) ..... e.g. children, adults
 ├── Language (0..n) ..... which languages are offered
 └── OrderItem (via date)  when booked

The booking primitive is always the date - never the event.

Pitfalls

  • Global calendar vs per-event calendar. For the website list across all events: GET /api/v4/dates. For a detail page of one event: GET /api/v4/events/:id (with embedded dates) or GET /api/v4/events/:event_id/dates.
  • Reservation endpoint only for public-tour bookings. POST /api/v4/events/reservations does exist (with event_id = booking id, quantity), but only works for bookings configured as a public tour (Einzelangebot). Pure events without a tour link have no reservation hold - their seats are claimed directly at order create. Plan accordingly: idempotent order create plus clean finalize error handling.
  • by_status is content-API-user only. Default is booked - cancelled dates do not show up in normal lists. To get cancelled ones, pass by_status=cancelled, but only a content API user token is allowed to do so.
  • start_at / end_at have defaults. Without parameters you get "from today to end of the month". For a 12-month calendar set both explicitly.
  • Category filter has two variants. by_category_ids[] filters via numeric id, by_categories[] via the filtername string of the category. The latter is more robust against id changes across instances.
  • exhibition_id = -1 in the filter is a special form: it returns dates that belong to no special exhibition. Useful for "collection events".