openapi: 3.0.3
info:
  title: THC Open Mindfulness Resources API
  version: "1.0.0"
  description: >
    A free, public, read-only REST API exposing The Holistic Care's open
    mindfulness resources: research citations (whitepapers) and a
    plain-language glossary. No authentication required.
  contact:
    name: The Holistic Care
    url: https://www.theholisticcare.com
    email: mohan@theholisticcare.com
servers:
  - url: https://api.theholisticcare.com/v1
paths:
  /whitepapers:
    get:
      summary: List research citations
      parameters:
        - $ref: '#/components/parameters/limit'
        - $ref: '#/components/parameters/offset'
        - name: topic
          in: query
          schema:
            type: string
            enum: [mindfulness, meditation, yoga, sleep, nonduality, children, anxiety, physiology]
        - name: study_type
          in: query
          schema:
            type: string
            enum: [rct, meta-analysis, observational, cohort, clinical-trial, physiological, guideline]
      responses:
        '200':
          description: A paginated list of research citations.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CitationListResponse'
        '429':
          $ref: '#/components/responses/RateLimited'
  /whitepapers/{slug}:
    get:
      summary: Get a single research citation by slug
      parameters:
        - $ref: '#/components/parameters/slug'
      responses:
        '200':
          description: A single research citation.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CitationDetailResponse'
        '404':
          $ref: '#/components/responses/NotFound'
        '429':
          $ref: '#/components/responses/RateLimited'
  /glossary:
    get:
      summary: List glossary terms
      parameters:
        - $ref: '#/components/parameters/limit'
        - $ref: '#/components/parameters/offset'
        - name: pillar
          in: query
          schema:
            type: string
            enum: [nonduality, yoga, meditation, kundalini, ayurveda, general-wisdom]
      responses:
        '200':
          description: A paginated list of glossary terms.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GlossaryListResponse'
        '429':
          $ref: '#/components/responses/RateLimited'
  /glossary/{slug}:
    get:
      summary: Get a single glossary term by slug
      parameters:
        - $ref: '#/components/parameters/slug'
      responses:
        '200':
          description: A single glossary term.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GlossaryDetailResponse'
        '404':
          $ref: '#/components/responses/NotFound'
        '429':
          $ref: '#/components/responses/RateLimited'
  /mindfulness-games:
    get:
      summary: List free mindfulness games
      parameters:
        - $ref: '#/components/parameters/limit'
        - $ref: '#/components/parameters/offset'
        - name: audience
          in: query
          schema:
            type: string
            enum: [children, teens, adults, educators, parents]
        - name: skill
          in: query
          schema:
            type: string
            enum: [attention, body-awareness, breathwork, cognitive-reframing, emotional-regulation, gratitude, grounding, loving-kindness, mindful-listening, nondual-awareness, relaxation, self-compassion, sleep]
      responses:
        '200':
          description: A paginated list of mindfulness games.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GameListResponse'
        '429':
          $ref: '#/components/responses/RateLimited'
  /mindfulness-games/{slug}:
    get:
      summary: Get a single mindfulness game by slug
      parameters:
        - $ref: '#/components/parameters/slug'
      responses:
        '200':
          description: A single mindfulness game.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GameDetailResponse'
        '404':
          $ref: '#/components/responses/NotFound'
        '429':
          $ref: '#/components/responses/RateLimited'
  /practices:
    get:
      summary: List free guided-audio practices (Stillness Library)
      description: >
        Free tracks only. The Stillness Library also has paid tracks; those are
        never exposed by this API.
      parameters:
        - $ref: '#/components/parameters/limit'
        - $ref: '#/components/parameters/offset'
        - name: category
          in: query
          schema:
            type: string
            enum: [mindfulness, children, breathwork, nondual-awareness, yoga-nidra, students, sleep]
      responses:
        '200':
          description: A paginated list of free practices.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PracticeListResponse'
        '429':
          $ref: '#/components/responses/RateLimited'
  /practices/{slug}:
    get:
      summary: Get a single free practice by slug
      parameters:
        - $ref: '#/components/parameters/slug'
      responses:
        '200':
          description: A single free practice.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PracticeDetailResponse'
        '404':
          $ref: '#/components/responses/NotFound'
        '429':
          $ref: '#/components/responses/RateLimited'
  /categories:
    get:
      summary: List the current valid topic/pillar filter values
      responses:
        '200':
          description: Distinct topics and pillars currently in use.
          content:
            application/json:
              schema:
                type: object
components:
  parameters:
    limit:
      name: limit
      in: query
      schema:
        type: integer
        default: 20
        maximum: 100
    offset:
      name: offset
      in: query
      schema:
        type: integer
        default: 0
    slug:
      name: slug
      in: path
      required: true
      schema:
        type: string
  responses:
    NotFound:
      description: No public record exists at that slug.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    RateLimited:
      description: Too many requests from this IP recently.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
  schemas:
    Error:
      type: object
      properties:
        error:
          type: object
          properties:
            code:
              type: string
            message:
              type: string
    Pagination:
      type: object
      properties:
        limit:
          type: integer
        offset:
          type: integer
        total:
          type: integer
    Citation:
      type: object
      properties:
        id:
          type: string
        slug:
          type: string
        type:
          type: string
          enum: [research_citation]
        title:
          type: string
        authors:
          type: string
        year:
          type: integer
        journal:
          type: string
        study_type:
          type: string
        sample_size:
          type: string
        topic:
          type: string
        summary:
          type: string
        key_finding:
          type: string
        limitations:
          type: string
        source_url:
          type: string
        updated_at:
          type: string
          format: date-time
    CitationListResponse:
      type: object
      properties:
        data:
          type: array
          items:
            $ref: '#/components/schemas/Citation'
        pagination:
          $ref: '#/components/schemas/Pagination'
    CitationDetailResponse:
      type: object
      properties:
        data:
          $ref: '#/components/schemas/Citation'
    GlossaryTerm:
      type: object
      properties:
        id:
          type: string
        slug:
          type: string
        type:
          type: string
          enum: [glossary_term]
        title:
          type: string
        pillar:
          type: string
        summary:
          type: string
        etymology:
          type: string
        also_known_as:
          type: array
          items:
            type: string
        updated_at:
          type: string
          format: date-time
    GlossaryListResponse:
      type: object
      properties:
        data:
          type: array
          items:
            $ref: '#/components/schemas/GlossaryTerm'
        pagination:
          $ref: '#/components/schemas/Pagination'
    GlossaryDetailResponse:
      type: object
      properties:
        data:
          $ref: '#/components/schemas/GlossaryTerm'
    Game:
      type: object
      properties:
        id:
          type: string
        slug:
          type: string
        type:
          type: string
          enum: [mindfulness_game]
        api_id:
          type: string
        title:
          type: string
        url:
          type: string
        icon:
          type: string
        tag:
          type: string
        description:
          type: string
        free:
          type: boolean
        keywords:
          type: array
          items:
            type: string
        audiences:
          type: array
          items:
            type: string
        age_min:
          type: integer
        age_max:
          type: integer
        duration_minutes:
          type: integer
        skills:
          type: array
          items:
            type: string
        updated_at:
          type: string
          format: date-time
    GameListResponse:
      type: object
      properties:
        data:
          type: array
          items:
            $ref: '#/components/schemas/Game'
        pagination:
          $ref: '#/components/schemas/Pagination'
    GameDetailResponse:
      type: object
      properties:
        data:
          $ref: '#/components/schemas/Game'
    Practice:
      type: object
      properties:
        id:
          type: string
        slug:
          type: string
        type:
          type: string
          enum: [practice]
        track_id:
          type: string
        title:
          type: string
        category:
          type: string
        excerpt:
          type: string
        audio_url:
          type: string
        read_time_minutes:
          type: integer
        canonical_url:
          type: string
        updated_at:
          type: string
          format: date-time
    PracticeListResponse:
      type: object
      properties:
        data:
          type: array
          items:
            $ref: '#/components/schemas/Practice'
        pagination:
          $ref: '#/components/schemas/Pagination'
    PracticeDetailResponse:
      type: object
      properties:
        data:
          $ref: '#/components/schemas/Practice'
