Přeskočit na hlavní obsah

API Požadavky

Reálné CoreAPI endpointy

Tento dokument definoval očekávané API kontrakty ještě před analýzou reálného backendu. Nyní máme k dispozici kompletní OpenAPI specifikaci Colosseum CoreAPI (v17.0.0.0, 70 endpointů, 13 domén). Mapování reálných endpointů na obrazovky, datové modely a klíčové poznatky: CoreAPI — Integrace.

Tento dokument definuje, co očekáváme od backend API z pohledu mobilní aplikace. Nejde o přesnou API specifikaci (tu dodá backend tým), ale o funkční požadavky, datové struktury a konvence, které mobilní klient potřebuje.

Formát

Endpointy jsou popsány REST-like konvencí. Implementace může být REST, GraphQL nebo jiná — důležitý je datový kontrakt a chování.


Obecné API konvence

AspektOčekávání
FormátJSON (application/json)
AuthBearer token v Authorization header
PaginationCursor-based (cursor, limit, hasMore)
Error formatKonzistentní error object: { code, message, details }
LocalizationAccept-Language header pro lokalizovaný obsah
Rate limitingHTTP 429 s Retry-After header
VersioningURL prefix (/v1/) nebo header-based
Image URLsAbsolutní URL s CDN, podporující width/height query params

Pagination (cursor-based)

Cursor-based pagination zajišťuje stabilní stránkování i při real-time změnách dat (nové akce, sold-out).

// Request
GET /v1/events?limit=20&cursor=eyJpZCI6MTIzfQ

// Response
{
"data": [...],
"pagination": {
"cursor": "eyJpZCI6MTQzfQ",
"hasMore": true,
"total": 342
}
}

Error format

{
"error": {
"code": "SEAT_UNAVAILABLE",
"message": "Vybrané sedadlo již není dostupné.",
"details": {
"seatId": "R5-S12",
"status": "reserved"
}
}
}

Events API [MVP]

Hlavní skupina endpointů pro práci s akcemi — prohlížení, vyhledávání, filtrování.

EndpointMetodaPopisFáze
/v1/eventsGETSeznam akcí (filtrovaný, stránkovaný, sortovatelný)MVP
/v1/events/{id}GETDetail akce s termíny, galerií, metadatyMVP
/v1/events/{id}/datesGETSeznam termínů s dostupnostíMVP
/v1/events/{id}/dates/{dateId}/seatsGETSeat map data (SVG/JSON) pro adresné sezeníMVP
/v1/events/{id}/dates/{dateId}/categoriesGETCenové kategorie pro neadresné sezeníMVP
/v1/events/featuredGETDoporučené / promo akce pro feedMVP
/v1/events/search?q=...&genre=...&city=...GETFulltext hledání s filtryMVP
/v1/events/{id}/relatedGETSouvisející akce (pro cross-sell)MVP

Filtering params pro /v1/events

ParametrTypPopis
genrestringŽánr/kategorie (musical, theatre, music, festival...)
citystringMěsto (praha, brno, ostrava)
venueIdstringID místa konání
organizerIdstringID pořadatele
dateFromISO 8601Akce od data
dateToISO 8601Akce do data
priceMinnumberMinimální cena (CZK)
priceMaxnumberMaximální cena (CZK)
availabilityenumavailable / few / soldout
sortenumdate / price / popularity

Response příklad: Event detail

{
"id": "evt_abc123",
"title": "La Traviata",
"organizer": {
"id": "org_xyz",
"name": "Národní divadlo"
},
"description": "Verdiovská opera v nové inscenaci...",
"category": "opera",
"tags": ["opera", "verdi", "narodni-divadlo"],
"hero": {
"url": "https://cdn.colosseum.cz/events/abc123/hero.webp",
"blurhash": "LKO2?U%2Tw=w]~RBVZRi};RPxuwH"
},
"gallery": [
{ "url": "...", "caption": "Scéna z 1. dějství" }
],
"metadata": {
"duration": "PT2H30M",
"language": "cs",
"subtitles": ["en"],
"intermission": true,
"accessibility": true,
"ageRestriction": null
},
"credits": [
{ "role": "Dirigent", "name": "Jakub Hrůša" },
{ "role": "Violetta", "name": "..." }
],
"venue": {
"id": "ven_nd",
"name": "Národní divadlo",
"city": "Praha"
},
"priceRange": { "min": 290, "max": 1490, "currency": "CZK" },
"dates": [
{
"id": "date_001",
"datetime": "2026-04-15T19:00:00+02:00",
"availability": "available",
"seatingType": "addressed"
}
]
}

Seat map data (/v1/events/{id}/dates/{dateId}/seats)

Vyřešeno — OQ-T-01

Formát seat map dat je JSON s koordinátyHallSeatOnline s x1, y1, x2, y2 (obdélníkové koordináty sedadla), color (#AARRGGBB), rotation (stupně). Endpointy: GET /cashdesk/event/{eventId} + GET /cashdesk/event/matrix/{eventId}. Viz CoreAPI integrace.

Očekávaná struktura:

{
"hall": {
"name": "Hlavní sál",
"layout": "svg_or_json_data_here",
"stagePosition": "top",
"sections": [
{ "id": "sec_1", "name": "Přízemí", "rows": [...] }
]
},
"seats": [
{
"id": "R5-S12",
"section": "sec_1",
"row": "5",
"number": "12",
"x": 245.5,
"y": 180.0,
"categoryId": "cat_premium",
"status": "available",
"price": 890
}
],
"categories": [
{
"id": "cat_premium",
"name": "Premium",
"color": "#D4AF37",
"price": 890
}
],
"meta": {
"totalSeats": 856,
"availableSeats": 342,
"updatedAt": "2026-04-15T18:30:00Z"
}
}

Auth API [MVP]

EndpointMetodaPopisFáze
/v1/auth/registerPOSTEmail+heslo registraceMVP
/v1/auth/loginPOSTEmail+heslo loginMVP
/v1/auth/oauth/{provider}POSTOAuth login/registrace (apple/google/facebook)MVP
/v1/auth/refreshPOSTToken refreshMVP
/v1/auth/forgot-passwordPOSTPassword reset emailMVP
/v1/auth/verify-emailPOSTOvěření emailu po registraciMVP
DELETE /v1/auth/accountDELETEGDPR smazání účtu (soft → hard po 30 dnech)MVP

Request/Response příklady

Login:

// POST /v1/auth/login
{
"email": "jan@example.cz",
"password": "..."
}

// Response 200
{
"accessToken": "eyJ...",
"refreshToken": "eyJ...",
"expiresIn": 900,
"user": {
"id": "usr_abc",
"email": "jan@example.cz",
"name": "Jan Novák",
"verified": true
}
}

OAuth:

// POST /v1/auth/oauth/apple
{
"idToken": "apple_id_token_here",
"nonce": "random_nonce"
}

// Response 200 (same format as login)

Token refresh:

// POST /v1/auth/refresh
{ "refreshToken": "eyJ..." }

// Response 200
{
"accessToken": "eyJ_new...",
"refreshToken": "eyJ_new_rotated...",
"expiresIn": 900
}

Cart & Payment API [MVP]

EndpointMetodaPopisFáze
/v1/cartPOSTVytvořit košík (session-based, timer start)MVP
/v1/cart/itemsPUTPřidat/odebrat položkyMVP
/v1/cart/voucherPOSTUplatnit kupón/voucherMVP
/v1/cart/checkoutPOSTZahájit platbuMVP
/v1/cart/payment-status/{id}GETStav platby (polling)MVP
/v1/cart/timerGETZbývající čas seat lockMVP

Timer management

Server řídí seat lock timer. Klient zobrazuje countdown na základě expiresAt timestamp z API. Při expiraci server automaticky uvolní sedadla.

// GET /v1/cart/timer
{
"cartId": "cart_xyz",
"expiresAt": "2026-04-15T19:15:00Z",
"remainingSeconds": 720,
"warningThreshold": 120
}

Platební flow

  1. Klient → POST /v1/cart/checkout (vybraná metoda)
  2. Server → redirect URL / payment intent (dle brány)
  3. Klient → native payment sheet (Apple/Google Pay) nebo WebView (kartová brána)
  4. Klient → polling GET /v1/cart/payment-status/{id} → success/failure
// POST /v1/cart/checkout
{
"paymentMethod": "apple_pay",
"cartId": "cart_xyz",
"contactInfo": {
"email": "jan@example.cz",
"firstName": "Jan",
"lastName": "Novák"
}
}

// Response 200
{
"paymentId": "pay_abc",
"status": "pending",
"method": "apple_pay",
"paymentIntent": "pi_...",
"clientSecret": "pi_..._secret_..."
}

Payment status polling

// GET /v1/cart/payment-status/pay_abc
{
"paymentId": "pay_abc",
"status": "completed",
"orderId": "ord_xyz",
"tickets": [
{ "id": "tkt_001", "eventTitle": "La Traviata", "seat": "R5-S12" }
]
}

Možné stavy: pendingprocessingcompleted | failed | expired


Tickets API [MVP]

EndpointMetodaPopisFáze
/v1/ticketsGETMoje vstupenky (včetně QR dat pro offline)MVP
/v1/tickets/{id}GETDetail vstupenkyMVP
/v1/tickets/{id}/sharePOSTVygenerovat share token (deep link)MVP
/v1/tickets/shared/{token}GETNačíst sdílenou vstupenkuMVP
/v1/tickets/{id}/wallet-passGETGenerovat Apple/Google Wallet passMVP

QR data format

Response musí obsahovat qrPayload (podepsaný string pro offline validaci) a qrMetadata (event name, date, seat info pro offline zobrazení).

{
"id": "tkt_001",
"orderId": "ord_xyz",
"event": {
"title": "La Traviata",
"venue": "Národní divadlo",
"datetime": "2026-04-15T19:00:00+02:00"
},
"seat": {
"section": "Přízemí",
"row": "5",
"number": "12",
"category": "Premium"
},
"qr": {
"payload": "signed_jwt_string_for_offline_validation",
"expiresAt": "2026-04-15T23:59:59Z"
},
"status": "valid",
"walletPassUrl": "https://api.colosseum.cz/v1/tickets/tkt_001/wallet-pass"
}

Orders API [MVP]

EndpointMetodaPopisFáze
/v1/ordersGETHistorie objednávek (stránkovaná)MVP
/v1/orders/{id}GETDetail objednávkyMVP
{
"id": "ord_xyz",
"createdAt": "2026-04-10T14:30:00Z",
"status": "completed",
"paymentMethod": "apple_pay",
"total": {
"amount": 1780,
"currency": "CZK"
},
"items": [
{
"ticketId": "tkt_001",
"eventTitle": "La Traviata",
"datetime": "2026-04-15T19:00:00+02:00",
"seat": "Přízemí, Řada 5, Sedadlo 12",
"category": "Premium",
"price": 890
}
],
"voucher": null
}

User Profile API [MVP / F1]

EndpointMetodaPopisFáze
/v1/profileGETProfil uživateleMVP
/v1/profilePUTAktualizace profiluMVP
/v1/profile/preferencesPUTOnboarding preference (žánry, města)F1
/v1/profile/preferencesGETAktuální preferenceF1

Notifications API [MVP / F1]

EndpointMetodaPopisFáze
/v1/notificationsGETSeznam notifikací (stránkovaný, cursor-based)F1
/v1/notifications/{id}/readPUTOznačit přečtenouF1
/v1/notifications/read-allPUTOznačit vše přečtenéF1
/v1/notifications/preferencesGETNastavení per typ notifikaceF1
/v1/notifications/preferencesPUTUložit nastaveníF1
/v1/devicesPOSTRegistrace push tokenu (FCM/APNs)MVP
/v1/devices/{id}DELETEOdregistrace push tokenu (logout)MVP

Registrace push tokenu

// POST /v1/devices
{
"token": "fcm_or_apns_token_here",
"platform": "ios",
"appVersion": "1.0.0",
"osVersion": "iOS 17.2"
}

Watchdog API [F1]

EndpointMetodaPopisFáze
/v1/watchdogsPOSTVytvořit hlídač (event + date)F1
/v1/watchdogsGETSeznam aktivních hlídačůF1
/v1/watchdogs/{id}DELETEZrušit hlídačF1
// POST /v1/watchdogs
{
"eventId": "evt_abc123",
"dateId": "date_001",
"notifyVia": ["push", "email"]
}

Loyalty API [F1]

EndpointMetodaPopisFáze
/v1/loyalty/accountGETBodový stav, tier, historieF1
/v1/loyalty/transactionsGETHistorie bodových transakcíF1
/v1/loyalty/rewardsGETKatalog odměn (stránkovaný)F1
/v1/loyalty/redeem/{rewardId}POSTVyměnit body za odměnuF1
// GET /v1/loyalty/account
{
"userId": "usr_abc",
"points": {
"balance": 450,
"lifetime": 1250,
"pendingExpiry": {
"amount": 100,
"expiresAt": "2026-10-15T00:00:00Z"
}
},
"tier": "Silver",
"nextTier": {
"name": "Gold",
"requiredPoints": 2000,
"remaining": 750
}
}

Content API [MVP / F1 / F2+]

EndpointMetodaPopisFáze
/v1/venues/{id}GETDetail místa konáníMVP
/v1/organizers/{id}GETDetail pořadateleMVP
/v1/subscriptionsGETSeznam předplatných / abonmáMVP
/v1/subscriptions/{id}GETDetail předplatnéhoMVP
/v1/faqGETFAQ seznam (kategorizovaný)F1
/v1/articlesGETBlog feed (stránkovaný)F2+
/v1/articles/{slug}GETDetail článkuF2+

Souhrnná tabulka všech endpointů

#EndpointMetodaFáze
1/v1/eventsGETMVP
2/v1/events/{id}GETMVP
3/v1/events/{id}/datesGETMVP
4/v1/events/{id}/dates/{dateId}/seatsGETMVP
5/v1/events/{id}/dates/{dateId}/categoriesGETMVP
6/v1/events/featuredGETMVP
7/v1/events/searchGETMVP
8/v1/events/{id}/relatedGETMVP
9/v1/auth/registerPOSTMVP
10/v1/auth/loginPOSTMVP
11/v1/auth/oauth/{provider}POSTMVP
12/v1/auth/refreshPOSTMVP
13/v1/auth/forgot-passwordPOSTMVP
14/v1/auth/verify-emailPOSTMVP
15/v1/auth/accountDELETEMVP
16/v1/cartPOSTMVP
17/v1/cart/itemsPUTMVP
18/v1/cart/voucherPOSTMVP
19/v1/cart/checkoutPOSTMVP
20/v1/cart/payment-status/{id}GETMVP
21/v1/cart/timerGETMVP
22/v1/ticketsGETMVP
23/v1/tickets/{id}GETMVP
24/v1/tickets/{id}/sharePOSTMVP
25/v1/tickets/shared/{token}GETMVP
26/v1/tickets/{id}/wallet-passGETMVP
27/v1/ordersGETMVP
28/v1/orders/{id}GETMVP
29/v1/profileGET/PUTMVP
30/v1/profile/preferencesGET/PUTF1
31/v1/devicesPOSTMVP
32/v1/devices/{id}DELETEMVP
33/v1/notificationsGETF1
34/v1/notifications/{id}/readPUTF1
35/v1/notifications/read-allPUTF1
36/v1/notifications/preferencesGET/PUTF1
37/v1/watchdogsGET/POSTF1
38/v1/watchdogs/{id}DELETEF1
39/v1/loyalty/accountGETF1
40/v1/loyalty/transactionsGETF1
41/v1/loyalty/rewardsGETF1
42/v1/loyalty/redeem/{rewardId}POSTF1
43/v1/venues/{id}GETMVP
44/v1/organizers/{id}GETMVP
45/v1/subscriptionsGETMVP
46/v1/subscriptions/{id}GETMVP
47/v1/faqGETF1
48/v1/articlesGETF2+
49/v1/articles/{slug}GETF2+

Celkem: 49 endpointů (32 MVP, 12 F1, 2 F2+, zbytek sdílený)