Booking Service API Changes - v1.60.0

Release: v1.60.0 Date: 2026-03-19 Base URL: https://api.seatmap.pro


Summary

Breaking Changes: YES New Endpoints: 1 Modified Endpoints: 2 Deprecated Endpoints: 0 Removed Endpoints: 1

API Versions Affected:

  • Private API (/api/private/v2.0/)

New Endpoints

POST /api/events/{eventId}/status

Status: New

Purpose: Transition an event between lifecycle states (DRAFT, PUBLISHED, ARCHIVED).

Authentication: Required

  • Type: Bearer Token
  • Header: Authorization: Bearer {token}

Request:

POST /api/events/{eventId}/status HTTP/1.1
Host: api.seatmap.pro
Content-Type: application/json
Authorization: Bearer {your_token}

{
  "status": "PUBLISHED"
}

Path Parameters:

Parameter Type Required Description Example
eventId UUID Yes The event ID a1b2c3d4-e5f6-7890-abcd-ef1234567890

Request Body:

{
  "status": "PUBLISHED"  // One of: DRAFT, PUBLISHED, ARCHIVED
}

Success (200 OK):

{
  "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "name": "Concert 2026",
  "status": "PUBLISHED",
  "publishedAt": "2026-03-19T10:00:00"
}

Allowed Transitions:

  • DRAFT -> PUBLISHED
  • PUBLISHED -> ARCHIVED
  • ARCHIVED -> DRAFT

Example:

# Publish a draft event
curl -X POST \
  'https://api.seatmap.pro/api/events/a1b2c3d4-e5f6-7890-abcd-ef1234567890/status' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"status": "PUBLISHED"}'

# Archive a published event (replaces DELETE)
curl -X POST \
  'https://api.seatmap.pro/api/events/a1b2c3d4-e5f6-7890-abcd-ef1234567890/status' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"status": "ARCHIVED"}'

Modified Endpoints

GET /api/private/v2.0/events/

Status: Modified

What Changed:

  • Added venueId filter parameter
  • Added status filter parameter
  • Added name full-text search parameter
  • Response now returns Page<EventExpand> with venue details

Breaking Change: NO – new parameters are optional, existing queries continue to work.

New Query Parameters:

Parameter Type Required Default Description Example
venueId Long No - Filter events by venue ?venueId=42
status String No - Filter by status (DRAFT, PUBLISHED, ARCHIVED) ?status=PUBLISHED
name String No - Case-insensitive text search on event name ?name=concert

Response now includes expanded fields:

{
  "content": [
    {
      "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
      "name": "Concert 2026",
      "start": "2026-06-15T19:00:00",
      "endDate": "2026-06-15T23:00:00",
      "schemaId": 123,
      "schemaName": "Main Hall",
      "venueId": "42",
      "venueName": "City Arena",
      "status": "PUBLISHED",
      "source": "MANUAL"
    }
  ],
  "pageable": { "pageNumber": 0, "pageSize": 20 },
  "totalElements": 1,
  "totalPages": 1
}

GET /api/private/v2.0/events/{id}

Status: Modified

What Changed:

  • Response now includes status, source, description, posterUrl, tags, publishedAt fields
  • Returns HTTP 422 if event is not PUBLISHED (for public API consumers)

Breaking Change: NO – additional fields in response only.


Breaking Changes

Removed Endpoints

DELETE /api/events/{eventId}

Removed In: v1.60.0

Replacement:

POST /api/events/{eventId}/status
Body: {"status": "ARCHIVED"}

Migration Guide:

  1. Replace DELETE /api/events/{eventId} calls with POST /api/events/{eventId}/status using body {"status": "ARCHIVED"}.
  2. Archived events are not deleted – they remain in the database and can be restored to DRAFT.

Booking API Rejects Non-Published Events

All public and private event endpoints now enforce that only PUBLISHED events are accessible. Requests for events in DRAFT or ARCHIVED state receive:

Response (422 Unprocessable Entity):

{
  "error": "EVENT_NOT_PUBLISHED",
  "message": "Event a1b2c3d4-e5f6-7890-abcd-ef1234567890 is not published"
}

Migration: All existing events are migrated to PUBLISHED by database migration V92, so no data is lost on upgrade. New events created via the API default to DRAFT and must be explicitly published before they appear in the booking API.

killAfter Field Deprecated

The killAfter field on events is now optional (nullable). Existing values are preserved. New integrations should not rely on this field.


Model Changes

Modified Models

Event

Added Fields:

{
  "status": "PUBLISHED",       // DRAFT | PUBLISHED | ARCHIVED
  "source": "MANUAL",          // MANUAL | API
  "externalId": "ext-123",     // Optional external system ID (unique)
  "description": "...",         // Optional event description
  "posterUrl": "https://...",   // Optional poster image URL
  "tags": ["rock", "outdoor"], // JSON array of tags
  "publishedAt": "2026-03-19T10:00:00",  // Set when event is published
  "createdAt": "2026-03-18T12:00:00",
  "updatedAt": "2026-03-19T10:00:00"
}

Changed Fields:

Field Old Type New Type Reason Migration
killAfter NOT NULL NULLABLE Deprecated No action needed – existing values preserved

New Models

EventExpand

Extends Event with venue context:

{
  "schemaName": "Main Hall",
  "venueId": "42",
  "venueName": "City Arena"
}

Error Handling Changes

New Error Codes

Code HTTP Status Description Resolution
EVENT_NOT_PUBLISHED 422 Event is not in PUBLISHED state Publish the event first via POST /api/events/{id}/status

Migration Guide

Quick Migration Checklist

  • Replace DELETE /api/events/{id} with POST /api/events/{id}/status + {"status": "ARCHIVED"}
  • Update event creation flow to explicitly publish events (API-created events default to DRAFT)
  • Handle HTTP 422 EVENT_NOT_PUBLISHED error in booking flows
  • Update client code to handle new event fields (status, source, tags, etc.)
  • Test event filtering with new query parameters

Step-by-Step Migration

1. Replace DELETE with Archive

- // Old: hard delete
- await fetch(`/api/events/${eventId}`, { method: 'DELETE' });

+ // New: archive (soft delete)
+ await fetch(`/api/events/${eventId}/status`, {
+   method: 'POST',
+   headers: { 'Content-Type': 'application/json' },
+   body: JSON.stringify({ status: 'ARCHIVED' })
+ });

2. Publish API-Created Events

Events created via the API now default to DRAFT. To make them bookable:

// Step 1: Create event (defaults to DRAFT)
const event = await createEvent({ name: 'Concert', schemaId: 123, ... });

// Step 2: Publish event
await fetch(`/api/events/${event.id}/status`, {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ status: 'PUBLISHED' })
});

3. Handle 422 in Booking Flows

const response = await fetch(`/api/public/v2.0/events/${eventId}`);
if (response.status === 422) {
  const error = await response.json();
  if (error.error === 'EVENT_NOT_PUBLISHED') {
    // Event is not yet published or has been archived
  }
}