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.0lifestyle.book_yoga_class

lifestyle.book_yoga_class — Full Intent Specification

INTENT NAMESPACE: lifestyle
INTENT NAME:      book_yoga_class
FULL ID:          lifestyle.book_yoga_class
VERSION:          v1.0.0
STATUS:           draft
LAST UPDATED:     2026-05-10
TTBS WEIGHTS:     time 0.30 · taste 0.40 · budget 0.20 · safety 0.10

Yoga class booking: instructor-led group or 1-on-1 yoga session at a studio. Inherits the slot-based shape from lifestyle.book_gym_session (which inherits from lifestyle.book_salon). Distinct: (a) yoga_style enum (Hatha, Vinyasa, Iyengar, Ashtanga, etc.); (b) class_kind (group / private / silent / themed); (c) props_provided (mats, blocks, straps, bolsters); (d) temperature_kind (room temp, hot yoga, cool); (e) instructor_certified_with_authority (Yoga Alliance, Iyengar Institute, traditional gurukul).

Inheritance contract: every field in lifestyle.book_gym_session §2/§4/§5 except gym-specific (equipment, treadmill, sauna_pool) is REQUIRED here too, adapted to yoga.


1. NATURAL LANGUAGE COVERAGE

Classifies IN

  • "yoga class tomorrow morning"
  • "Vinyasa yoga session"
  • "hot yoga near me"
  • "Iyengar yoga class"
  • "private yoga 1-on-1"
  • "Ashtanga yoga 6am"
  • "yoga class for beginners"
  • "yoga for back pain"
  • "kundalini yoga session Saturday"

Classifies OUT — borderline NO

  • "yoga at home" → lifestyle.book_at_home_service (yoga variant)
  • "gym session" → lifestyle.book_gym_session
  • "personal trainer for fitness" → lifestyle.book_personal_trainer
  • "spa with yoga" → lifestyle.book_spa_treatment
  • "wellness retreat with yoga" → lifestyle.book_wellness_retreat

MULTI-INTENT TRIGGERS

  • "yoga class and breakfast tiffin" → lifestyle.book_yoga_class + food.subscribe_tiffin
  • "yoga and cab" → lifestyle.book_yoga_class + mobility.book_intracity_ride

2. INPUT — TOMO → PROVIDER (DELTA over lifestyle.book_gym_session)

All fields from lifestyle.book_gym_session §2 are REQUIRED, with adaptations:

  • REPLACE workout_intent with yoga_intent block
  • REPLACE gym-specific preferences with yoga-specific
  • ADD yoga_style_preferences block
{
  "intent":          "lifestyle.book_yoga_class",
  "intent_version":  "v1.0.0",
  "request_id":      "req_yoga_8h2k_2026-05-10T08:00:00Z",

  "search_area": { ... },                                     // same as base
  "scheduled_for_iso":   "2026-05-12T06:00:00+05:30",
  "duration_minutes":     60,
  "session_kind":        "drop_in_class",

  "user_yoga_profile": {
    "gender":              "female",
    "age_band":            "26-35",
    "yoga_experience_level": "intermediate",
    "years_of_practice":   3,
    "medical_conditions_disclosed": ["mild_back_pain"],
    "yoga_goals":          ["flexibility", "stress_reduction"],
    "weight_kg":           58,
    "pregnant_or_postpartum": "none"
  },

  "yoga_intent": {
    "yoga_styles_acceptable":   ["hatha", "vinyasa", "iyengar"],
    "yoga_style_preferred":     "iyengar",
    "class_kind_acceptable":    ["group_drop_in", "private_session"],
    "class_kind_preferred":     "group_drop_in",
    "temperature_kind_acceptable": ["room_temp", "warm_studio"],
    "max_class_size":           20,
    "min_instructor_skill":     4,
    "props_required":           ["mat", "block", "strap"]
  },

  "preferences": {
    "studio_kind_acceptable":   ["dedicated_yoga_studio", "wellness_center", "fitness_with_yoga_floor"],
    "studio_kind_preferred":    "dedicated_yoga_studio",
    "instructor_gender_preference": "female",
    "instructor_min_experience_years": 3,
    "instructor_certifications_required": true,
    "instructor_certification_authority_acceptable": ["yoga_alliance_200", "yoga_alliance_500", "iyengar_institute", "traditional_gurukul"],
    "shower_required":          true,
    "locker_required":          true,
    "ac_or_fan_required":       true,
    "parking_required":         true,
    "music_during_class_kind":  "soft_instrumental",
    "single_gender_class_required": false,
    "budget_band":              "good",
    "budget_max_inr_total":      900,
    "online_payment_required":  true,
    "trial_first_class_optional": false
  },

  "context": { ... }
}
Field Type Constraint Notes
intent string REQUIRED, equals "lifestyle.book_yoga_class"
session_kind enum REQUIRED, see §5
user_yoga_profile.yoga_experience_level enum REQUIRED, see §5
user_yoga_profile.years_of_practice int REQUIRED, ≥0
user_yoga_profile.medical_conditions_disclosed array REQUIRED, may be empty see §5
user_yoga_profile.yoga_goals array REQUIRED, ≥1 see §5
user_yoga_profile.pregnant_or_postpartum enum REQUIRED, STRICT none | pregnant_t1 | pregnant_t2 | pregnant_t3 | postpartum_under_6mo | postpartum_over_6mo drives prenatal-yoga filter
yoga_intent.yoga_styles_acceptable array REQUIRED, ≥1 see §5
yoga_intent.yoga_style_preferred enum REQUIRED, see §5
yoga_intent.class_kind_acceptable array REQUIRED, ≥1 see §5
yoga_intent.temperature_kind_acceptable array REQUIRED, ≥1 see §5
yoga_intent.max_class_size int REQUIRED, ≥1
yoga_intent.min_instructor_skill int REQUIRED, 1-5
yoga_intent.props_required array REQUIRED, may be empty see §5
preferences.studio_kind_acceptable array REQUIRED, ≥1 see §5
preferences.instructor_certifications_required bool REQUIRED
preferences.instructor_certification_authority_acceptable array REQUIRED, ≥1 see §5
preferences.music_during_class_kind enum REQUIRED, see §5
preferences.trial_first_class_optional bool REQUIRED

REMOVED from lifestyle.book_gym_session §2:

  • gym-specific equipment intent (replaced by yoga_intent)
  • pool/sauna preferences (no relevance)
  • vegan_smoothie_bar (no relevance)

Anti-fabrication preamble (universal): no paid placement, no urgency text, no commission-influenced fields.


3. PROVIDER TOOLS

8 of 9 tools from lifestyle.book_salon §3 are REQUIRED, with SalonOption replaced by YogaClassOption. Implementations use yoga-specific terminology.


4. RESPONSE SHAPE (DELTA)

YogaClassOption

All fields from GymSessionOption §4 REQUIRED, REPLACING gym block with yoga_studio, equipment_and_classes_catalog with yoga_class_catalog. ADD yoga-specific blocks.

yoga_studio:
  id:                             string, REQUIRED
  merchant_id:                    string, REQUIRED
  name:                           string, REQUIRED
  brand:                          string, REQUIRED
  studio_kind:                    STRICT ENUM, REQUIRED         # see §5
  partner_account_age_days:       int, REQUIRED, ≥0
  total_classes_offered_30day:    int, REQUIRED, ≥0
  total_active_members:           int, REQUIRED, ≥0
  founded_year:                   int, REQUIRED                  # heritage signal
  yoga_lineage:                   STRICT ENUM, REQUIRED          # see §5

  address:                        # same shape as gym
    line_1:                       string, REQUIRED
    neighborhood:                 string, REQUIRED
    city:                         string, REQUIRED
    pincode:                      string, REQUIRED
    lat:                          float, REQUIRED
    lng:                          float, REQUIRED
    google_place_id:              string, REQUIRED
    landmark:                     string, REQUIRED

  distance_from_user_km:          float, REQUIRED

  ratings:
    overall_score:                float, REQUIRED, 0-5
    overall_count:                int, REQUIRED, ≥0
    recent_30day_score:           float, REQUIRED, 0-5
    cleanliness_score:            float, REQUIRED, 0-5
    instructor_skill_score:       float, REQUIRED, 0-5
    ambience_score:               float, REQUIRED, 0-5
    on_time_30day_pct:            float, REQUIRED, 0-1

  operating_hours:                # same as gym
    is_open_now:                  boolean, REQUIRED
    next_open_iso:                ISO_DATETIME, REQUIRED
    next_close_iso:               ISO_DATETIME, REQUIRED
    is_24x7:                      boolean, REQUIRED
    hours_of_operation:           array, REQUIRED, 7 entries

  amenities:
    air_conditioning:             boolean, REQUIRED
    fan_only:                     boolean, REQUIRED
    natural_lighting:             boolean, REQUIRED
    showers_count:                int, REQUIRED, ≥0
    showers_with_hot_water:       boolean, REQUIRED
    lockers_count:                int, REQUIRED, ≥0
    locker_secure_lock:           boolean, REQUIRED
    changing_rooms_count:         int, REQUIRED, ≥0
    parking_available:            boolean, REQUIRED
    parking_kind:                 STRICT ENUM, REQUIRED
    drinking_water_filtered:      boolean, REQUIRED
    quiet_zone_strict:            boolean, REQUIRED
    silent_meditation_room:       boolean, REQUIRED
    studio_floor_kind:            STRICT ENUM, REQUIRED          # see §5
    floor_anti_slip:              boolean, REQUIRED
    cctv_in_premises:             boolean, REQUIRED
    panic_button_at_floor:        boolean, REQUIRED
    wheelchair_accessible:        boolean, REQUIRED
    childcare_available:          boolean, REQUIRED
    female_only_class_hours_available: boolean, REQUIRED
    male_only_class_hours_available:   boolean, REQUIRED

  trust:
    municipal_license_number:     string, REQUIRED
    municipal_license_valid_until: ISO_DATE, REQUIRED
    safety_audit_iso:             ISO_DATETIME, REQUIRED
    safety_audit_score:           int, REQUIRED, 0-100
    employee_kyc_pct:             int, REQUIRED, 0-100
    insurance_coverage_inr:       INR_INTEGER, REQUIRED
    aed_defibrillator_present:    boolean, REQUIRED
    first_aid_kit_present:        boolean, REQUIRED
    fire_safety_compliant:        boolean, REQUIRED
    tomo_field_team_audited:      boolean, REQUIRED

  photos:
    thumbnail_url:                URL, REQUIRED
    hero_url:                     URL, REQUIRED
    studio_floor_photos_url:      URL, REQUIRED
    instructors_photos_url:       URL, REQUIRED
    ai_generated_photos:          boolean, REQUIRED              # MUST be false

yoga_class_catalog:               array<YogaClassItem>, REQUIRED, ≥1

available_slots:                  array<YogaSlotOption>, REQUIRED, ≥1

instructors:                      array<YogaInstructorProfile>, REQUIRED, ≥1

session_pass:
  pass_kind:                      STRICT ENUM, REQUIRED          # see §5
  pass_inr:                       INR_INTEGER, REQUIRED
  pass_includes:                  array<STRICT ENUM>, REQUIRED, ≥1
  props_included:                 boolean, REQUIRED
  shower_included:                boolean, REQUIRED
  validity_days:                  int, REQUIRED, ≥1

# (all standard fields - fare, cancellation, freshness, _provider - REQUIRED)

YogaClassItem

class_id:                         string, REQUIRED
yoga_style:                       STRICT ENUM, REQUIRED         # see §5
class_name:                       string, REQUIRED              # "Iyengar Foundations"
description:                      string, REQUIRED              # ≥80 chars
class_kind:                       STRICT ENUM, REQUIRED         # see §5
duration_minutes:                 int, REQUIRED, ≥30
difficulty_level:                 STRICT ENUM, REQUIRED         # beginner | intermediate | advanced | mixed
class_size_max:                   int, REQUIRED, ≥1
class_size_typical:               int, REQUIRED, ≥1
temperature_kind:                 STRICT ENUM, REQUIRED         # see §5
props_provided:                   array<STRICT ENUM>, REQUIRED  # see §5
prenatal_friendly:                boolean, REQUIRED
postpartum_friendly:              boolean, REQUIRED
back_pain_friendly:               boolean, REQUIRED
photo_url:                        URL, REQUIRED
photo_ai_generated:               boolean, REQUIRED              # MUST be false
recurring_schedule:               array, REQUIRED, may be empty
  - day_of_week:                  STRICT ENUM, REQUIRED
    start_iso_time:               string, REQUIRED

YogaInstructorProfile

(Subset of TrainerProfile — adapted to yoga. All fields REQUIRED.)

instructor_id:                    string, REQUIRED
display_name:                     string, REQUIRED
photo_url:                        URL, REQUIRED
photo_ai_generated:               boolean, REQUIRED              # MUST be false
gender:                           STRICT ENUM, REQUIRED
age_band:                         STRICT ENUM, REQUIRED
experience_years:                 int, REQUIRED, ≥0
years_of_personal_practice:       int, REQUIRED, ≥0              # additional yoga-specific signal
specializations:                  array<STRICT ENUM>, REQUIRED, ≥1   # see §5
certifications:                   array<STRICT ENUM>, REQUIRED, may be empty
certifying_authorities:           array<STRICT ENUM>, REQUIRED, may be empty
trained_in_lineage:               STRICT ENUM, REQUIRED          # see §5
languages_spoken:                 array<RFC_3066_LOCALE>, REQUIRED, ≥1
ratings:
  rating_avg:                     float, REQUIRED, 0-5
  rating_count:                   int, REQUIRED, ≥0
  classes_taught_total:           int, REQUIRED, ≥0
  classes_taught_30day:           int, REQUIRED, ≥0
kyc:
  aadhaar_verified:               boolean, REQUIRED
  pan_verified:                   boolean, REQUIRED
  background_check_passed:        boolean, REQUIRED
  background_check_iso:           ISO_DATETIME, REQUIRED
employed_kind:                    STRICT ENUM, REQUIRED
private_session_inr:              INR_INTEGER, REQUIRED          # for 1-on-1

YogaSlotOption

(Same shape as GymSlotOption from lifestyle.book_gym_session §4 — class_id mandatory here, instructor_id_assigned mandatory.)

Forbidden fields

paid_placement_score | sponsored_rank | promotion_priority |
fake_recent_class_text | auto_inflate_class_count |
ai_generated_photos (must equal false) | hidden_pass_fee |
fake_certifications | fake_yoga_lineage_claim |
fake_partner_completion_rate_30d

5. CONTROLLED VOCABULARIES (DELTA)

session_kind

drop_in_class | trial_class | private_session | guest_pass |
themed_workshop | retreat_intro

studio_kind

dedicated_yoga_studio | wellness_center | fitness_with_yoga_floor |
ashram_or_traditional | celebrity_brand | franchise_chain |
home_studio_certified

yoga_lineage

iyengar | ashtanga | bks_iyengar_lineage | sivananda | kundalini |
hatha_traditional | vinyasa_modern | krishnamacharya | partner_method | mixed

user_yoga_profile.yoga_experience_level

beginner | novice | intermediate | advanced | teacher_level

user_yoga_profile.medical_conditions_disclosed[]

hypertension | diabetes | heart_condition | back_pain | knee_problem |
shoulder_problem | hernia | arthritis | recent_surgery | pregnancy |
postpartum | other | none | mild_back_pain

user_yoga_profile.yoga_goals[]

flexibility | strength | stress_reduction | meditation | weight_loss |
posture | back_pain_relief | better_sleep | spiritual | athletic_recovery |
prenatal_wellness | postpartum_recovery

user_yoga_profile.pregnant_or_postpartum

none | pregnant_t1 | pregnant_t2 | pregnant_t3 |
postpartum_under_6mo | postpartum_over_6mo

yoga_intent.yoga_styles_acceptable[] and YogaClassItem.yoga_style

hatha | vinyasa | iyengar | ashtanga | kundalini | yin |
restorative | power_yoga | hot_yoga | bikram | jivamukti |
sivananda | aerial_yoga | aqua_yoga | chair_yoga | prenatal |
postpartum | meditative | mantra | bhakti

yoga_intent.class_kind_acceptable[] and YogaClassItem.class_kind

group_drop_in | private_session | group_themed_workshop |
silent_class | special_intro | beginners_only | advanced_only |
prenatal_class | postpartum_class | seniors_class | kids_class

yoga_intent.temperature_kind_acceptable[] and YogaClassItem.temperature_kind

room_temp | warm_studio | hot_yoga_40c | cool_studio

yoga_intent.props_required[] and YogaClassItem.props_provided[]

mat | block | strap | bolster | blanket | wheel | chair |
wall_ropes | suspension_strap | meditation_cushion

studio.studio_floor_kind

hardwood | bamboo | sprung_floor | rubber_mat_carpet | concrete_with_mats

studio.amenities.parking_kind

Same enum as lifestyle.book_gym_session §5.

session_pass.pass_kind

single_class | trial_class | guest_pass | private_with_instructor |
weekly_unlimited | monthly_drop_in_pack

session_pass.pass_includes[]

class_attendance | props_use | shower_access | locker_access |
post_class_meditation | herbal_tea | cooling_towel

YogaInstructorProfile.specializations[]

hatha_specialist | vinyasa_specialist | iyengar_certified |
ashtanga_certified | kundalini_certified | prenatal_certified |
postpartum_certified | yin_specialist | meditation_teacher |
mantra_chanting | sanskrit_teacher | senior_yoga_specialist |
back_pain_rehab_yoga

YogaInstructorProfile.certifications[]

yoga_alliance_200 | yoga_alliance_500 | yoga_alliance_eryt |
iyengar_introductory | iyengar_intermediate | iyengar_senior |
ashtanga_authorized | ashtanga_certified | sivananda_ttc |
art_of_living_yoga | krishnamacharya_yoga_mandiram |
state_yoga_council_cert | partner_internal_cert

YogaInstructorProfile.certifying_authorities[]

yoga_alliance | iyengar_institute | sri_k_pattabhi_jois |
sivananda_lineage | art_of_living | kym_lineage |
state_yoga_council | aytm_authority | partner_internal

YogaInstructorProfile.trained_in_lineage

iyengar | ashtanga | sivananda | kundalini | hatha_traditional |
vinyasa_modern | krishnamacharya | partner_method | mixed

YogaInstructorProfile.gender, age_band, employed_kind

Same as lifestyle.book_gym_session §5.

preferences.music_during_class_kind

silent | mantra | soft_instrumental | classical | nature_sounds | bowls

cancel_appointment.reason

Same as lifestyle.book_salon §5.


6. TTBS DIMENSIONS (DELTA)

Per-domain weights

lifestyle (book_yoga_class): { time: 0.30, taste: 0.40, budget: 0.20, safety: 0.10 }

TIME

Same as lifestyle.book_gym_session §6.

TASTE (override)

SIGNALS USED:
  - studio.ratings.instructor_skill_score             weight 0.25
  - studio.ratings.recent_30day_score                 weight 0.15
  - instructor specializations match yoga_style       weight 0.20
  - instructor.certifications in user-acceptable list weight 0.20
  - studio.yoga_lineage match user-style              weight 0.10
  - props_required satisfied by class                 weight 0.10

HARD FILTERS:
  - yoga_style not in YogaClassItem.yoga_style → drop
  - prenatal_friendly required AND class.prenatal_friendly=false
  - postpartum_friendly required AND class.postpartum_friendly=false
  - difficulty_level mismatch with user.yoga_experience_level (extreme gap)
  - pregnant_t3 AND no special prenatal class → drop entire studio
  - back_pain disclosed AND back_pain_friendly=false → drop

BUDGET

Same as lifestyle.book_gym_session §6.

SAFETY

SIGNALS USED:
  - studio.trust.first_aid_kit_present                HARD FILTER
  - studio.trust.fire_safety_compliant                HARD FILTER
  - studio.trust.aed_defibrillator_present            weight 0.20
  - instructor.kyc.background_check_passed            HARD FILTER
  - studio.trust.safety_audit_score                   weight 0.20
  - studio.amenities.cctv_in_premises                 weight 0.10
  - studio.amenities.panic_button_at_floor            weight 0.10
  - certified instructor (Yoga Alliance ≥200hr or equivalent) HARD FILTER for advanced classes
  - prenatal class instructor must have prenatal cert  HARD FILTER

Hidden ranking factor

information_completeness_score weight 0.10.


7. COMPLETION CONTRACT

POST /api/v1/cpc/mcp_provider/{tomo_partner_id}
{
  "intent":            "lifestyle.book_yoga_class",
  "intent_version":    "v1.0.0",
  "external_id":       "YOGA-XYZ",
  "amount_inr":         750,
  "closed_at":         "2026-05-12T07:14:00+05:30",
  "request_id":        "req_yoga_8h2k_...",
  "status":            "completed",
  "appointment_ref":   "YOGA-XYZ",
  "yoga_studio_id":    "studio_8423",
  "instructor_id":     "instructor_xyz",
  "class_id":          "iyengar_foundations_morning",
  "started_at":        "2026-05-12T06:02:00+05:30",
  "ended_at":          "2026-05-12T07:00:00+05:30",
  "duration_actual_minutes": 58,
  "user_arrived_late_minutes": 2,
  "props_used":        ["mat", "block", "strap"],
  "currency":          "INR",
  "fare_breakdown_total_inr": 750,
  "rider_tip_inr":       100,
  "ratings_pending":     true,
  "notes":              ""
}

Status enum: completed | cancelled_by_user | cancelled_by_studio | no_show | failed | partial_completion_user_left_early | medical_event_class_halted


8. WIDGET, 9. CACHING, 10. ERROR CODES, 11. CHECKLIST

(All inherit shape from lifestyle.book_gym_session §8-11. Widget type: yoga_class_options. Class kinds and yoga-style filtering replace gym filtering. Add prenatal-class HARD FILTER to error codes.)


12. ANTI-FABRICATION RULES

All rules from lifestyle.book_salon §12 + lifestyle.book_gym_session §12 REQUIRED. ADD:

RULE 17 — Yoga lineage claim real.
  yoga_lineage=iyengar requires verifiable lineage to BKS Iyengar tradition
  (Iyengar Institute cert or documented teacher chain). Marketing-as-lineage
  without authority = breach.

RULE 18 — Instructor cert real.
  Yoga Alliance 200/500hr cert claim requires active YA registration.
  Lapsed cert claimed as current = breach.

RULE 19 — Prenatal certification non-negotiable.
  Prenatal class instructor without prenatal-specific cert = severe breach
  + pregnancy safety hazard.

RULE 20 — Class size honest.
  class_size_typical reflects average attended count. Inflating to claim
  intimacy then crowding = breach.

RULE 21 — Hot yoga temperature accurate.
  hot_yoga_40c claim = thermometer-verifiable 38-42°C. Lower temp claimed
  as hot = breach + heat-stress safety concern.

RULE 22 — Props condition honored.
  Props provided must be hygienic, undamaged. Charging full price for class
  with broken/dirty props = breach.

RULE 23 — No bait-and-switch instructor.
  Headline instructor in marketing must teach the booked class for ≥80% of
  scheduled sessions. Frequent substitution = breach.

RULE 24 — Medical disclosure honored.
  User discloses condition; class HARD FILTER ensures appropriate class.
  Letting back-pain user into power yoga without warning = severe breach.

VERSION HISTORY

v1.0.0 — 2026-05-10 — Initial spec (delta over lifestyle.book_gym_session, yoga adaptation)