T
TOMO
Developer Docs
BETA These docs are under partner review. Some features described are roadmap items, not yet shipped. Verify against your sandbox before relying on any contract.
● DRAFTv1.0.0entertainment.book_theatre_play

Intent Spec — entertainment.book_theatre_play

FULL ID:       entertainment.book_theatre_play
VERSION:       v1.0.0
STATUS:        draft
LAST UPDATED:  2026-05-12
DOMAIN:        entertainment
PRIMARY AGENT: EntertainmentAgent
TTBS WEIGHTS:  time=0.20 taste=0.45 budget=0.20 safety=0.15

User books a ticket to a live theatre play, drama, musical, or dance recital. TASTE-dominant — the user is choosing a production, often a specific director/troupe/translation. Distinct from entertainment.book_movie_ticket, entertainment.book_comedy_show, and entertainment.book_concert_ticket.

Partner exemplars: BookMyShow, Paytm Insider, individual theatre venues (Prithvi Theatre, Ranga Shankara, Jagriti, NCPA), regional troupes' direct sites.


SECTION 1 — INTENT IDENTITY

User wants to attend live theatre. Distinct from:

  • entertainment.book_movie_ticket — recorded film
  • entertainment.book_comedy_show — stand-up / improv
  • entertainment.book_concert_ticket — music concert
  • entertainment.book_event_venue — book the venue (private use)

Single intent per booking. Multi-act festival passes (theatre festivals like META) are single intent.


SECTION 2 — NATURAL LANGUAGE COVERAGE

CLASSIFIES IN

  • "Book play at Prithvi Theatre"
  • "Hindi drama in Bengaluru this weekend"
  • "Marathi natak tickets"
  • "Bharatanatyam recital this Saturday"
  • "Musical theatre in Hyderabad"
  • "Two tickets for Romeo and Juliet at Ranga Shankara"
  • "English play tonight"
  • "Mahesh Dattani play"
  • "Children's theatre Sunday afternoon"
  • "Tamil drama in Chennai"

CLASSIFIES OUT — BORDERLINE NO

  • "Comedy show" → entertainment.book_comedy_show
  • "Concert" → entertainment.book_concert_ticket
  • "Movie" → entertainment.book_movie_ticket
  • "Book Prithvi for my play production" → entertainment.book_event_venue

MULTI-INTENT TRIGGERS

  • "Play + dinner before" → entertainment.book_theatre_play + food.book_dine_in
  • "Theatre + ride home" → entertainment.book_theatre_play + mobility.book_intracity_ride

SECTION 3 — INPUT (TOMO → PROVIDER)

{
  "intent": "entertainment.book_theatre_play",
  "request_id": "req_01J9Z...",
  "user_location": { "lat": 17.4475, "lng": 78.3563, "max_radius_km": 18, "city": "Hyderabad" },
  "preferences": {
    "play_title": null,
    "playwright_or_director": null,
    "troupe_name": null,
    "language": ["en", "hi"],
    "play_format": ["drama"],
    "show_window": {
      "start": "2026-05-17T15:00:00+05:30",
      "end":   "2026-05-17T23:00:00+05:30"
    },
    "seat_count": 2,
    "seat_section_preference": ["reserved", "general"],
    "content_rating_max": "adult_16",
    "accessibility": { "wheelchair_seats_required": 0 }
  },
  "ttbs_user_band": { "time": "balanced", "taste": "great", "budget": "good", "safety": "balanced" },
  "session_context": { "tomo_session_id": "ses_01J9Z...", "user_dna_hash": "dna_v3_a7c9..." }
}

Anti-fabrication preamble: Listings must come from venues/troupes with active production schedules. Imaginary "coming soon" listings without confirmed dates = suspension.


SECTION 4 — PROVIDER TOOLS

(Same 4-tool pattern: search_plays / get_seat_map / create_booking / cancel_booking.)


SECTION 5 — RESPONSE SHAPE

TheatrePlayListing

TheatrePlayListing:
  show_id: { type: string, constraint: REQUIRED }
  production:
    play_title: { type: string, constraint: REQUIRED }
    playwright: { type: string, constraint: REQUIRED nullable }
    director: { type: string, constraint: REQUIRED nullable }
    troupe_name: { type: string, constraint: REQUIRED }
    language: { type: enum, constraint: REQUIRED, BCP-47 }
    play_format: { type: enum, constraint: REQUIRED, STRICT ENUM §6 }
    duration_minutes: { type: int, constraint: REQUIRED, 30-300 }
    intermissions_count: { type: int, constraint: REQUIRED, 0-3 }
    content_rating: { type: enum, constraint: REQUIRED, STRICT ENUM §6 }
    content_warnings:
      type: array<enum>
      constraint: REQUIRED, may be empty
      values: [strong_language, sexual_content, violence, religious, political, dark_themes, flashing_lights, smoke_effects]
    synopsis: { type: string, constraint: REQUIRED, ≤500 chars }
    cast_size: { type: int, constraint: REQUIRED, 1-50 }

  venue:
    venue_id: { type: string, constraint: REQUIRED }
    name: { type: string, constraint: REQUIRED }
    venue_type:
      type: enum
      constraint: REQUIRED, STRICT ENUM §6
      values: [proscenium_theatre, black_box, open_air_amphitheatre, hotel_ballroom, school_auditorium, multi_purpose]
    address: { type: string, constraint: REQUIRED }
    location: { type: object, shape: { lat, lng }, constraint: REQUIRED }
    distance_from_user_km: { type: float, constraint: REQUIRED, 0-50 }
    seating_style:
      type: enum
      constraint: REQUIRED, STRICT ENUM §6
      values: [proscenium, thrust, theatre_in_the_round, traverse, flexible]
    accessibility:
      wheelchair_accessible: { type: boolean, constraint: REQUIRED }
      hearing_loop: { type: boolean, constraint: REQUIRED }
      audio_description_available: { type: boolean, constraint: REQUIRED }

  showtime:
    start: { type: string, constraint: REQUIRED, ISO_DATETIME }
    end: { type: string, constraint: REQUIRED, ISO_DATETIME }
    advance_booking_cutoff: { type: string, constraint: REQUIRED, ISO_DATETIME }
    latecomer_policy: { type: enum, constraint: REQUIRED, STRICT ENUM §6, values: [no_entry, entry_at_intermission, entry_any_time] }

  pricing:
    sections:
      type: array<SectionPrice>
      constraint: REQUIRED, ≥1
      shape:
        section_id: { type: string, constraint: REQUIRED }
        section_label: { type: enum, constraint: REQUIRED, STRICT ENUM §6, values: [general, reserved, premium, box] }
        base_price_inr: { type: int, constraint: REQUIRED, INR_INTEGER, ≥0 }
        convenience_fee_inr: { type: int, constraint: REQUIRED, INR_INTEGER, ≥0 }
        gst_inr: { type: int, constraint: REQUIRED, INR_INTEGER, ≥0 }
        total_per_seat_inr: { type: int, constraint: REQUIRED, INR_INTEGER }

  availability:
    seats_available_total: { type: int, constraint: REQUIRED, ≥0 }
    seats_available_by_section: { type: object<section_id,int>, constraint: REQUIRED }
    fast_selling: { type: boolean, constraint: REQUIRED, semantics: "ratio < 20%" }
    house_full_threshold_pct: { type: int, constraint: REQUIRED, 0-100 }

  policies:
    cancellation:
      cutoff_minutes_before_start: { type: int, constraint: REQUIRED, ≥0 }
      refund_percent: { type: int, constraint: REQUIRED, 0-100 }
    age_restriction_enforced: { type: boolean, constraint: REQUIRED }
    photography_allowed: { type: boolean, constraint: REQUIRED, semantics: "almost always FALSE in theatre" }
    re_entry_allowed: { type: boolean, constraint: REQUIRED }

  partner_reference:
    source: { type: string, constraint: REQUIRED }
    deeplink: { type: string, constraint: REQUIRED, HTTPS URL }

FORBIDDEN FIELDS

Same standard forbidden list (paid_placement / urgency / AI photos / commission_padded). PLUS phantom_production_listing — productions without confirmed staging dates may not appear.


SECTION 6 — CONTROLLED VOCABULARIES

preferences.play_format / play_format:
  values:
    drama:           "Standard drama / play"
    musical:         "Musical theatre"
    one_man_show:    "Solo performance"
    dance_recital:   "Bharatanatyam / Kathak / contemporary etc."
    childrens:       "Children's theatre"
    devised:         "Devised / experimental"
    physical_theatre: "Physical / mime"
    classical_recital: "Classical music recital (theatre venue)"
    play_reading:    "Staged reading"

venue.venue_type:
  values: { proscenium_theatre, black_box, open_air_amphitheatre, hotel_ballroom, school_auditorium, multi_purpose }

venue.seating_style:
  values: { proscenium, thrust, theatre_in_the_round, traverse, flexible }

pricing.sections.section_label:
  values: { general, reserved, premium, box }

latecomer_policy: { values: { no_entry, entry_at_intermission, entry_any_time } }

content_rating: { values: { U, UA, adult_16, adult_18 } }

content_warnings:
  values: { strong_language, sexual_content, violence, religious, political, dark_themes, flashing_lights, smoke_effects }

SECTION 7 — TTBS DIMENSIONS

TIME (weight = 0.20):
  signals_used: [distance, showtime fit]
  weighting: { distance: 0.35, fit: 0.65 }

TASTE (weight = 0.45):
  signals_used:
    - playwright / director / troupe match
    - language match
    - play_format match
    - content_rating ≤ user max
    - venue familiarity (DNA)
  weighting:
    troupe_or_director: 0.40
    language: 0.25
    format: 0.20
    rating_ok: 0.10
    venue: 0.05

BUDGET (weight = 0.20):
  signals_used: [pricing min]

SAFETY (weight = 0.15):
  signals_used:
    - venue.accessibility
    - policies.age_restriction_enforced
    - content_warnings disclosed
    - latecomer_policy (no_entry can strand users; safety against arrival pressure)

SECTION 8 — COMPLETION CONTRACT

POST /api/v1/cpc/mcp_provider/<your_partner_id>
Body:
{
  "intent":           "entertainment.book_theatre_play",
  "external_id":      "<booking_id>",
  "request_id":       "<request_id>",
  "amount_inr":       480,
  "gst_inr":          86,
  "tips_inr":         0,
  "pass_through_inr": 0,
  "closed_at":        "2026-05-17T20:30:00+05:30",
  "status":           "completed",
  "seat_count":       2,
  "play_format":      "drama",
  "play_title":       "Romeo and Juliet"
}

HMAC, 5-min replay, NET-only commission.


SECTION 9 — WIDGET

TheatrePlayWidget (planned). Field mapping: play_title + troupe → header; venue + distance → subline 1; showtime + duration + intermissions → subline 2; pricing min → "From ₹X"; content_warnings (when present) → expandable info pill; latecomer_policy=no_entry → orange "Arrive by start" pill.


SECTION 10 — CACHING POLICY

(Same as comedy_show.)


SECTION 11 — ERROR CODES

(Same as comedy_show + LATECOMER_POLICY_VIOLATION (403 on entry, not at booking).)


SECTION 12 — SANDBOX → PRODUCTION CHECKLIST

[ ] All four tools implemented
[ ] Production listings backed by confirmed staging dates (no phantom productions)
[ ] content_warnings exhaustively populated where applicable
[ ] HMAC + amount_inr=NET
[ ] Compliance: GSTIN, venue entertainment license, troupe registration, privacy policy

SECTION 13 — ANTI-FABRICATION RULES

RULE 1: No paid_placement / ad / kickback.

RULE 2: phantom_production_listing forbidden — productions must have confirmed
        staging dates with venue + cast on file.

RULE 3: content_warnings must be exhaustively disclosed for productions with
        18+ themes, flashing lights (epilepsy risk), or smoke effects.

RULE 4: fast_selling ratio rule (<20%).

RULE 5: Convenience fee must be reasonable (typically ≤15% of base). Excessive
        booking fees that exceed Consumer Protection norms = review.

RULE 6: AI-generated production stills forbidden. Real production photos only.

RULE 7: Honest casting — director / playwright / troupe names must be accurate
        and verifiable.

RULE 8: No "Top Pick" / "TOMO Recommended" badges.

RULE 9: latecomer_policy must be displayed prominently. Surprising users with
        no_entry without disclosure = customer harm = suspension.

RULE 10: photography_allowed must be honest — most theatres prohibit, but
         enforcement is at venue. Misstating = customer expectation breach.

VERSION HISTORY

v1.0.0 — 2026-05-12 — Initial spec. NET commission base. TASTE-dominant (0.45)
                       — troupe / playwright / director are the decision drivers.