Files
azionelab/docs/api-contract.md

6.0 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:

  • name is required;
  • email must be a valid email address;
  • party_size must 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

Verify QR Code

POST /api/check-ins/verify/

Validates a QR token and records check-in. This endpoint is for authenticated staff or an authenticated scanning interface.

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"
}

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 perform 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 response should include only the minimum information staff need to admit the party.

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."]
}