Two tiny single-page examples that render a seat map. They show the one thing that matters: how to drive a seats.io chart from the Coras API.
vue/- web (Vue 3 +@seatsio/seatsio-vue)flutter/- mobile (Flutter + theseatsiopackage)
Ids are hardcoded, there is no reservation call, and selecting a seat just logs. That is on purpose.
Coras's seats.io charts only hold the layout (sections, rows, seats). They carry no categories. Availability, categories and prices all live in the Coras API. So you fetch from the API first, then feed that data into the chart.
1. GET theater-events/{eventId}?date_start=DATE&date_end=DATE pick the instance, read price_bands
2. GET theater-events/{eventId}/instances/{instanceId}/seats available seats, grouped by category
3. transform into chart inputs:
categories [{ key, label, color }] from price bands
objectCategories { "DRESS CIRCLE-A-6": "id" } available seats only
pricing [{ category, price }]
4. render the chart: event = instanceId, plus the inputs above
5. on select / deselect: log
- Seat keys from
/seats(e.g.DRESS CIRCLE-A-6) are the seats.io object labels, so they drop straight intoobjectCategories. - A seat's
category_idis the Coras price bandid. That links each seat to its color and price. - The seats.io event key is the performance
instance_id. - Prices are in minor units (
7500means75.00), so thepriceFormatterdivides by 100. - Availability: we only categorize available seats, then block the rest.
Vue passes
selectableObjects(the available labels). Flutter has noselectableObjects, so it setsobjectWithoutCategorySelectable = falseinstead. - Price bands come from the date-filtered listing endpoint. The single-instance endpoint needs a
Booking-Sessionheader, so we avoid it. - Row labels: turn on
showRowLabels(Vue does). There is no "both sides" flag; that is part of the chart design in seats.io, and labels only appear once you zoom into a section. - Deprecation warnings for
categoriesandobjectWithoutCategorySelectableare expected. They still work. The long-term fix is to put categories on the seats.io event itself (a backend change), after which the chart needs onlyobjectCategoriesandpricing.
Two values are not in source, so you set them yourself:
- Vue: copy
vue/.env.exampletovue/.envand fillVITE_CORAS_API_BASEandVITE_CORAS_DISTRIBUTOR_ID. - Flutter: pass them on the command line:
flutter run --dart-define=CORAS_API_BASE=... --dart-define=CORAS_DISTRIBUTOR_ID=...
Everything else is in the config block of coras.js / coras.dart:
| Setting | Value |
|---|---|
| API base | from env (your Coras API host, e.g. the sandbox) |
Coras-Distributor |
from env (your distributor id) |
| API version | v2 |
| seats.io public key | 18511d38-1ee3-44ea-86d6-a8fcad5fe598 (public, safe to expose) |
| region | eu (change if your workspace differs) |
| event id | dcf9ff63ab58ce482597dabfe9e27223 (sandbox test event) |
| instance / date | 5c5677e4bf1d2aaa896fc740ab96a06a / 2026-05-31 |
| language / currency | en / GBP |
The instance ([TEST] The Lion King, 2026-05-31) is already set. For another date, get its
instance_id from the listing endpoint and update date + instanceId.
The API is called straight from the browser or app with the Coras-Distributor header. Locally
you may hit CORS. If so, run behind the distributor domain or proxy through your own backend.