openapi: 3.1.0
info:
  title: Kissan Ki Pehchan API
  version: 0.2.0-blueprint
  description: >
    Provider-neutral reference API for the controlled live audio-video agricultural consultation pilot.
    All examples are fictional and not agricultural advice.
servers:
  - url: https://api.example.gov.pk
    description: Illustrative production endpoint
security:
  - bearerAuth: []
paths:
  /v1/cases:
    post:
      summary: Create a case
      operationId: createCase
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [language, consent_version]
              properties:
                farmer_id: {type: string, nullable: true}
                language: {type: string, example: ur-PK}
                consent_version: {type: string}
                crop_context: {type: object}
                location_context: {type: object}
      responses:
        '201':
          description: Case created
          content:
            application/json:
              schema:
                $ref: './schemas/case-state.schema.json'
  /v1/cases/{case_id}:
    get:
      summary: Read a case
      operationId: getCase
      parameters:
        - $ref: '#/components/parameters/CaseId'
      responses:
        '200':
          description: Current case state
          content:
            application/json:
              schema:
                $ref: './schemas/case-state.schema.json'
  /v1/cases/{case_id}/live-sessions:
    post:
      summary: Create a live WebRTC consultation session
      operationId: createLiveSession
      parameters:
        - $ref: '#/components/parameters/CaseId'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [consent_version]
              properties:
                consent_version: {type: string}
                requested_media_mode:
                  type: string
                  enum: [FULL_VIDEO, REDUCED_VIDEO, AUDIO_WITH_STILLS]
      responses:
        '201':
          description: Session and short-lived room token created
          content:
            application/json:
              schema:
                type: object
                properties:
                  session: {$ref: './schemas/live-session.schema.json'}
                  room_token: {type: string}
                  room_url: {type: string, format: uri}
  /v1/live-sessions/{session_id}:
    get:
      summary: Read live consultation state
      operationId: getLiveSession
      parameters:
        - name: session_id
          in: path
          required: true
          schema: {type: string}
      responses:
        '200':
          description: Current live session
          content:
            application/json:
              schema:
                $ref: './schemas/live-session.schema.json'
  /v1/live-sessions/{session_id}/frames:
    post:
      summary: Register a selected live frame or explicit still
      operationId: registerLiveFrame
      parameters:
        - name: session_id
          in: path
          required: true
          schema: {type: string}
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [frame_id, captured_at, capture_objective, quality]
              properties:
                frame_id: {type: string}
                captured_at: {type: string, format: date-time}
                capture_objective: {type: string}
                quality: {type: object}
                object_uri: {type: string}
                content_hash: {type: string}
      responses:
        '202': {description: Frame accepted for evidence processing}
  /v1/live-sessions/{session_id}/join-requests:
    post:
      summary: Request an officer join or warm handoff
      operationId: requestOfficerJoin
      parameters:
        - name: session_id
          in: path
          required: true
          schema: {type: string}
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [reason, urgency]
              properties:
                reason: {type: string}
                urgency: {type: string, enum: [routine, urgent, critical]}
                handoff_mode: {type: string, enum: [join_assist, warm_handoff]}
      responses:
        '202': {description: Join request queued}
  /v1/cases/{case_id}/turns:
    post:
      summary: Submit farmer text or transcript turn
      operationId: addTurn
      parameters:
        - $ref: '#/components/parameters/CaseId'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [text, language]
              properties:
                text: {type: string}
                language: {type: string}
                source: {type: string, enum: [typed, stt_final, officer]}
                stt_metadata: {type: object}
      responses:
        '202': {description: Turn accepted}
  /v1/cases/{case_id}/media:
    post:
      summary: Register and upload case media
      operationId: addMedia
      parameters:
        - $ref: '#/components/parameters/CaseId'
      requestBody:
        required: true
        content:
          multipart/form-data:
            schema:
              type: object
              required: [file, media_role]
              properties:
                file: {type: string, format: binary}
                media_role:
                  type: string
                  enum: [whole_plant, affected_area, front, underside, close_up, field_wide, short_video, explicit_live_still]
      responses:
        '202': {description: Media accepted for validation}
  /v1/cases/{case_id}/analyse:
    post:
      summary: Run or resume the evidence and reasoning workflow
      operationId: analyseCase
      parameters:
        - $ref: '#/components/parameters/CaseId'
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                mode:
                  type: string
                  enum: [normal, local_only, deep_research, shadow]
                research_budget:
                  type: object
                  properties:
                    max_queries: {type: integer, minimum: 0, maximum: 20}
                    max_seconds: {type: integer, minimum: 1, maximum: 600}
      responses:
        '200':
          description: Structured analysis or next action
          content:
            application/json:
              schema:
                $ref: './schemas/diagnosis.schema.json'
  /v1/research/search:
    post:
      summary: Search controlled external and internal sources
      operationId: researchSearch
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [case_id, questions]
              properties:
                case_id: {type: string}
                questions:
                  type: array
                  items: {type: string}
                source_policy:
                  type: string
                  enum: [local_only, authoritative_web, scholarly, mixed]
                max_results: {type: integer, minimum: 1, maximum: 50}
      responses:
        '200':
          description: Assessed research sources
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: './schemas/research-source.schema.json'
  /v1/policy/validate:
    post:
      summary: Validate exact treatment or regulatory claims
      operationId: validatePolicy
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [case_id, request]
              properties:
                case_id: {type: string}
                request: {type: object}
      responses:
        '200':
          description: Policy result
          content:
            application/json:
              schema:
                $ref: './schemas/policy-decision.schema.json'
  /v1/escalations:
    post:
      summary: Create a human-review escalation
      operationId: createEscalation
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: './schemas/escalation.schema.json'
      responses:
        '201':
          description: Escalation created
          content:
            application/json:
              schema:
                $ref: './schemas/escalation.schema.json'
  /v1/escalations/{escalation_id}/decision:
    post:
      summary: Record a reviewer decision
      operationId: decideEscalation
      parameters:
        - name: escalation_id
          in: path
          required: true
          schema: {type: string}
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [decision, rationale]
              properties:
                decision:
                  type: string
                  enum: [approve, amend, request_evidence, reject, escalate, out_of_scope]
                rationale: {type: string}
                response_text: {type: string}
                policy_result_ids:
                  type: array
                  items: {type: string}
      responses:
        '200': {description: Decision recorded}
  /health:
    get:
      security: []
      summary: Service health
      operationId: health
      responses:
        '200':
          description: Health status
          content:
            application/json:
              schema:
                type: object
                properties:
                  status: {type: string, enum: [ok, degraded]}
                  dependencies: {type: object}
components:
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT
  parameters:
    CaseId:
      name: case_id
      in: path
      required: true
      schema: {type: string}
