7.8 KiB
API Contract
This document proposes the initial REST API for AzioneLab. Endpoint names are intentionally explicit and small-project friendly.
All examples use JSON unless noted otherwise.
Public Content
List Shows
GET /api/shows/
Returns published shows.
Response 200 OK:
{
"results": [
{
"id": 1,
"title": "The Open Stage",
"slug": "the-open-stage",
"summary": "A contemporary theatre performance.",
"poster_image": "https://example.org/media/shows/open-stage.jpg"
}
]
}
Show Detail
GET /api/shows/{slug}/
Response 200 OK:
{
"id": 1,
"title": "The Open Stage",
"slug": "the-open-stage",
"summary": "A contemporary theatre performance.",
"description": "Full public show description.",
"poster_image": "https://example.org/media/shows/open-stage.jpg",
"performances": [
{
"id": 10,
"starts_at": "2026-05-15T20:30:00+02:00",
"venue": {
"name": "AzioneLab Theatre",
"city": "Rome"
},
"booking_enabled": true,
"available_seats": 24
}
]
}
Status codes:
200 OK: show found;404 Not Found: show does not exist or is not published.
List Performances
GET /api/performances/
Optional filters:
show: show slug;from: start date/time lower bound.
Response 200 OK:
{
"results": [
{
"id": 10,
"show": {
"title": "The Open Stage",
"slug": "the-open-stage"
},
"venue": {
"name": "AzioneLab Theatre",
"city": "Rome"
},
"starts_at": "2026-05-15T20:30:00+02:00",
"booking_enabled": true,
"available_seats": 24
}
]
}
Performance Detail
GET /api/performances/{id}/
Response 200 OK:
{
"id": 10,
"show": {
"title": "The Open Stage",
"slug": "the-open-stage",
"summary": "A contemporary theatre performance."
},
"venue": {
"name": "AzioneLab Theatre",
"address": "Via Example 10",
"city": "Rome"
},
"starts_at": "2026-05-15T20:30:00+02:00",
"booking_enabled": true,
"available_seats": 24
}
Status codes:
200 OK: performance found;404 Not Found: performance does not exist or is not public.
Booking
Create Reservation
POST /api/performances/{id}/reservations/
Creates a pending reservation and sends a confirmation email.
Request:
{
"name": "Maria Rossi",
"email": "maria.rossi@example.org",
"phone": "+390600000000",
"party_size": 2,
"notes": "We will arrive a few minutes early."
}
Response 201 Created:
{
"id": 123,
"status": "pending",
"performance": 10,
"party_size": 2,
"message": "Reservation created. Please check your email to confirm it."
}
Status codes:
201 Created: pending reservation created;400 Bad Request: invalid input;404 Not Found: performance does not exist or is not public;409 Conflict: booking is closed or capacity is already unavailable.
Validation rules:
nameis required;emailmust be a valid email address;party_sizemust be a positive integer;- public clients must not set reservation status;
- the backend must validate booking availability server-side.
Confirm Reservation
POST /api/reservations/confirm/
Confirms a pending reservation using the token from the email link.
Request:
{
"token": "opaque-confirmation-token"
}
Response 200 OK:
{
"reservation_id": 123,
"status": "confirmed",
"party_size": 2,
"qr_code_url": "https://example.org/api/reservations/123/qr-code/"
}
Status codes:
200 OK: reservation confirmed;400 Bad Request: token is missing or malformed;404 Not Found: token is unknown;409 Conflict: token already used, reservation already handled, or no capacity remains;410 Gone: token expired.
Retrieve QR Code
GET /api/reservations/{id}/qr-code/
Returns the generated QR code for a confirmed reservation. Access must be protected by a valid QR token, signed URL, or equivalent control so that reservation IDs are not enough to retrieve QR codes.
Response 200 OK:
{
"reservation_id": 123,
"qr_code_image": "data:image/png;base64,...",
"printable": true
}
Status codes:
200 OK: QR code available;403 Forbidden: caller is not allowed to access the QR code;404 Not Found: reservation not found;409 Conflict: reservation is not confirmed.
Check-In
Check-in endpoints are for authenticated staff or admin users. Staff use a mobile-friendly Angular page to scan the QR code with a device camera or enter the token manually.
The QR code must contain only an opaque verification token or a verification URL containing that token. The backend resolves and validates the token server-side.
QR Verification Preview
POST /api/check-ins/preview/
Validates a QR token and returns a preview before staff confirms entrance. This endpoint must not create a successful check-in.
Request:
{
"token": "opaque-check-in-token"
}
Response 200 OK:
{
"status": "valid",
"reservation_id": 123,
"performance_id": 10,
"show_title": "The Open Stage",
"venue_name": "AzioneLab Theatre",
"starts_at": "2026-05-15T20:30:00+02:00",
"party_size": 2
}
Status codes:
200 OK: token is valid and reservation can be checked in;400 Bad Request: token is missing or malformed;401 Unauthorized: staff authentication is missing;403 Forbidden: authenticated user cannot preview check-in;404 Not Found: token is unknown;409 Conflict: reservation is not confirmed or was already checked in;410 Gone: token is expired.
The preview response should include only the minimum information staff need to validate the party. It must not expose unnecessary reservation personal data.
Check-In Confirmation
POST /api/check-ins/confirm/
Validates the token again and records successful entrance.
Request:
{
"token": "opaque-check-in-token"
}
Response 200 OK:
{
"status": "checked_in",
"reservation_id": 123,
"performance_id": 10,
"party_size": 2,
"checked_in_at": "2026-05-15T19:55:00+02:00",
"checked_in_by": 7
}
Status codes:
200 OK: reservation checked in;400 Bad Request: token is missing or malformed;401 Unauthorized: staff authentication is missing;403 Forbidden: authenticated user cannot confirm check-in;404 Not Found: token is unknown;409 Conflict: reservation is not confirmed or was already checked in;410 Gone: token is expired.
Successful confirmation creates a CheckIn record, or updates an existing incomplete check-in record for the reservation. A reservation cannot have two successful check-ins.
Error responses should use clear machine-readable states so the staff interface can show simple messages.
Example 409 Conflict for duplicate check-in:
{
"status": "already_checked_in",
"detail": "This reservation has already been checked in."
}
Example 409 Conflict for unconfirmed reservation:
{
"status": "reservation_not_confirmed",
"detail": "This reservation is not confirmed."
}
Administration
The initial administration API is Django admin.
Admin paths:
GET /admin/
Admin users can manage shows, venues, performances, reservations, reservation tokens, and check-ins according to staff permissions.
Status codes:
302 Found: unauthenticated browser redirected to admin login;200 OK: authenticated admin page;403 Forbidden: authenticated user lacks the required permission.
Error Format
Use Django REST Framework's standard validation error format unless a project-specific envelope is introduced later.
Example 400 Bad Request:
{
"email": ["Enter a valid email address."],
"party_size": ["Ensure this value is greater than or equal to 1."]
}