swagger: '2.0'
info:
  title: HealyNG Telemedicine API
  description: |2

    # HealyNG Telemedicine Platform API

    AI-powered telemedicine platform for Africa (Nigeria-first).

    ## Authentication
    All API endpoints require JWT authentication. Include the token in the Authorization header:
    ```
    Authorization: Bearer <your-token>
    ```

    ## Versioning
    Current API version: **v1**

    ## Rate Limiting
    API requests are rate-limited. Check response headers for rate limit information.

    ## Error Responses
    All errors follow a consistent format:
    ```json
    {
        "error": "Error code",
        "message": "Human-readable error message",
        "details": {}
    }
    ```

    ## Common Status Codes
    - `200 OK` - Request successful
    - `201 Created` - Resource created
    - `400 Bad Request` - Invalid request data
    - `401 Unauthorized` - Authentication required
    - `403 Forbidden` - Insufficient permissions
    - `404 Not Found` - Resource not found
    - `429 Too Many Requests` - Rate limit exceeded
    - `500 Internal Server Error` - Server error

    ## Healthcare Compliance
    This API handles Protected Health Information (PHI) and complies with:
    - NDPR (Nigeria Data Protection Regulation)
    - HIPAA (for US operations)

    All medical data is encrypted at rest and in transit.
  termsOfService: https://healy.ng/terms/
  contact:
    name: HealyNG Support
    url: https://healy.ng/support
    email: support@healy.ng
  license:
    name: Proprietary
    url: https://healy.ng/license
  version: v1
host: api.healy.ng
schemes:
- https
basePath: /api
consumes:
- application/json
produces:
- application/json
securityDefinitions:
  Bearer:
    type: apiKey
    name: Authorization
    in: header
    description: 'JWT Authorization header using the Bearer scheme. Example: ''Authorization:
      Bearer {token}'''
security:
- Bearer: []
paths:
  /ai/:
    get:
      operationId: ai_list
      description: List all available AI tools and their endpoints.
      parameters: []
      responses:
        '200':
          description: ''
      tags:
      - ai
    parameters: []
  /ai/appointment/{appointment_id}/predictive/:
    get:
      operationId: ai_appointment_predictive_list
      description: List predictive assessments for the patient linked to this appointment
        (provider/owner/admin).
      parameters: []
      responses:
        '200':
          description: ''
      tags:
      - ai
    parameters:
    - name: appointment_id
      in: path
      required: true
      type: string
  /ai/appointment/{appointment_id}/predictive/assess/:
    post:
      operationId: ai_appointment_predictive_assess_create
      description: Run predictive analytics for the patient linked to this appointment.
      parameters: []
      responses:
        '201':
          description: ''
      tags:
      - ai
    parameters:
    - name: appointment_id
      in: path
      required: true
      type: string
  /ai/appointment/{appointment_id}/triage/:
    get:
      operationId: ai_appointment_triage_list
      description: List triage assessments for the patient linked to this appointment
        (provider/owner/admin).
      parameters: []
      responses:
        '200':
          description: ''
      tags:
      - ai
    parameters:
    - name: appointment_id
      in: path
      required: true
      type: string
  /ai/appointment/{appointment_id}/triage/assess/:
    post:
      operationId: ai_appointment_triage_assess_create
      description: 'Run AI triage for the patient linked to this appointment. Body:
        symptoms, age?, gender?, additional_info?.'
      parameters: []
      responses:
        '201':
          description: ''
      tags:
      - ai
    parameters:
    - name: appointment_id
      in: path
      required: true
      type: string
  /ai/predictive/assess/:
    post:
      operationId: ai_predictive_assess_create
      description: |-
        Run AI predictive analytics for a patient. Uses medical history, conditions,
        medications, allergies, vitals to predict health risks, disease progression,
        and complications. Patient: own data. Provider: pass patient_id.
      parameters: []
      responses:
        '201':
          description: ''
      tags:
      - ai
    parameters: []
  /ai/predictive/my-assessments/:
    get:
      operationId: ai_predictive_my-assessments_list
      description: Get current user's predictive assessments (patient only).
      parameters: []
      responses:
        '200':
          description: ''
      tags:
      - ai
    parameters: []
  /ai/triage/assess/:
    post:
      operationId: ai_triage_assess_create
      description: AI-powered symptom assessment. Allows anonymous access.
      parameters: []
      responses:
        '201':
          description: ''
      tags:
      - ai
    parameters: []
  /ai/triage/my-assessments/:
    get:
      operationId: ai_triage_my-assessments_list
      description: Get current user's triage assessments.
      parameters: []
      responses:
        '200':
          description: ''
      tags:
      - ai
    parameters: []
  /appointments/:
    get:
      operationId: appointments_list
      description: List and create appointments.
      parameters:
      - name: search
        in: query
        description: A search term.
        required: false
        type: string
      - name: ordering
        in: query
        description: Which field to use when ordering the results.
        required: false
        type: string
      - name: page
        in: query
        description: A page number within the paginated result set.
        required: false
        type: integer
      - name: page_size
        in: query
        description: Number of results to return per page.
        required: false
        type: integer
      responses:
        '200':
          description: ''
          schema:
            required:
            - count
            - results
            type: object
            properties:
              count:
                type: integer
              next:
                type: string
                format: uri
                x-nullable: true
              previous:
                type: string
                format: uri
                x-nullable: true
              results:
                type: array
                items:
                  $ref: '#/definitions/Appointment'
      tags:
      - appointments
    post:
      operationId: appointments_create
      description: List and create appointments.
      parameters:
      - name: data
        in: body
        required: true
        schema:
          $ref: '#/definitions/Appointment'
      responses:
        '201':
          description: ''
          schema:
            $ref: '#/definitions/Appointment'
      tags:
      - appointments
    parameters: []
  /appointments/slots/:
    get:
      operationId: appointments_slots_list
      description: List and create appointment slots for providers.
      parameters:
      - name: search
        in: query
        description: A search term.
        required: false
        type: string
      - name: ordering
        in: query
        description: Which field to use when ordering the results.
        required: false
        type: string
      - name: page
        in: query
        description: A page number within the paginated result set.
        required: false
        type: integer
      - name: page_size
        in: query
        description: Number of results to return per page.
        required: false
        type: integer
      responses:
        '200':
          description: ''
          schema:
            required:
            - count
            - results
            type: object
            properties:
              count:
                type: integer
              next:
                type: string
                format: uri
                x-nullable: true
              previous:
                type: string
                format: uri
                x-nullable: true
              results:
                type: array
                items:
                  $ref: '#/definitions/AppointmentSlot'
      tags:
      - appointments
    post:
      operationId: appointments_slots_create
      description: List and create appointment slots for providers.
      parameters:
      - name: data
        in: body
        required: true
        schema:
          $ref: '#/definitions/AppointmentSlot'
      responses:
        '201':
          description: ''
          schema:
            $ref: '#/definitions/AppointmentSlot'
      tags:
      - appointments
    parameters: []
  /appointments/slots/{id}/:
    get:
      operationId: appointments_slots_read
      description: Detail view for appointment slots.
      parameters: []
      responses:
        '200':
          description: ''
          schema:
            $ref: '#/definitions/AppointmentSlot'
      tags:
      - appointments
    put:
      operationId: appointments_slots_update
      description: Detail view for appointment slots.
      parameters:
      - name: data
        in: body
        required: true
        schema:
          $ref: '#/definitions/AppointmentSlot'
      responses:
        '200':
          description: ''
          schema:
            $ref: '#/definitions/AppointmentSlot'
      tags:
      - appointments
    patch:
      operationId: appointments_slots_partial_update
      description: Detail view for appointment slots.
      parameters:
      - name: data
        in: body
        required: true
        schema:
          $ref: '#/definitions/AppointmentSlot'
      responses:
        '200':
          description: ''
          schema:
            $ref: '#/definitions/AppointmentSlot'
      tags:
      - appointments
    delete:
      operationId: appointments_slots_delete
      description: Detail view for appointment slots.
      parameters: []
      responses:
        '204':
          description: ''
      tags:
      - appointments
    parameters:
    - name: id
      in: path
      required: true
      type: string
  /appointments/slots/{provider_id}/:
    get:
      operationId: appointments_slots_read
      description: Get available appointment slots for a provider.
      parameters: []
      responses:
        '200':
          description: ''
      tags:
      - appointments
    parameters:
    - name: provider_id
      in: path
      required: true
      type: string
  /appointments/{id}/:
    get:
      operationId: appointments_read
      description: Detail view for appointments.
      parameters: []
      responses:
        '200':
          description: ''
          schema:
            $ref: '#/definitions/Appointment'
      tags:
      - appointments
    put:
      operationId: appointments_update
      description: Detail view for appointments.
      parameters:
      - name: data
        in: body
        required: true
        schema:
          $ref: '#/definitions/Appointment'
      responses:
        '200':
          description: ''
          schema:
            $ref: '#/definitions/Appointment'
      tags:
      - appointments
    patch:
      operationId: appointments_partial_update
      description: Detail view for appointments.
      parameters:
      - name: data
        in: body
        required: true
        schema:
          $ref: '#/definitions/Appointment'
      responses:
        '200':
          description: ''
          schema:
            $ref: '#/definitions/Appointment'
      tags:
      - appointments
    delete:
      operationId: appointments_delete
      description: Detail view for appointments.
      parameters: []
      responses:
        '204':
          description: ''
      tags:
      - appointments
    parameters:
    - name: id
      in: path
      required: true
      type: string
  /appointments/{id}/accept/:
    post:
      operationId: appointments_accept_create
      description: Accept an appointment by provider.
      parameters: []
      responses:
        '201':
          description: ''
      tags:
      - appointments
    parameters:
    - name: id
      in: path
      required: true
      type: string
  /appointments/{id}/assign-provider/:
    post:
      operationId: appointments_assign-provider_create
      description: Assign a provider to an appointment manually (organization owner
        only). Fallback when not auto-assigned.
      parameters: []
      responses:
        '201':
          description: ''
      tags:
      - appointments
    parameters:
    - name: id
      in: path
      required: true
      type: string
  /appointments/{id}/cancel/:
    post:
      operationId: appointments_cancel_create
      description: Cancel an appointment.
      parameters: []
      responses:
        '201':
          description: ''
      tags:
      - appointments
    parameters:
    - name: id
      in: path
      required: true
      type: string
  /appointments/{id}/create-allergy/:
    post:
      operationId: appointments_create-allergy_create
      description: Create an allergy record from an appointment.
      parameters: []
      responses:
        '201':
          description: ''
      tags:
      - appointments
    parameters:
    - name: id
      in: path
      required: true
      type: string
  /appointments/{id}/create-condition/:
    post:
      operationId: appointments_create-condition_create
      description: Create a condition record from an appointment.
      parameters: []
      responses:
        '201':
          description: ''
      tags:
      - appointments
    parameters:
    - name: id
      in: path
      required: true
      type: string
  /appointments/{id}/create-consultation/:
    post:
      operationId: appointments_create-consultation_create
      description: Create a consultation record from an appointment.
      parameters: []
      responses:
        '201':
          description: ''
      tags:
      - appointments
    parameters:
    - name: id
      in: path
      required: true
      type: string
  /appointments/{id}/create-lab-order/:
    post:
      operationId: appointments_create-lab-order_create
      description: Create a lab order (draft) for the appointment patient.
      parameters: []
      responses:
        '201':
          description: ''
      tags:
      - appointments
    parameters:
    - name: id
      in: path
      required: true
      type: string
  /appointments/{id}/create-medical-record/:
    post:
      operationId: appointments_create-medical-record_create
      description: Create a medical record from an appointment.
      parameters: []
      responses:
        '201':
          description: ''
      tags:
      - appointments
    parameters:
    - name: id
      in: path
      required: true
      type: string
  /appointments/{id}/create-prescription/:
    post:
      operationId: appointments_create-prescription_create
      description: Create a prescription from an appointment.
      parameters: []
      responses:
        '201':
          description: ''
      tags:
      - appointments
    parameters:
    - name: id
      in: path
      required: true
      type: string
  /appointments/{id}/reject/:
    post:
      operationId: appointments_reject_create
      description: Reject an appointment by provider.
      parameters: []
      responses:
        '201':
          description: ''
      tags:
      - appointments
    parameters:
    - name: id
      in: path
      required: true
      type: string
  /consultations/:
    get:
      operationId: consultations_list
      description: List and create consultations.
      parameters:
      - name: search
        in: query
        description: A search term.
        required: false
        type: string
      - name: ordering
        in: query
        description: Which field to use when ordering the results.
        required: false
        type: string
      - name: page
        in: query
        description: A page number within the paginated result set.
        required: false
        type: integer
      - name: page_size
        in: query
        description: Number of results to return per page.
        required: false
        type: integer
      responses:
        '200':
          description: ''
          schema:
            required:
            - count
            - results
            type: object
            properties:
              count:
                type: integer
              next:
                type: string
                format: uri
                x-nullable: true
              previous:
                type: string
                format: uri
                x-nullable: true
              results:
                type: array
                items:
                  $ref: '#/definitions/Consultation'
      tags:
      - consultations
    post:
      operationId: consultations_create
      description: List and create consultations.
      parameters:
      - name: data
        in: body
        required: true
        schema:
          $ref: '#/definitions/Consultation'
      responses:
        '201':
          description: ''
          schema:
            $ref: '#/definitions/Consultation'
      tags:
      - consultations
    parameters: []
  /consultations/{consultation_id}/:
    get:
      operationId: consultations_read
      description: Detail view for consultations.
      parameters: []
      responses:
        '200':
          description: ''
          schema:
            $ref: '#/definitions/Consultation'
      tags:
      - consultations
    put:
      operationId: consultations_update
      description: Detail view for consultations.
      parameters:
      - name: data
        in: body
        required: true
        schema:
          $ref: '#/definitions/Consultation'
      responses:
        '200':
          description: ''
          schema:
            $ref: '#/definitions/Consultation'
      tags:
      - consultations
    patch:
      operationId: consultations_partial_update
      description: Detail view for consultations.
      parameters:
      - name: data
        in: body
        required: true
        schema:
          $ref: '#/definitions/Consultation'
      responses:
        '200':
          description: ''
          schema:
            $ref: '#/definitions/Consultation'
      tags:
      - consultations
    parameters:
    - name: consultation_id
      in: path
      required: true
      type: string
  /consultations/{consultation_id}/end-video/:
    post:
      operationId: consultations_end-video_create
      description: |-
        End video and mark consultation completed (End Call from client).
        Doctor or patient.
        Accepts optional recording_sid and recording_url to save with consultation.
      parameters: []
      responses:
        '201':
          description: ''
      tags:
      - consultations
    parameters:
    - name: consultation_id
      in: path
      required: true
      type: string
  /consultations/{consultation_id}/end/:
    post:
      operationId: consultations_end_create
      description: End a consultation.
      parameters: []
      responses:
        '201':
          description: ''
      tags:
      - consultations
    parameters:
    - name: consultation_id
      in: path
      required: true
      type: string
  /consultations/{consultation_id}/start-video/:
    post:
      operationId: consultations_start-video_create
      description: |-
        Set consultation room (Stream call id) and status to in_progress.
        Provider only. Stream Video call is created/joined client-side using this room_name.
      parameters: []
      responses:
        '201':
          description: ''
      tags:
      - consultations
    parameters:
    - name: consultation_id
      in: path
      required: true
      type: string
  /consultations/{consultation_id}/start/:
    post:
      operationId: consultations_start_create
      description: Start a consultation.
      parameters: []
      responses:
        '201':
          description: ''
      tags:
      - consultations
    parameters:
    - name: consultation_id
      in: path
      required: true
      type: string
  /consultations/{consultation_id}/video-token/:
    post:
      operationId: consultations_video-token_create
      description: |-
        Return Stream (GetStream) token and metadata for Video/Chat clients.
        API key is public; token is short-lived. Secret is never sent.
      parameters: []
      responses:
        '201':
          description: ''
      tags:
      - consultations
    parameters:
    - name: consultation_id
      in: path
      required: true
      type: string
  /documents/:
    get:
      operationId: documents_list
      description: ''
      parameters:
      - name: search
        in: query
        description: A search term.
        required: false
        type: string
      - name: ordering
        in: query
        description: Which field to use when ordering the results.
        required: false
        type: string
      - name: page
        in: query
        description: A page number within the paginated result set.
        required: false
        type: integer
      - name: page_size
        in: query
        description: Number of results to return per page.
        required: false
        type: integer
      responses:
        '200':
          description: ''
          schema:
            required:
            - count
            - results
            type: object
            properties:
              count:
                type: integer
              next:
                type: string
                format: uri
                x-nullable: true
              previous:
                type: string
                format: uri
                x-nullable: true
              results:
                type: array
                items:
                  $ref: '#/definitions/Document'
      consumes:
      - multipart/form-data
      - application/x-www-form-urlencoded
      tags:
      - documents
    post:
      operationId: documents_create
      description: ''
      parameters:
      - name: file
        in: formData
        required: true
        type: file
      - name: title
        in: formData
        required: false
        type: string
        maxLength: 255
      - name: description
        in: formData
        required: false
        type: string
      - name: organization
        in: formData
        description: Organization context when uploaded (optional).
        required: false
        type: string
        format: uuid
        x-nullable: true
      responses:
        '201':
          description: ''
          schema:
            $ref: '#/definitions/DocumentCreate'
      consumes:
      - multipart/form-data
      - application/x-www-form-urlencoded
      tags:
      - documents
    parameters: []
  /documents/{id}/:
    get:
      operationId: documents_read
      description: GET/PATCH/DELETE a single document by id.
      parameters: []
      responses:
        '200':
          description: ''
          schema:
            $ref: '#/definitions/Document'
      consumes:
      - multipart/form-data
      - application/x-www-form-urlencoded
      tags:
      - documents
    put:
      operationId: documents_update
      description: GET/PATCH/DELETE a single document by id.
      parameters:
      - name: title
        in: formData
        required: false
        type: string
        maxLength: 255
      - name: description
        in: formData
        required: false
        type: string
      - name: file
        in: formData
        required: false
        type: file
      responses:
        '200':
          description: ''
          schema:
            $ref: '#/definitions/DocumentUpdate'
      consumes:
      - multipart/form-data
      - application/x-www-form-urlencoded
      tags:
      - documents
    patch:
      operationId: documents_partial_update
      description: GET/PATCH/DELETE a single document by id.
      parameters:
      - name: title
        in: formData
        required: false
        type: string
        maxLength: 255
      - name: description
        in: formData
        required: false
        type: string
      - name: file
        in: formData
        required: false
        type: file
      responses:
        '200':
          description: ''
          schema:
            $ref: '#/definitions/DocumentUpdate'
      consumes:
      - multipart/form-data
      - application/x-www-form-urlencoded
      tags:
      - documents
    delete:
      operationId: documents_delete
      description: GET/PATCH/DELETE a single document by id.
      parameters: []
      responses:
        '204':
          description: ''
      consumes:
      - multipart/form-data
      - application/x-www-form-urlencoded
      tags:
      - documents
    parameters:
    - name: id
      in: path
      required: true
      type: string
  /documents/{id}/download/:
    get:
      operationId: documents_download_list
      description: Stream the file as attachment (useful when MEDIA is not public).
      parameters: []
      responses:
        '200':
          description: ''
      tags:
      - documents
    parameters:
    - name: id
      in: path
      required: true
      type: string
  /lab-orders/:
    get:
      operationId: lab-orders_list
      description: ''
      parameters:
      - name: search
        in: query
        description: A search term.
        required: false
        type: string
      - name: ordering
        in: query
        description: Which field to use when ordering the results.
        required: false
        type: string
      - name: page
        in: query
        description: A page number within the paginated result set.
        required: false
        type: integer
      - name: page_size
        in: query
        description: Number of results to return per page.
        required: false
        type: integer
      responses:
        '200':
          description: ''
          schema:
            required:
            - count
            - results
            type: object
            properties:
              count:
                type: integer
              next:
                type: string
                format: uri
                x-nullable: true
              previous:
                type: string
                format: uri
                x-nullable: true
              results:
                type: array
                items:
                  $ref: '#/definitions/LabOrder'
      tags:
      - lab-orders
    post:
      operationId: lab-orders_create
      description: ''
      parameters:
      - name: data
        in: body
        required: true
        schema:
          $ref: '#/definitions/LabOrderCreate'
      responses:
        '201':
          description: ''
          schema:
            $ref: '#/definitions/LabOrderCreate'
      tags:
      - lab-orders
    parameters: []
  /lab-orders/{id}/:
    get:
      operationId: lab-orders_read
      description: ''
      parameters: []
      responses:
        '200':
          description: ''
          schema:
            $ref: '#/definitions/LabOrder'
      tags:
      - lab-orders
    put:
      operationId: lab-orders_update
      description: ''
      parameters:
      - name: data
        in: body
        required: true
        schema:
          $ref: '#/definitions/LabOrder'
      responses:
        '200':
          description: ''
          schema:
            $ref: '#/definitions/LabOrder'
      tags:
      - lab-orders
    patch:
      operationId: lab-orders_partial_update
      description: ''
      parameters:
      - name: data
        in: body
        required: true
        schema:
          $ref: '#/definitions/LabOrderDraftUpdate'
      responses:
        '200':
          description: ''
          schema:
            $ref: '#/definitions/LabOrderDraftUpdate'
      tags:
      - lab-orders
    delete:
      operationId: lab-orders_delete
      description: ''
      parameters: []
      responses:
        '204':
          description: ''
      tags:
      - lab-orders
    parameters:
    - name: id
      in: path
      required: true
      type: string
  /lab-orders/{id}/acknowledge/:
    post:
      operationId: lab-orders_acknowledge_create
      description: ''
      parameters: []
      responses:
        '201':
          description: ''
      tags:
      - lab-orders
    parameters:
    - name: id
      in: path
      required: true
      type: string
  /lab-orders/{id}/cancel/:
    post:
      operationId: lab-orders_cancel_create
      description: ''
      parameters: []
      responses:
        '201':
          description: ''
      tags:
      - lab-orders
    parameters:
    - name: id
      in: path
      required: true
      type: string
  /lab-orders/{id}/complete/:
    post:
      operationId: lab-orders_complete_create
      description: ''
      parameters: []
      responses:
        '201':
          description: ''
      tags:
      - lab-orders
    parameters:
    - name: id
      in: path
      required: true
      type: string
  /lab-orders/{id}/mark-in-progress/:
    post:
      operationId: lab-orders_mark-in-progress_create
      description: ''
      parameters: []
      responses:
        '201':
          description: ''
      tags:
      - lab-orders
    parameters:
    - name: id
      in: path
      required: true
      type: string
  /lab-orders/{id}/mark-sent/:
    post:
      operationId: lab-orders_mark-sent_create
      description: ''
      parameters: []
      responses:
        '201':
          description: ''
      tags:
      - lab-orders
    parameters:
    - name: id
      in: path
      required: true
      type: string
  /lab-orders/{id}/sign/:
    post:
      operationId: lab-orders_sign_create
      description: ''
      parameters: []
      responses:
        '201':
          description: ''
      tags:
      - lab-orders
    parameters:
    - name: id
      in: path
      required: true
      type: string
  /medical-records/allergies/:
    get:
      operationId: medical-records_allergies_list
      description: List and create allergies.
      parameters:
      - name: search
        in: query
        description: A search term.
        required: false
        type: string
      - name: ordering
        in: query
        description: Which field to use when ordering the results.
        required: false
        type: string
      - name: page
        in: query
        description: A page number within the paginated result set.
        required: false
        type: integer
      - name: page_size
        in: query
        description: Number of results to return per page.
        required: false
        type: integer
      responses:
        '200':
          description: ''
          schema:
            required:
            - count
            - results
            type: object
            properties:
              count:
                type: integer
              next:
                type: string
                format: uri
                x-nullable: true
              previous:
                type: string
                format: uri
                x-nullable: true
              results:
                type: array
                items:
                  $ref: '#/definitions/Allergy'
      tags:
      - medical-records
    post:
      operationId: medical-records_allergies_create
      description: List and create allergies.
      parameters:
      - name: data
        in: body
        required: true
        schema:
          $ref: '#/definitions/Allergy'
      responses:
        '201':
          description: ''
          schema:
            $ref: '#/definitions/Allergy'
      tags:
      - medical-records
    parameters: []
  /medical-records/conditions/:
    get:
      operationId: medical-records_conditions_list
      description: List and create conditions.
      parameters:
      - name: search
        in: query
        description: A search term.
        required: false
        type: string
      - name: ordering
        in: query
        description: Which field to use when ordering the results.
        required: false
        type: string
      - name: page
        in: query
        description: A page number within the paginated result set.
        required: false
        type: integer
      - name: page_size
        in: query
        description: Number of results to return per page.
        required: false
        type: integer
      responses:
        '200':
          description: ''
          schema:
            required:
            - count
            - results
            type: object
            properties:
              count:
                type: integer
              next:
                type: string
                format: uri
                x-nullable: true
              previous:
                type: string
                format: uri
                x-nullable: true
              results:
                type: array
                items:
                  $ref: '#/definitions/Condition'
      tags:
      - medical-records
    post:
      operationId: medical-records_conditions_create
      description: List and create conditions.
      parameters:
      - name: data
        in: body
        required: true
        schema:
          $ref: '#/definitions/Condition'
      responses:
        '201':
          description: ''
          schema:
            $ref: '#/definitions/Condition'
      tags:
      - medical-records
    parameters: []
  /medical-records/patient/me/portfolio/:
    get:
      operationId: medical-records_patient_me_portfolio_list
      description: |-
        Return the authenticated patient's medical records, conditions, allergies,
        prescriptions, and raw vital sign rows in one response.

        Intended for patient mobile/web portals to avoid multiple round trips.
        Each sub-list is capped for performance; use the specific list endpoints
        for full pagination.
      parameters: []
      responses:
        '200':
          description: ''
      tags:
      - medical-records
    parameters: []
  /medical-records/records/:
    get:
      operationId: medical-records_records_list
      description: List and create medical records.
      parameters:
      - name: search
        in: query
        description: A search term.
        required: false
        type: string
      - name: ordering
        in: query
        description: Which field to use when ordering the results.
        required: false
        type: string
      - name: page
        in: query
        description: A page number within the paginated result set.
        required: false
        type: integer
      - name: page_size
        in: query
        description: Number of results to return per page.
        required: false
        type: integer
      responses:
        '200':
          description: ''
          schema:
            required:
            - count
            - results
            type: object
            properties:
              count:
                type: integer
              next:
                type: string
                format: uri
                x-nullable: true
              previous:
                type: string
                format: uri
                x-nullable: true
              results:
                type: array
                items:
                  $ref: '#/definitions/MedicalRecord'
      tags:
      - medical-records
    post:
      operationId: medical-records_records_create
      description: List and create medical records.
      parameters:
      - name: data
        in: body
        required: true
        schema:
          $ref: '#/definitions/MedicalRecord'
      responses:
        '201':
          description: ''
          schema:
            $ref: '#/definitions/MedicalRecord'
      tags:
      - medical-records
    parameters: []
  /notifications/:
    get:
      operationId: notifications_list
      description: List notifications for the current user.
      parameters:
      - name: ordering
        in: query
        description: Which field to use when ordering the results.
        required: false
        type: string
      - name: page
        in: query
        description: A page number within the paginated result set.
        required: false
        type: integer
      - name: page_size
        in: query
        description: Number of results to return per page.
        required: false
        type: integer
      responses:
        '200':
          description: ''
          schema:
            required:
            - count
            - results
            type: object
            properties:
              count:
                type: integer
              next:
                type: string
                format: uri
                x-nullable: true
              previous:
                type: string
                format: uri
                x-nullable: true
              results:
                type: array
                items:
                  $ref: '#/definitions/Notification'
      tags:
      - notifications
    post:
      operationId: notifications_create
      description: List notifications for the current user.
      parameters:
      - name: data
        in: body
        required: true
        schema:
          $ref: '#/definitions/Notification'
      responses:
        '201':
          description: ''
          schema:
            $ref: '#/definitions/Notification'
      tags:
      - notifications
    patch:
      operationId: notifications_partial_update
      description: Handle PATCH request to mark all as read.
      parameters:
      - name: data
        in: body
        required: true
        schema:
          $ref: '#/definitions/Notification'
      responses:
        '200':
          description: ''
          schema:
            $ref: '#/definitions/Notification'
      tags:
      - notifications
    parameters: []
  /notifications/mark-all-read/:
    patch:
      operationId: notifications_mark-all-read_partial_update
      description: Mark all notifications as read for the current user.
      parameters: []
      responses:
        '200':
          description: ''
      tags:
      - notifications
    parameters: []
  /notifications/{id}/:
    get:
      operationId: notifications_read
      description: Retrieve, update, or delete a notification.
      parameters: []
      responses:
        '200':
          description: ''
          schema:
            $ref: '#/definitions/Notification'
      tags:
      - notifications
    put:
      operationId: notifications_update
      description: Retrieve, update, or delete a notification.
      parameters:
      - name: data
        in: body
        required: true
        schema:
          $ref: '#/definitions/NotificationUpdate'
      responses:
        '200':
          description: ''
          schema:
            $ref: '#/definitions/NotificationUpdate'
      tags:
      - notifications
    patch:
      operationId: notifications_partial_update
      description: Retrieve, update, or delete a notification.
      parameters:
      - name: data
        in: body
        required: true
        schema:
          $ref: '#/definitions/NotificationUpdate'
      responses:
        '200':
          description: ''
          schema:
            $ref: '#/definitions/NotificationUpdate'
      tags:
      - notifications
    delete:
      operationId: notifications_delete
      description: Retrieve, update, or delete a notification.
      parameters: []
      responses:
        '204':
          description: ''
      tags:
      - notifications
    parameters:
    - name: id
      in: path
      required: true
      type: string
  /org/add-provider/:
    post:
      operationId: org_add-provider_create
      description: Add an existing user (provider) to the current organization by
        email.
      parameters: []
      responses:
        '201':
          description: ''
      tags:
      - org
    parameters: []
  /org/admin/:
    get:
      operationId: org_admin_list
      description: Get all organizations with detailed statistics for admin.
      parameters: []
      responses:
        '200':
          description: ''
      tags:
      - org
    parameters: []
  /org/admin/create/:
    post:
      operationId: org_admin_create_create
      description: Create a new organization (admin only).
      parameters: []
      responses:
        '201':
          description: ''
      tags:
      - org
    parameters: []
  /org/admin/stats/:
    get:
      operationId: org_admin_stats_list
      description: Get organization statistics for admin dashboard.
      parameters: []
      responses:
        '200':
          description: ''
      tags:
      - org
    parameters: []
  /org/admin/{org_id}/toggle-status/:
    patch:
      operationId: org_admin_toggle-status_partial_update
      description: Toggle organization active status (admin only).
      parameters: []
      responses:
        '200':
          description: ''
      tags:
      - org
    parameters:
    - name: org_id
      in: path
      required: true
      type: string
  /org/branding/:
    get:
      operationId: org_branding_list
      description: |-
        Get organization branding (public, no auth required).
        Used for white-label frontend.
      parameters: []
      responses:
        '200':
          description: ''
      tags:
      - org
    parameters: []
  /org/branding/{slug}/:
    get:
      operationId: org_branding_read
      description: |-
        Get organization branding (public, no auth required).
        Used for white-label frontend.
      parameters: []
      responses:
        '200':
          description: ''
      tags:
      - org
    parameters:
    - name: slug
      in: path
      required: true
      type: string
  /org/create-patient/:
    post:
      operationId: org_create-patient_create
      description: Create a new patient and add them to the organization in one transaction.
      parameters: []
      responses:
        '201':
          description: ''
      tags:
      - org
    parameters: []
  /org/create-provider/:
    post:
      operationId: org_create-provider_create
      description: Create a new provider and add them to the organization in one transaction.
      parameters: []
      responses:
        '201':
          description: ''
      tags:
      - org
    parameters: []
  /org/create/:
    post:
      operationId: org_create_create
      description: Create a new organization and assign user as owner.
      parameters: []
      responses:
        '201':
          description: ''
      tags:
      - org
    parameters: []
  /org/doctors/:
    get:
      operationId: org_doctors_list
      description: Get list of doctors in current organization.
      parameters: []
      responses:
        '200':
          description: ''
      tags:
      - org
    parameters: []
  /org/identity/admin/organizations/:
    get:
      operationId: org_identity_admin_organizations_list
      description: ''
      parameters: []
      responses:
        '200':
          description: ''
      tags:
      - org
    parameters: []
  /org/identity/admin/organizations/{org_id}/:
    get:
      operationId: org_identity_admin_organizations_read
      description: ''
      parameters: []
      responses:
        '200':
          description: ''
      tags:
      - org
    parameters:
    - name: org_id
      in: path
      required: true
      type: string
  /org/identity/admin/organizations/{org_id}/approve-cac/:
    post:
      operationId: org_identity_admin_organizations_approve-cac_create
      description: ''
      parameters: []
      responses:
        '201':
          description: ''
      tags:
      - org
    parameters:
    - name: org_id
      in: path
      required: true
      type: string
  /org/identity/admin/organizations/{org_id}/query-cac/:
    post:
      operationId: org_identity_admin_organizations_query-cac_create
      description: ''
      parameters: []
      responses:
        '201':
          description: ''
      tags:
      - org
    parameters:
    - name: org_id
      in: path
      required: true
      type: string
  /org/identity/admin/organizations/{org_id}/suspend-address/:
    post:
      operationId: org_identity_admin_organizations_suspend-address_create
      description: ''
      parameters: []
      responses:
        '201':
          description: ''
      tags:
      - org
    parameters:
    - name: org_id
      in: path
      required: true
      type: string
  /org/identity/admin/organizations/{org_id}/suspend-cac/:
    post:
      operationId: org_identity_admin_organizations_suspend-cac_create
      description: ''
      parameters: []
      responses:
        '201':
          description: ''
      tags:
      - org
    parameters:
    - name: org_id
      in: path
      required: true
      type: string
  /org/identity/cac/:
    post:
      operationId: org_identity_cac_create
      description: |-
        Explicit paid CAC registry pre-check (cac-basic). The only API that may bill
        the verification provider for CAC. Does not store or approve CAC on the org.
      parameters: []
      responses:
        '201':
          description: ''
      tags:
      - org
    parameters: []
  /org/identity/me/:
    get:
      operationId: org_identity_me_list
      description: ''
      parameters: []
      responses:
        '200':
          description: ''
      tags:
      - org
    patch:
      operationId: org_identity_me_partial_update
      description: ''
      parameters: []
      responses:
        '200':
          description: ''
      tags:
      - org
    parameters: []
  /org/identity/me/complete/:
    post:
      operationId: org_identity_me_complete_create
      description: ''
      parameters: []
      responses:
        '201':
          description: ''
      tags:
      - org
    parameters: []
  /org/identity/upgrade/:
    post:
      operationId: org_identity_upgrade_create
      description: ''
      parameters: []
      responses:
        '201':
          description: ''
      tags:
      - org
    parameters: []
  /org/me/:
    get:
      operationId: org_me_list
      description: Get or update current organization details (uses X-Organization-ID
        from cookie).
      parameters: []
      responses:
        '200':
          description: ''
      tags:
      - org
    patch:
      operationId: org_me_partial_update
      description: Get or update current organization details (uses X-Organization-ID
        from cookie).
      parameters: []
      responses:
        '200':
          description: ''
      tags:
      - org
    parameters: []
  /org/patient-plans/:
    get:
      operationId: org_patient-plans_list
      description: |-
        List organization payment plans available to patients (read-only).
        Patients can view plans to upgrade/downgrade their subscription.
        On mobile, JWT auth runs after middleware so request.organization may be
        unset; resolve from request.user.organization when needed.
      parameters: []
      responses:
        '200':
          description: ''
      tags:
      - org
    parameters: []
  /org/patients/:
    get:
      operationId: org_patients_list
      description: Get list of patients (users) in current organization.
      parameters: []
      responses:
        '200':
          description: ''
      tags:
      - org
    parameters: []
  /org/payment-plans/:
    get:
      operationId: org_payment-plans_list
      description: ViewSet for managing organization payment plans.
      parameters:
      - name: search
        in: query
        description: A search term.
        required: false
        type: string
      - name: ordering
        in: query
        description: Which field to use when ordering the results.
        required: false
        type: string
      - name: page
        in: query
        description: A page number within the paginated result set.
        required: false
        type: integer
      - name: page_size
        in: query
        description: Number of results to return per page.
        required: false
        type: integer
      responses:
        '200':
          description: ''
          schema:
            required:
            - count
            - results
            type: object
            properties:
              count:
                type: integer
              next:
                type: string
                format: uri
                x-nullable: true
              previous:
                type: string
                format: uri
                x-nullable: true
              results:
                type: array
                items:
                  $ref: '#/definitions/OrganizationPaymentPlan'
      tags:
      - org
    post:
      operationId: org_payment-plans_create
      description: ViewSet for managing organization payment plans.
      parameters:
      - name: data
        in: body
        required: true
        schema:
          $ref: '#/definitions/OrganizationPaymentPlan'
      responses:
        '201':
          description: ''
          schema:
            $ref: '#/definitions/OrganizationPaymentPlan'
      tags:
      - org
    parameters: []
  /org/payment-plans/{id}/:
    get:
      operationId: org_payment-plans_read
      description: ViewSet for managing organization payment plans.
      parameters: []
      responses:
        '200':
          description: ''
          schema:
            $ref: '#/definitions/OrganizationPaymentPlan'
      tags:
      - org
    put:
      operationId: org_payment-plans_update
      description: ViewSet for managing organization payment plans.
      parameters:
      - name: data
        in: body
        required: true
        schema:
          $ref: '#/definitions/OrganizationPaymentPlan'
      responses:
        '200':
          description: ''
          schema:
            $ref: '#/definitions/OrganizationPaymentPlan'
      tags:
      - org
    patch:
      operationId: org_payment-plans_partial_update
      description: ViewSet for managing organization payment plans.
      parameters:
      - name: data
        in: body
        required: true
        schema:
          $ref: '#/definitions/OrganizationPaymentPlan'
      responses:
        '200':
          description: ''
          schema:
            $ref: '#/definitions/OrganizationPaymentPlan'
      tags:
      - org
    delete:
      operationId: org_payment-plans_delete
      description: ViewSet for managing organization payment plans.
      parameters: []
      responses:
        '204':
          description: ''
      tags:
      - org
    parameters:
    - name: id
      in: path
      required: true
      type: string
  /org/plan-usage/:
    get:
      operationId: org_plan-usage_list
      description: |-
        Return organization plan limits and current usage.
        Useful for dashboards and upgrade prompts.
      parameters: []
      responses:
        '200':
          description: ''
      tags:
      - org
    parameters: []
  /org/plans/:
    get:
      operationId: org_plans_list
      description: List all available pricing plans.
      parameters: []
      responses:
        '200':
          description: ''
      tags:
      - org
    parameters: []
  /org/plans/{tier}/:
    get:
      operationId: org_plans_read
      description: Get a specific pricing plan by tier.
      parameters: []
      responses:
        '200':
          description: ''
      tags:
      - org
    parameters:
    - name: tier
      in: path
      required: true
      type: string
  /org/pricing/:
    get:
      operationId: org_pricing_list
      description: ViewSet for managing organization pricing.
      parameters:
      - name: search
        in: query
        description: A search term.
        required: false
        type: string
      - name: ordering
        in: query
        description: Which field to use when ordering the results.
        required: false
        type: string
      - name: page
        in: query
        description: A page number within the paginated result set.
        required: false
        type: integer
      - name: page_size
        in: query
        description: Number of results to return per page.
        required: false
        type: integer
      responses:
        '200':
          description: ''
          schema:
            required:
            - count
            - results
            type: object
            properties:
              count:
                type: integer
              next:
                type: string
                format: uri
                x-nullable: true
              previous:
                type: string
                format: uri
                x-nullable: true
              results:
                type: array
                items:
                  $ref: '#/definitions/OrganizationPricing'
      tags:
      - org
    post:
      operationId: org_pricing_create
      description: ViewSet for managing organization pricing.
      parameters:
      - name: data
        in: body
        required: true
        schema:
          $ref: '#/definitions/OrganizationPricing'
      responses:
        '201':
          description: ''
          schema:
            $ref: '#/definitions/OrganizationPricing'
      tags:
      - org
    parameters: []
  /org/pricing/{id}/:
    get:
      operationId: org_pricing_read
      description: ViewSet for managing organization pricing.
      parameters: []
      responses:
        '200':
          description: ''
          schema:
            $ref: '#/definitions/OrganizationPricing'
      tags:
      - org
    put:
      operationId: org_pricing_update
      description: ViewSet for managing organization pricing.
      parameters:
      - name: data
        in: body
        required: true
        schema:
          $ref: '#/definitions/OrganizationPricing'
      responses:
        '200':
          description: ''
          schema:
            $ref: '#/definitions/OrganizationPricing'
      tags:
      - org
    patch:
      operationId: org_pricing_partial_update
      description: ViewSet for managing organization pricing.
      parameters:
      - name: data
        in: body
        required: true
        schema:
          $ref: '#/definitions/OrganizationPricing'
      responses:
        '200':
          description: ''
          schema:
            $ref: '#/definitions/OrganizationPricing'
      tags:
      - org
    delete:
      operationId: org_pricing_delete
      description: ViewSet for managing organization pricing.
      parameters: []
      responses:
        '204':
          description: ''
      tags:
      - org
    parameters:
    - name: id
      in: path
      required: true
      type: string
  /org/providers/:
    get:
      operationId: org_providers_list
      description: Get list of providers (users) in current organization.
      parameters: []
      responses:
        '200':
          description: ''
      tags:
      - org
    parameters: []
  /org/register/:
    post:
      operationId: org_register_create
      summary: 'Create organization (step 1: register), setup_step=subscription.'
      description: |-
        **Anonymous (no session):** requires business owner account + org in one request.
        - Top-level or nested ``user``: ``email``, ``password``, ``password_confirm``,
          ``first_name``, ``last_name``, optional ``phone_number``.
        - Also ``name``, ``slug`` (and optional ``domain``, ``description``).
        - Creates the user (platform role OWNER, no org yet), then the organization,
          links the user as organization owner, sends verification like ``/api/users/register/``,
          and returns ``requires_verification: true`` (no JWT until verify + login).

        **Authenticated:** same org fields; optional ``user`` profile object to update
        ``first_name`` / ``last_name`` / ``phone_number`` on the current account before
        attaching as owner. Do not send ``password`` on this path.
      parameters: []
      responses:
        '201':
          description: ''
      tags:
      - org
    parameters: []
  /org/reports/:
    get:
      operationId: org_reports_list
      description: Get basic analytics/reports for organization.
      parameters: []
      responses:
        '200':
          description: ''
      tags:
      - org
    parameters: []
  /org/set-pricing/:
    post:
      operationId: org_set-pricing_create
      description: Set pricing for a service type.
      parameters: []
      responses:
        '201':
          description: ''
      tags:
      - org
    parameters: []
  /org/statistics/:
    get:
      operationId: org_statistics_list
      description: Get organization statistics for reports.
      parameters: []
      responses:
        '200':
          description: ''
      tags:
      - org
    parameters: []
  /org/statistics/export/:
    get:
      operationId: org_statistics_export_list
      description: Export organization statistics as CSV.
      parameters: []
      responses:
        '200':
          description: ''
      tags:
      - org
    parameters: []
  /payments/:
    get:
      operationId: payments_list
      description: |-
        List payments for the current user (patient) in the current organization.
        Patients see only their own payments; org admins could be extended later.
      parameters: []
      responses:
        '200':
          description: ''
      tags:
      - payments
    parameters: []
  /payments/admin/all/:
    get:
      operationId: payments_admin_all_list
      description: Get all payments with filtering for admin dashboard.
      parameters: []
      responses:
        '200':
          description: ''
      tags:
      - payments
    parameters: []
  /payments/admin/gateway-mode/:
    get:
      operationId: payments_admin_gateway-mode_list
      description: Read or update platform-wide payment gateway mode and/or automated
        payout flag.
      parameters: []
      responses:
        '200':
          description: ''
      tags:
      - payments
    put:
      operationId: payments_admin_gateway-mode_update
      description: Read or update platform-wide payment gateway mode and/or automated
        payout flag.
      parameters: []
      responses:
        '200':
          description: ''
      tags:
      - payments
    parameters: []
  /payments/admin/payouts/:
    get:
      operationId: payments_admin_payouts_list
      description: |-
        List payout records (organization requests + platform) for admin billing.
        Query params: status, provider, payout_type (organization|platform|all), search.
      parameters: []
      responses:
        '200':
          description: ''
      tags:
      - payments
    parameters: []
  /payments/admin/payouts/{payout_id}/:
    patch:
      operationId: payments_admin_payouts_partial_update
      description: Update a pending payout to success (deduct revenue) or failed (no
        deduction).
      parameters: []
      responses:
        '200':
          description: ''
      tags:
      - payments
    parameters:
    - name: payout_id
      in: path
      required: true
      type: string
  /payments/admin/revenue/system/:
    get:
      operationId: payments_admin_revenue_system_list
      description: |-
        Get system (platform) revenue summary. Admin only.
        Tracks revenue from organizations subscribing to use the platform.
      parameters: []
      responses:
        '200':
          description: ''
      tags:
      - payments
    parameters: []
  /payments/admin/stats/:
    get:
      operationId: payments_admin_stats_list
      description: Get billing statistics for admin dashboard.
      parameters: []
      responses:
        '200':
          description: ''
      tags:
      - payments
    parameters: []
  /payments/appointment/initiate/:
    post:
      operationId: payments_appointment_initiate_create
      description: Create a pending payment for an appointment in pay-per-appointment
        mode.
      parameters: []
      responses:
        '201':
          description: ''
      tags:
      - payments
    parameters: []
  /payments/appointment/verify/:
    post:
      operationId: payments_appointment_verify_create
      description: Verify an appointment payment by reference.
      parameters: []
      responses:
        '201':
          description: ''
      tags:
      - payments
    parameters: []
  /payments/config/:
    get:
      operationId: payments_config_list
      description: Return payment provider public keys for frontend (safe to expose).
      parameters: []
      responses:
        '200':
          description: ''
      tags:
      - payments
    parameters: []
  /payments/my-subscription/:
    get:
      operationId: payments_my-subscription_list
      description: |-
        Get the current user's active subscription (patient plan).
        Returns null if user has no active subscription.
      parameters: []
      responses:
        '200':
          description: ''
      tags:
      - payments
    parameters: []
  /payments/organization/:
    get:
      operationId: payments_organization_list
      description: |-
        List all payments for the current organization.
        Org admins can see all payments for their organization with filtering options.
      parameters: []
      responses:
        '200':
          description: ''
      tags:
      - payments
    parameters: []
  /payments/organization/revenue/:
    get:
      operationId: payments_organization_revenue_list
      description: Get the available revenue for the current organization.
      parameters: []
      responses:
        '200':
          description: ''
      tags:
      - payments
    parameters: []
  /payments/organization/subscription/initiate/:
    post:
      operationId: payments_organization_subscription_initiate_create
      description: Create a pending payment for patient to organization subscription
        and return Paystack params.
      parameters: []
      responses:
        '201':
          description: ''
      tags:
      - payments
    parameters: []
  /payments/organization/subscription/verify/:
    post:
      operationId: payments_organization_subscription_verify_create
      description: Verify an organization subscription payment by reference.
      parameters: []
      responses:
        '201':
          description: ''
      tags:
      - payments
    parameters: []
  /payments/payout-accounts/:
    get:
      operationId: payments_payout-accounts_list
      description: |-
        GET /payout-accounts/ → list (the one account the user can manage).
        POST /payout-accounts/ → add payout account.
      parameters: []
      responses:
        '200':
          description: ''
      tags:
      - payments
    post:
      operationId: payments_payout-accounts_create
      description: |-
        GET /payout-accounts/ → list (the one account the user can manage).
        POST /payout-accounts/ → add payout account.
      parameters: []
      responses:
        '201':
          description: ''
      tags:
      - payments
    parameters: []
  /payments/payout-accounts/banks/:
    get:
      operationId: payments_payout-accounts_banks_list
      description: |-
        GET /payout-accounts/banks/?provider=flutterwave&country=NG
        Returns available banks for payout account setup.
      parameters: []
      responses:
        '200':
          description: ''
      tags:
      - payments
    parameters: []
  /payments/payout-accounts/payout/:
    post:
      operationId: payments_payout-accounts_payout_create
      description: |-
        POST /payout-accounts/payout/
        Initiate payout of total_revenue to the user's payout account.
        - Superuser: pays out system (platform) total_revenue.
        - Org owner: pays out organization total_revenue.
        Amount is determined by backend from revenue; no amount in body.
      parameters: []
      responses:
        '201':
          description: ''
      tags:
      - payments
    parameters: []
  /payments/payout-accounts/{id}/:
    get:
      operationId: payments_payout-accounts_read
      description: |-
        GET /payout-accounts/{id}/ → retrieve.
        PUT /payout-accounts/{id}/ → update.
      parameters: []
      responses:
        '200':
          description: ''
      tags:
      - payments
    put:
      operationId: payments_payout-accounts_update
      description: |-
        GET /payout-accounts/{id}/ → retrieve.
        PUT /payout-accounts/{id}/ → update.
      parameters: []
      responses:
        '200':
          description: ''
      tags:
      - payments
    parameters:
    - name: id
      in: path
      required: true
      type: string
  /payments/subscription/initiate/:
    post:
      operationId: payments_subscription_initiate_create
      description: |-
        Create a pending payment for subscription and return Paystack params.
        Frontend uses these with react-paystack PaystackButton.
      parameters: []
      responses:
        '201':
          description: ''
      tags:
      - payments
    parameters: []
  /payments/verify/:
    post:
      operationId: payments_verify_create
      description: |-
        Verify a payment by reference (client callback after Paystack success).
        When Paystack confirms success, updates Payment to completed and organization subscription.
        Fallback when webhook is not reachable (e.g. local dev).
      parameters: []
      responses:
        '201':
          description: ''
      tags:
      - payments
    parameters: []
  /prescriptions/:
    get:
      operationId: prescriptions_list
      description: List and create prescriptions.
      parameters:
      - name: search
        in: query
        description: A search term.
        required: false
        type: string
      - name: ordering
        in: query
        description: Which field to use when ordering the results.
        required: false
        type: string
      - name: page
        in: query
        description: A page number within the paginated result set.
        required: false
        type: integer
      - name: page_size
        in: query
        description: Number of results to return per page.
        required: false
        type: integer
      responses:
        '200':
          description: ''
          schema:
            required:
            - count
            - results
            type: object
            properties:
              count:
                type: integer
              next:
                type: string
                format: uri
                x-nullable: true
              previous:
                type: string
                format: uri
                x-nullable: true
              results:
                type: array
                items:
                  $ref: '#/definitions/Prescription'
      tags:
      - prescriptions
    post:
      operationId: prescriptions_create
      description: List and create prescriptions.
      parameters:
      - name: data
        in: body
        required: true
        schema:
          $ref: '#/definitions/Prescription'
      responses:
        '201':
          description: ''
          schema:
            $ref: '#/definitions/Prescription'
      tags:
      - prescriptions
    parameters: []
  /prescriptions/{prescription_id}/:
    get:
      operationId: prescriptions_read
      description: Detail view for prescriptions.
      parameters: []
      responses:
        '200':
          description: ''
          schema:
            $ref: '#/definitions/Prescription'
      tags:
      - prescriptions
    put:
      operationId: prescriptions_update
      description: Detail view for prescriptions.
      parameters:
      - name: data
        in: body
        required: true
        schema:
          $ref: '#/definitions/Prescription'
      responses:
        '200':
          description: ''
          schema:
            $ref: '#/definitions/Prescription'
      tags:
      - prescriptions
    patch:
      operationId: prescriptions_partial_update
      description: Detail view for prescriptions.
      parameters:
      - name: data
        in: body
        required: true
        schema:
          $ref: '#/definitions/Prescription'
      responses:
        '200':
          description: ''
          schema:
            $ref: '#/definitions/Prescription'
      tags:
      - prescriptions
    parameters:
    - name: prescription_id
      in: path
      required: true
      type: string
  /profiles/admin/verifications/providers/:
    get:
      operationId: profiles_admin_verifications_providers_list
      description: ''
      parameters: []
      responses:
        '200':
          description: ''
      tags:
      - profiles
    parameters: []
  /profiles/admin/verifications/providers/{profile_id}/:
    get:
      operationId: profiles_admin_verifications_providers_read
      description: ''
      parameters: []
      responses:
        '200':
          description: ''
      tags:
      - profiles
    parameters:
    - name: profile_id
      in: path
      required: true
      type: string
  /profiles/admin/verifications/providers/{profile_id}/approve-license/:
    post:
      operationId: profiles_admin_verifications_providers_approve-license_create
      description: ''
      parameters: []
      responses:
        '201':
          description: ''
      tags:
      - profiles
    parameters:
    - name: profile_id
      in: path
      required: true
      type: string
  /profiles/admin/verifications/providers/{profile_id}/query-license/:
    post:
      operationId: profiles_admin_verifications_providers_query-license_create
      description: ''
      parameters: []
      responses:
        '201':
          description: ''
      tags:
      - profiles
    parameters:
    - name: profile_id
      in: path
      required: true
      type: string
  /profiles/admin/verifications/providers/{profile_id}/suspend-license/:
    post:
      operationId: profiles_admin_verifications_providers_suspend-license_create
      description: ''
      parameters: []
      responses:
        '201':
          description: ''
      tags:
      - profiles
    parameters:
    - name: profile_id
      in: path
      required: true
      type: string
  /profiles/applications/:
    get:
      operationId: profiles_applications_list
      description: List all provider applications (admin only).
      parameters: []
      responses:
        '200':
          description: ''
      tags:
      - profiles
    parameters: []
  /profiles/applications/{application_id}/:
    get:
      operationId: profiles_applications_read
      description: Get a single provider application by ID (admin only).
      parameters: []
      responses:
        '200':
          description: ''
      tags:
      - profiles
    parameters:
    - name: application_id
      in: path
      required: true
      type: string
  /profiles/applications/{application_id}/review/:
    post:
      operationId: profiles_applications_review_create
      description: Review and approve/reject provider application (admin only).
      parameters: []
      responses:
        '201':
          description: ''
      tags:
      - profiles
    parameters:
    - name: application_id
      in: path
      required: true
      type: string
  /profiles/me/:
    get:
      operationId: profiles_me_list
      description: Get current user's profile based on role. Creates profile if it
        doesn't exist.
      parameters: []
      responses:
        '200':
          description: ''
      tags:
      - profiles
    parameters: []
  /profiles/patient/:
    get:
      operationId: profiles_patient_read
      description: View for patient profile.
      parameters: []
      responses:
        '200':
          description: ''
          schema:
            $ref: '#/definitions/PatientProfile'
      tags:
      - profiles
    put:
      operationId: profiles_patient_update
      description: View for patient profile.
      parameters:
      - name: data
        in: body
        required: true
        schema:
          $ref: '#/definitions/PatientProfile'
      responses:
        '200':
          description: ''
          schema:
            $ref: '#/definitions/PatientProfile'
      tags:
      - profiles
    patch:
      operationId: profiles_patient_partial_update
      description: View for patient profile.
      parameters:
      - name: data
        in: body
        required: true
        schema:
          $ref: '#/definitions/PatientProfile'
      responses:
        '200':
          description: ''
          schema:
            $ref: '#/definitions/PatientProfile'
      tags:
      - profiles
    parameters: []
  /profiles/provider/:
    get:
      operationId: profiles_provider_read
      description: View for provider profile.
      parameters: []
      responses:
        '200':
          description: ''
          schema:
            $ref: '#/definitions/ProviderProfile'
      tags:
      - profiles
    put:
      operationId: profiles_provider_update
      description: View for provider profile.
      parameters:
      - name: data
        in: body
        required: true
        schema:
          $ref: '#/definitions/ProviderProfile'
      responses:
        '200':
          description: ''
          schema:
            $ref: '#/definitions/ProviderProfile'
      tags:
      - profiles
    patch:
      operationId: profiles_provider_partial_update
      description: View for provider profile.
      parameters:
      - name: data
        in: body
        required: true
        schema:
          $ref: '#/definitions/ProviderProfile'
      responses:
        '200':
          description: ''
          schema:
            $ref: '#/definitions/ProviderProfile'
      tags:
      - profiles
    parameters: []
  /profiles/provider/application/:
    get:
      operationId: profiles_provider_application_list
      description: Get or submit provider application. Allows any authenticated user
        to apply.
      parameters: []
      responses:
        '200':
          description: ''
      tags:
      - profiles
    post:
      operationId: profiles_provider_application_create
      description: Get or submit provider application. Allows any authenticated user
        to apply.
      parameters: []
      responses:
        '201':
          description: ''
      tags:
      - profiles
    put:
      operationId: profiles_provider_application_update
      description: Get or submit provider application. Allows any authenticated user
        to apply.
      parameters: []
      responses:
        '200':
          description: ''
      tags:
      - profiles
    patch:
      operationId: profiles_provider_application_partial_update
      description: Get or submit provider application. Allows any authenticated user
        to apply.
      parameters: []
      responses:
        '200':
          description: ''
      tags:
      - profiles
    parameters: []
  /profiles/providers/:
    get:
      operationId: profiles_providers_list
      description: List providers for current organization.
      parameters: []
      responses:
        '200':
          description: ''
      tags:
      - profiles
    parameters: []
  /reports/dashboard/:
    get:
      operationId: reports_dashboard_list
      description: Get comprehensive dashboard statistics for admin.
      parameters: []
      responses:
        '200':
          description: ''
      tags:
      - reports
    parameters: []
  /reports/growth/:
    get:
      operationId: reports_growth_list
      description: Get growth and trend metrics.
      parameters: []
      responses:
        '200':
          description: ''
      tags:
      - reports
    parameters: []
  /reports/health/:
    get:
      operationId: reports_health_list
      description: Get system health status.
      parameters: []
      responses:
        '200':
          description: ''
      tags:
      - reports
    parameters: []
  /users/auth/redirect-callback/:
    get:
      operationId: users_auth_redirect-callback_list
      description: |-
        Exchange one-time redirect token for access/refresh. Used when login on main domain
        redirects to org subdomain - cookies don't cross localhost/neem.localhost, so we
        pass a token and set cookies on the org domain.
      parameters: []
      responses:
        '200':
          description: ''
      tags:
      - users
    parameters: []
  /users/create/:
    post:
      operationId: users_create_create
      description: Admin user creation endpoint with role selection.
      parameters:
      - name: data
        in: body
        required: true
        schema:
          $ref: '#/definitions/UserCreation'
      responses:
        '201':
          description: ''
          schema:
            $ref: '#/definitions/UserCreation'
      tags:
      - users
    parameters: []
  /users/list/:
    get:
      operationId: users_list_list
      description: List all users (admin only).
      parameters: []
      responses:
        '200':
          description: ''
      tags:
      - users
    parameters: []
  /users/login/:
    post:
      operationId: users_login_create
      description: User login endpoint.
      parameters:
      - name: data
        in: body
        required: true
        schema:
          $ref: '#/definitions/TokenObtainPair'
      responses:
        '201':
          description: ''
          schema:
            $ref: '#/definitions/TokenObtainPair'
      tags:
      - users
    parameters: []
  /users/me/:
    get:
      operationId: users_me_list
      description: Get current user details. Includes redirect_url for domain-based
        multi-tenancy.
      parameters: []
      responses:
        '200':
          description: ''
      tags:
      - users
    parameters: []
  /users/me/change-password/:
    post:
      operationId: users_me_change-password_create
      description: Change user password.
      parameters: []
      responses:
        '201':
          description: ''
      tags:
      - users
    parameters: []
  /users/me/update/:
    put:
      operationId: users_me_update_update
      description: Update user profile.
      parameters: []
      responses:
        '200':
          description: ''
      tags:
      - users
    patch:
      operationId: users_me_update_partial_update
      description: Update user profile.
      parameters: []
      responses:
        '200':
          description: ''
      tags:
      - users
    parameters: []
  /users/password/reset/:
    post:
      operationId: users_password_reset_create
      description: Request password reset.
      parameters: []
      responses:
        '201':
          description: ''
      tags:
      - users
    parameters: []
  /users/password/reset/confirm/:
    post:
      operationId: users_password_reset_confirm_create
      description: Confirm password reset.
      parameters: []
      responses:
        '201':
          description: ''
      tags:
      - users
    parameters: []
  /users/register/:
    post:
      operationId: users_register_create
      description: User registration endpoint.
      parameters:
      - name: data
        in: body
        required: true
        schema:
          $ref: '#/definitions/UserRegistration'
      responses:
        '201':
          description: ''
          schema:
            $ref: '#/definitions/UserRegistration'
      tags:
      - users
    parameters: []
  /users/send-verification-code/:
    post:
      operationId: users_send-verification-code_create
      description: Send verification code via email or phone.
      parameters: []
      responses:
        '201':
          description: ''
      tags:
      - users
    parameters: []
  /users/token/refresh/:
    post:
      operationId: users_token_refresh_create
      description: |-
        Takes a refresh type JSON web token and returns an access type JSON web
        token if the refresh token is valid.
      parameters:
      - name: data
        in: body
        required: true
        schema:
          $ref: '#/definitions/TokenRefresh'
      responses:
        '201':
          description: ''
          schema:
            $ref: '#/definitions/TokenRefresh'
      tags:
      - users
    parameters: []
  /users/verify-code/:
    post:
      operationId: users_verify-code_create
      description: Verify code for email or phone.
      parameters: []
      responses:
        '201':
          description: ''
      tags:
      - users
    parameters: []
  /users/verify-email/:
    post:
      operationId: users_verify-email_create
      description: Verify user email.
      parameters: []
      responses:
        '201':
          description: ''
      tags:
      - users
    parameters: []
  /users/{user_id}/:
    get:
      operationId: users_read
      description: Get or update a user by id (admin only). Used for toggling is_active,
        etc.
      parameters: []
      responses:
        '200':
          description: ''
      tags:
      - users
    patch:
      operationId: users_partial_update
      description: Get or update a user by id (admin only). Used for toggling is_active,
        etc.
      parameters: []
      responses:
        '200':
          description: ''
      tags:
      - users
    parameters:
    - name: user_id
      in: path
      required: true
      type: string
  /vitals/:
    get:
      operationId: vitals_list
      description: List and create vital signs.
      parameters:
      - name: search
        in: query
        description: A search term.
        required: false
        type: string
      - name: ordering
        in: query
        description: Which field to use when ordering the results.
        required: false
        type: string
      - name: page
        in: query
        description: A page number within the paginated result set.
        required: false
        type: integer
      - name: page_size
        in: query
        description: Number of results to return per page.
        required: false
        type: integer
      responses:
        '200':
          description: ''
          schema:
            required:
            - count
            - results
            type: object
            properties:
              count:
                type: integer
              next:
                type: string
                format: uri
                x-nullable: true
              previous:
                type: string
                format: uri
                x-nullable: true
              results:
                type: array
                items:
                  $ref: '#/definitions/VitalSign'
      tags:
      - vitals
    post:
      operationId: vitals_create
      description: List and create vital signs.
      parameters:
      - name: data
        in: body
        required: true
        schema:
          $ref: '#/definitions/VitalSign'
      responses:
        '201':
          description: ''
          schema:
            $ref: '#/definitions/VitalSign'
      tags:
      - vitals
    parameters: []
definitions:
  User:
    required:
    - email
    type: object
    properties:
      id:
        title: Id
        type: string
        format: uuid
        readOnly: true
      email:
        title: Email
        type: string
        format: email
        maxLength: 254
        minLength: 1
      phone_number:
        title: Phone number
        type: string
        maxLength: 20
        x-nullable: true
      first_name:
        title: First name
        type: string
        maxLength: 150
      last_name:
        title: Last name
        type: string
        maxLength: 150
      full_name:
        title: Full name
        type: string
        readOnly: true
      role:
        title: Role
        type: string
        enum:
        - patient
        - provider
        - admin
        - owner
        - support
      is_active:
        title: Is active
        type: boolean
      is_verified:
        title: Is verified
        type: boolean
        readOnly: true
      is_superuser:
        title: Superuser status
        description: Designates that this user has all permissions without explicitly
          assigning them.
        type: boolean
        readOnly: true
      is_staff:
        title: Is staff
        type: boolean
        readOnly: true
      organization:
        title: Organization
        type: string
        format: uuid
        readOnly: true
      organization_role:
        title: Organization role
        type: string
        readOnly: true
        minLength: 1
      account_identity_locked:
        title: Account identity locked
        type: boolean
        readOnly: true
      created_at:
        title: Created at
        type: string
        format: date-time
        readOnly: true
      last_login:
        title: Last login
        type: string
        format: date-time
        readOnly: true
        x-nullable: true
  PatientProfile:
    type: object
    properties:
      id:
        title: Id
        type: string
        format: uuid
        readOnly: true
      user:
        $ref: '#/definitions/User'
      date_of_birth:
        title: Date of birth
        type: string
        format: date
        x-nullable: true
      gender:
        title: Gender
        type: string
        enum:
        - male
        - female
        - other
        - prefer_not_to_say
      blood_type:
        title: Blood type
        type: string
        enum:
        - A+
        - A-
        - B+
        - B-
        - AB+
        - AB-
        - O+
        - O-
        - unknown
      address_line1:
        title: Address line1
        type: string
        maxLength: 255
      address_line2:
        title: Address line2
        type: string
        maxLength: 255
      city:
        title: City
        type: string
        maxLength: 100
      state:
        title: State
        type: string
        maxLength: 100
      postal_code:
        title: Postal code
        type: string
        maxLength: 20
      country:
        title: Country
        type: string
        maxLength: 100
        minLength: 1
      emergency_contact_name:
        title: Emergency contact name
        type: string
        maxLength: 255
      emergency_contact_phone:
        title: Emergency contact phone
        type: string
        maxLength: 20
      emergency_contact_relationship:
        title: Emergency contact relationship
        type: string
        maxLength: 100
      allergies:
        title: Allergies
        description: Known allergies
        type: string
      chronic_conditions:
        title: Chronic conditions
        description: Chronic medical conditions
        type: string
      current_medications:
        title: Current medications
        description: Current medications
        type: string
      insurance_provider:
        title: Insurance provider
        type: string
        maxLength: 255
      insurance_policy_number:
        title: Insurance policy number
        type: string
        maxLength: 100
      preferred_language:
        title: Preferred language
        type: string
        maxLength: 10
        minLength: 1
      timezone:
        title: Timezone
        type: string
        maxLength: 50
        minLength: 1
      age:
        title: Age
        type: string
        readOnly: true
      created_at:
        title: Created at
        type: string
        format: date-time
        readOnly: true
      updated_at:
        title: Updated at
        type: string
        format: date-time
        readOnly: true
  ProviderProfile:
    type: object
    properties:
      id:
        title: Id
        type: string
        format: uuid
        readOnly: true
      user:
        $ref: '#/definitions/User'
      is_assignable:
        title: Is assignable
        description: If true, profile can be assigned to appointments (hidden when
          admin-only).
        type: boolean
      is_organization_owner:
        title: Is organization owner
        type: boolean
        readOnly: true
      license_number:
        title: License number
        type: string
        maxLength: 100
        x-nullable: true
      license_issuing_authority:
        title: License issuing authority
        type: string
        maxLength: 255
      license_expiry_date:
        title: License expiry date
        type: string
        format: date
        x-nullable: true
      license_verified:
        title: License verified
        type: boolean
        readOnly: true
      license_verified_at:
        title: License verified at
        type: string
        format: date-time
        readOnly: true
        x-nullable: true
      specialization:
        title: Specialization
        type: string
        maxLength: 255
      qualifications:
        title: Qualifications
        description: Medical qualifications and certifications
        type: string
      years_of_experience:
        title: Years of experience
        type: integer
        maximum: 50
        minimum: 0
        x-nullable: true
      bio:
        title: Bio
        description: Professional biography
        type: string
      license_review_status:
        title: License review status
        type: string
        enum:
        - submitted
        - queried
        - approved
        readOnly: true
      license_admin_note:
        title: License admin note
        type: string
        readOnly: true
        minLength: 1
      license_query_message:
        title: License query message
        type: string
        readOnly: true
        minLength: 1
      license_editable:
        title: License editable
        type: boolean
        readOnly: true
      profile_editable:
        title: Profile editable
        type: boolean
        readOnly: true
      license_expired:
        title: License expired
        type: boolean
        readOnly: true
      note:
        title: Note
        description: Legacy internal note; prefer license_admin_note
        type: string
        readOnly: true
        minLength: 1
      average_rating:
        title: Average rating
        type: string
        format: decimal
        readOnly: true
      total_reviews:
        title: Total reviews
        type: integer
        readOnly: true
      is_verified:
        title: Is verified
        type: boolean
        readOnly: true
      verified_at:
        title: Verified at
        type: string
        format: date-time
        readOnly: true
        x-nullable: true
      application_status:
        title: Application status
        type: string
        enum:
        - pending
        - submitted
        - under_review
        - documents_requested
        - approved
        - rejected
        readOnly: true
      application_submitted_at:
        title: Application submitted at
        type: string
        format: date-time
        readOnly: true
        x-nullable: true
      application_reviewed_at:
        title: Application reviewed at
        type: string
        format: date-time
        readOnly: true
        x-nullable: true
      rejection_reason:
        title: Rejection reason
        description: Reason for rejection if applicable
        type: string
        readOnly: true
        minLength: 1
      created_at:
        title: Created at
        type: string
        format: date-time
        readOnly: true
      updated_at:
        title: Updated at
        type: string
        format: date-time
        readOnly: true
  Appointment:
    type: object
    properties:
      id:
        title: Id
        type: string
        format: uuid
        readOnly: true
      appointment_number:
        title: Appointment number
        description: Unique appointment reference number
        type: string
        readOnly: true
        minLength: 1
      patient:
        $ref: '#/definitions/PatientProfile'
      patient_id:
        title: Patient id
        type: string
        format: uuid
      provider:
        $ref: '#/definitions/ProviderProfile'
      provider_id:
        title: Provider id
        type: string
        format: uuid
        x-nullable: true
      scheduled_at:
        title: Scheduled at
        type: string
        format: date-time
        x-nullable: true
      preferred_time:
        title: Preferred time
        description: Patient's preferred date/time (optional, flexible allowed)
        type: string
        format: date-time
        x-nullable: true
      duration_minutes:
        title: Duration minutes
        description: Appointment duration in minutes
        type: integer
        maximum: 2147483647
        minimum: 15
      consultation_type:
        title: Consultation type
        type: string
        enum:
        - virtual
        - in_person
      status:
        title: Status
        type: string
        enum:
        - pending_provider_assignment
        - provider_assigned
        - scheduled
        - confirmed
        - in_progress
        - completed
        - cancelled
        - no_show
        - rescheduled
        - accept
        - reject
      reason:
        title: Reason
        description: Reason for appointment / appointment type
        type: string
      patient_requirements:
        title: Patient requirements
        description: Notes or requirements from patient for matching
        type: string
      notes:
        title: Notes
        description: Additional notes
        type: string
      payment_mode:
        title: Payment mode
        description: Payment mode configured by organization at appointment creation
          time
        type: string
        enum:
        - free
        - subscription
        - pay_per_appointment
      appointment_payment_mode:
        title: Appointment payment mode
        type: string
        readOnly: true
      requires_subscription_for_acceptance:
        title: Requires subscription for acceptance
        type: string
        readOnly: true
      requires_payment_for_acceptance:
        title: Requires payment for acceptance
        type: string
        readOnly: true
      is_patient_subscription_active:
        title: Is patient subscription active
        type: string
        readOnly: true
      is_appointment_payment_completed:
        title: Is appointment payment completed
        type: string
        readOnly: true
      can_be_accepted:
        title: Can be accepted
        type: string
        readOnly: true
      payment_block_reason:
        title: Payment block reason
        type: string
        readOnly: true
      reminder_sent:
        title: Reminder sent
        type: boolean
        readOnly: true
      cancelled_at:
        title: Cancelled at
        type: string
        format: date-time
        x-nullable: true
      cancellation_reason:
        title: Cancellation reason
        type: string
      created_at:
        title: Created at
        type: string
        format: date-time
        readOnly: true
      updated_at:
        title: Updated at
        type: string
        format: date-time
        readOnly: true
  AppointmentSlot:
    required:
    - start_time
    - end_time
    type: object
    properties:
      id:
        title: Id
        type: string
        format: uuid
        readOnly: true
      provider:
        $ref: '#/definitions/ProviderProfile'
      provider_id:
        title: Provider id
        type: string
        format: uuid
      start_time:
        title: Start time
        type: string
        format: date-time
      end_time:
        title: End time
        type: string
        format: date-time
      is_available:
        title: Is available
        type: boolean
      is_recurring:
        title: Is recurring
        description: Is this a recurring slot?
        type: boolean
      recurrence_pattern:
        title: Recurrence pattern
        description: e.g., 'daily', 'weekly', 'weekdays'
        type: string
        maxLength: 50
      created_at:
        title: Created at
        type: string
        format: date-time
        readOnly: true
      updated_at:
        title: Updated at
        type: string
        format: date-time
        readOnly: true
  Consultation:
    required:
    - patient
    - provider
    type: object
    properties:
      id:
        title: Id
        type: string
        format: uuid
        readOnly: true
      consultation_number:
        title: Consultation number
        type: string
        readOnly: true
        minLength: 1
      appointment:
        title: Appointment
        type: string
        format: uuid
        x-nullable: true
      patient:
        title: Patient
        type: string
        format: uuid
      provider:
        title: Provider
        type: string
        format: uuid
      patient_details:
        title: Patient details
        type: string
        readOnly: true
      provider_details:
        title: Provider details
        type: string
        readOnly: true
      consultation_type:
        title: Consultation type
        type: string
        enum:
        - virtual
        - in_person
      status:
        title: Status
        type: string
        enum:
        - scheduled
        - started
        - in_progress
        - completed
        - cancelled
      started_at:
        title: Started at
        type: string
        format: date-time
        readOnly: true
        x-nullable: true
      ended_at:
        title: Ended at
        type: string
        format: date-time
        readOnly: true
        x-nullable: true
      duration_minutes:
        title: Duration minutes
        type: integer
        readOnly: true
        x-nullable: true
      room_name:
        title: Room name
        type: string
        readOnly: true
        minLength: 1
        x-nullable: true
      video_started_at:
        title: Video started at
        type: string
        format: date-time
        readOnly: true
        x-nullable: true
      video_ended_at:
        title: Video ended at
        type: string
        format: date-time
        readOnly: true
        x-nullable: true
      chief_complaint:
        title: Chief complaint
        type: string
      history_of_present_illness:
        title: History of present illness
        type: string
      physical_examination:
        title: Physical examination
        type: string
      assessment:
        title: Assessment
        type: string
      plan:
        title: Plan
        type: string
      clinical_notes:
        title: Clinical notes
        type: string
      follow_up_required:
        title: Follow up required
        type: boolean
      follow_up_date:
        title: Follow up date
        type: string
        format: date
        x-nullable: true
      follow_up_notes:
        title: Follow up notes
        type: string
      patient_rating:
        title: Patient rating
        type: integer
        maximum: 5
        minimum: 1
        x-nullable: true
      patient_feedback:
        title: Patient feedback
        type: string
      created_at:
        title: Created at
        type: string
        format: date-time
        readOnly: true
      updated_at:
        title: Updated at
        type: string
        format: date-time
        readOnly: true
  Document:
    type: object
    properties:
      id:
        title: Id
        type: string
        format: uuid
        readOnly: true
      owner_id:
        title: Owner id
        type: string
        readOnly: true
      organization:
        title: Organization
        description: Organization context when uploaded (optional).
        type: string
        format: uuid
        x-nullable: true
      title:
        title: Title
        type: string
        maxLength: 255
      description:
        title: Description
        type: string
      file_url:
        title: File url
        type: string
        readOnly: true
      original_filename:
        title: Original filename
        type: string
        readOnly: true
        minLength: 1
      size_bytes:
        title: Size bytes
        type: integer
        readOnly: true
      mime_type:
        title: Mime type
        type: string
        readOnly: true
        minLength: 1
      created_at:
        title: Created at
        type: string
        format: date-time
        readOnly: true
      updated_at:
        title: Updated at
        type: string
        format: date-time
        readOnly: true
  DocumentCreate:
    type: object
    properties:
      file:
        title: File
        type: string
        readOnly: true
        format: uri
      title:
        title: Title
        type: string
        maxLength: 255
      description:
        title: Description
        type: string
      organization:
        title: Organization
        description: Organization context when uploaded (optional).
        type: string
        format: uuid
        x-nullable: true
  DocumentUpdate:
    type: object
    properties:
      title:
        title: Title
        type: string
        maxLength: 255
      description:
        title: Description
        type: string
      file:
        title: File
        type: string
        readOnly: true
        format: uri
  LabOrderLineItem:
    required:
    - test_name
    type: object
    properties:
      id:
        title: Id
        type: string
        format: uuid
        readOnly: true
      test_code:
        title: Test code
        description: Optional local or LOINC code
        type: string
        maxLength: 64
      test_name:
        title: Test name
        type: string
        maxLength: 255
        minLength: 1
      urgency:
        title: Urgency
        type: string
        enum:
        - routine
        - urgent
        - stat
      sort_order:
        title: Sort order
        type: integer
        maximum: 2147483647
        minimum: 0
      notes:
        title: Notes
        type: string
      created_at:
        title: Created at
        type: string
        format: date-time
        readOnly: true
  LabOrder:
    required:
    - patient
    type: object
    properties:
      id:
        title: Id
        type: string
        format: uuid
        readOnly: true
      order_number:
        title: Order number
        type: string
        readOnly: true
        minLength: 1
      patient:
        title: Patient
        type: string
        format: uuid
      ordering_provider:
        title: Ordering provider
        type: string
        format: uuid
        readOnly: true
      organization:
        title: Organization
        type: string
        format: uuid
        readOnly: true
        x-nullable: true
      appointment:
        title: Appointment
        type: string
        format: uuid
        readOnly: true
        x-nullable: true
      consultation:
        title: Consultation
        type: string
        format: uuid
        readOnly: true
        x-nullable: true
      status:
        title: Status
        type: string
        enum:
        - draft
        - signed
        - sent
        - acknowledged
        - in_progress
        - completed
        - cancelled
      clinical_indication:
        title: Clinical indication
        description: Reason for testing / clinical question
        type: string
      patient_instructions:
        title: Patient instructions
        description: e.g. fasting, timing, hydration
        type: string
      laboratory_name:
        title: Laboratory name
        type: string
        maxLength: 255
      external_accession:
        title: External accession
        description: Lab reference / accession number
        type: string
        maxLength: 128
      result_summary:
        title: Result summary
        type: string
      document:
        title: Document
        description: Optional uploaded requisition or result PDF
        type: string
        format: uuid
        x-nullable: true
      signed_at:
        title: Signed at
        type: string
        format: date-time
        readOnly: true
        x-nullable: true
      signed_by:
        title: Signed by
        type: string
        format: uuid
        readOnly: true
        x-nullable: true
      sent_at:
        title: Sent at
        type: string
        format: date-time
        readOnly: true
        x-nullable: true
      acknowledged_at:
        title: Acknowledged at
        type: string
        format: date-time
        readOnly: true
        x-nullable: true
      completed_at:
        title: Completed at
        type: string
        format: date-time
        readOnly: true
        x-nullable: true
      cancelled_at:
        title: Cancelled at
        type: string
        format: date-time
        readOnly: true
        x-nullable: true
      line_items:
        type: array
        items:
          $ref: '#/definitions/LabOrderLineItem'
        readOnly: true
      created_at:
        title: Created at
        type: string
        format: date-time
        readOnly: true
      updated_at:
        title: Updated at
        type: string
        format: date-time
        readOnly: true
  LabOrderCreate:
    required:
    - patient
    - line_items
    type: object
    properties:
      patient:
        title: Patient
        type: string
        format: uuid
      appointment:
        title: Appointment
        type: string
        format: uuid
        x-nullable: true
      consultation:
        title: Consultation
        type: string
        format: uuid
        x-nullable: true
      clinical_indication:
        title: Clinical indication
        type: string
      patient_instructions:
        title: Patient instructions
        type: string
      laboratory_name:
        title: Laboratory name
        type: string
      line_items:
        type: array
        items:
          type: object
          additionalProperties:
            type: string
            x-nullable: true
        minItems: 1
  LabOrderDraftUpdate:
    type: object
    properties:
      clinical_indication:
        title: Clinical indication
        type: string
      patient_instructions:
        title: Patient instructions
        type: string
      laboratory_name:
        title: Laboratory name
        type: string
      external_accession:
        title: External accession
        type: string
      line_items:
        type: array
        items:
          type: object
          additionalProperties:
            type: string
            x-nullable: true
        minItems: 1
  Allergy:
    required:
    - allergen
    - reaction
    - severity
    type: object
    properties:
      id:
        title: Id
        type: string
        format: uuid
        readOnly: true
      patient:
        title: Patient
        type: string
        format: uuid
        readOnly: true
      allergen:
        title: Allergen
        type: string
        maxLength: 255
        minLength: 1
      reaction:
        title: Reaction
        type: string
        minLength: 1
      severity:
        title: Severity
        type: string
        enum:
        - mild
        - moderate
        - severe
        - life_threatening
      first_observed:
        title: First observed
        type: string
        format: date
        x-nullable: true
      created_at:
        title: Created at
        type: string
        format: date-time
        readOnly: true
  Condition:
    required:
    - condition_name
    - diagnosis_date
    type: object
    properties:
      id:
        title: Id
        type: string
        format: uuid
        readOnly: true
      patient:
        title: Patient
        type: string
        format: uuid
        readOnly: true
      condition_name:
        title: Condition name
        type: string
        maxLength: 255
        minLength: 1
      diagnosis_code:
        title: Diagnosis code
        type: string
        maxLength: 50
      diagnosis_date:
        title: Diagnosis date
        type: string
        format: date
      status:
        title: Status
        type: string
        enum:
        - active
        - resolved
        - chronic
        - monitoring
      notes:
        title: Notes
        type: string
      created_at:
        title: Created at
        type: string
        format: date-time
        readOnly: true
  MedicalRecord:
    required:
    - record_type
    - title
    - record_date
    type: object
    properties:
      id:
        title: Id
        type: string
        format: uuid
        readOnly: true
      record_number:
        title: Record number
        type: string
        readOnly: true
        minLength: 1
      patient:
        title: Patient
        type: string
        format: uuid
        readOnly: true
      provider:
        title: Provider
        type: string
        format: uuid
        readOnly: true
        x-nullable: true
      record_type:
        title: Record type
        type: string
        enum:
        - diagnosis
        - lab_result
        - imaging
        - procedure
        - note
        - discharge
        - referral
      title:
        title: Title
        type: string
        maxLength: 255
        minLength: 1
      description:
        title: Description
        type: string
      diagnosis_code:
        title: Diagnosis code
        description: ICD-10 code
        type: string
        maxLength: 50
      record_date:
        title: Record date
        type: string
        format: date
      effective_date:
        title: Effective date
        type: string
        format: date
        x-nullable: true
      attachments:
        title: Attachments
        description: List of file URLs
        type: object
      is_confidential:
        title: Is confidential
        type: boolean
      tags:
        title: Tags
        type: object
      created_at:
        title: Created at
        type: string
        format: date-time
        readOnly: true
      updated_at:
        title: Updated at
        type: string
        format: date-time
        readOnly: true
  Notification:
    type: object
    properties:
      id:
        title: Id
        type: string
        format: uuid
        readOnly: true
      userId:
        title: Userid
        type: string
        readOnly: true
        minLength: 1
      type:
        title: Type
        type: string
        readOnly: true
        minLength: 1
      title:
        title: Title
        type: string
        readOnly: true
        minLength: 1
      message:
        title: Message
        type: string
        readOnly: true
        minLength: 1
      read:
        title: Read
        type: boolean
      actionUrl:
        title: Actionurl
        type: string
        readOnly: true
      metadata:
        title: Metadata
        type: object
      createdAt:
        title: Createdat
        type: string
        format: date-time
        readOnly: true
  NotificationUpdate:
    type: object
    properties:
      read:
        title: Read
        type: boolean
  OrganizationPaymentPlan:
    required:
    - name
    - price
    type: object
    properties:
      id:
        title: Id
        type: string
        format: uuid
        readOnly: true
      organization:
        title: Organization
        type: string
        format: uuid
        readOnly: true
      name:
        title: Name
        description: Plan name (e.g., Basic, Premium, Family)
        type: string
        maxLength: 100
        minLength: 1
      description:
        title: Description
        description: Optional plan description
        type: string
      price:
        title: Price
        description: Plan price
        type: string
        format: decimal
      currency:
        title: Currency
        type: string
        default: NGN
        minLength: 1
      features:
        title: Features
        description: List of included features (e.g., 'Unlimited consultations')
        type: object
      billing_cycle:
        title: Billing cycle
        description: Billing cycle for this plan
        type: string
        enum:
        - monthly
        - annually
      max_patients:
        title: Max patients
        description: Maximum number of patients allowed under this subscription plan
          (null for unlimited)
        type: integer
        maximum: 2147483647
        minimum: 0
        x-nullable: true
      max_appointments:
        title: Max appointments
        description: Maximum number of appointments per month (null for unlimited)
        type: integer
        maximum: 2147483647
        minimum: 0
        x-nullable: true
      is_active:
        title: Is active
        type: boolean
      display_order:
        title: Display order
        description: Display order (lower = shown first)
        type: integer
        maximum: 2147483647
        minimum: -2147483648
      created_at:
        title: Created at
        type: string
        format: date-time
        readOnly: true
      updated_at:
        title: Updated at
        type: string
        format: date-time
        readOnly: true
  OrganizationPricing:
    required:
    - organization
    - service_type
    - price
    type: object
    properties:
      id:
        title: Id
        type: string
        format: uuid
        readOnly: true
      organization:
        title: Organization
        type: string
        format: uuid
      service_type:
        title: Service type
        description: Service type (e.g., 'consultation', 'follow_up', 'emergency')
        type: string
        maxLength: 50
        minLength: 1
      price:
        title: Price
        description: Price in NGN
        type: string
        format: decimal
      currency:
        title: Currency
        type: string
        maxLength: 3
        minLength: 1
      is_active:
        title: Is active
        type: boolean
      created_at:
        title: Created at
        type: string
        format: date-time
        readOnly: true
      updated_at:
        title: Updated at
        type: string
        format: date-time
        readOnly: true
  Prescription:
    required:
    - medication_name
    - dosage
    - frequency
    - duration_days
    - quantity
    - prescribed_date
    type: object
    properties:
      id:
        title: Id
        type: string
        format: uuid
        readOnly: true
      prescription_number:
        title: Prescription number
        type: string
        readOnly: true
        minLength: 1
      consultation:
        title: Consultation
        type: string
        format: uuid
        readOnly: true
        x-nullable: true
      patient:
        title: Patient
        type: string
        format: uuid
        readOnly: true
      provider:
        title: Provider
        type: string
        format: uuid
        readOnly: true
      medication_name:
        title: Medication name
        type: string
        maxLength: 255
        minLength: 1
      dosage:
        title: Dosage
        type: string
        maxLength: 100
        minLength: 1
      frequency:
        title: Frequency
        description: e.g., 'twice daily', 'as needed'
        type: string
        maxLength: 100
        minLength: 1
      duration_days:
        title: Duration days
        description: Duration in days
        type: integer
        maximum: 2147483647
        minimum: -2147483648
      quantity:
        title: Quantity
        type: string
        maxLength: 50
        minLength: 1
      instructions:
        title: Instructions
        type: string
      status:
        title: Status
        type: string
        enum:
        - active
        - completed
        - cancelled
        - expired
      prescribed_date:
        title: Prescribed date
        type: string
        format: date
      start_date:
        title: Start date
        type: string
        format: date
        x-nullable: true
      end_date:
        title: End date
        type: string
        format: date
        x-nullable: true
      refills_remaining:
        title: Refills remaining
        type: integer
        maximum: 2147483647
        minimum: -2147483648
      max_refills:
        title: Max refills
        type: integer
        maximum: 2147483647
        minimum: -2147483648
      created_at:
        title: Created at
        type: string
        format: date-time
        readOnly: true
  UserCreation:
    required:
    - email
    - first_name
    - last_name
    - password
    - password_confirm
    - role
    type: object
    properties:
      id:
        title: Id
        type: string
        format: uuid
        readOnly: true
      email:
        title: Email
        type: string
        format: email
        maxLength: 254
        minLength: 1
      phone_number:
        title: Phone number
        type: string
        maxLength: 20
        x-nullable: true
      first_name:
        title: First name
        type: string
        maxLength: 150
      last_name:
        title: Last name
        type: string
        maxLength: 150
      password:
        title: Password
        type: string
        minLength: 8
      password_confirm:
        title: Password confirm
        type: string
        minLength: 8
      role:
        title: Role
        type: string
        enum:
        - patient
        - provider
        - admin
        - owner
        - support
  TokenObtainPair:
    required:
    - email
    - password
    type: object
    properties:
      email:
        title: Email
        type: string
        minLength: 1
      password:
        title: Password
        type: string
        minLength: 1
  UserRegistration:
    required:
    - email
    - first_name
    - last_name
    - password
    - password_confirm
    type: object
    properties:
      id:
        title: Id
        type: string
        format: uuid
        readOnly: true
      email:
        title: Email
        type: string
        format: email
        maxLength: 254
        minLength: 1
      phone_number:
        title: Phone number
        type: string
        maxLength: 20
        x-nullable: true
      first_name:
        title: First name
        type: string
        maxLength: 150
      last_name:
        title: Last name
        type: string
        maxLength: 150
      password:
        title: Password
        type: string
        minLength: 8
      password_confirm:
        title: Password confirm
        type: string
        minLength: 8
      role:
        title: Role
        type: string
        enum:
        - patient
        - provider
        - admin
        - owner
        - support
      org_slug:
        title: Org slug
        type: string
  TokenRefresh:
    required:
    - refresh
    type: object
    properties:
      refresh:
        title: Refresh
        type: string
        minLength: 1
      access:
        title: Access
        type: string
        readOnly: true
        minLength: 1
  VitalSign:
    required:
    - patient
    - vital_type
    - value
    - measured_at
    type: object
    properties:
      id:
        title: Id
        type: string
        format: uuid
        readOnly: true
      patient:
        title: Patient
        type: string
        format: uuid
      vital_type:
        title: Vital type
        type: string
        enum:
        - blood_pressure
        - heart_rate
        - temperature
        - glucose
        - weight
        - height
        - oxygen_saturation
        - respiratory_rate
      value:
        title: Value
        description: Primary value
        type: string
        format: decimal
      value_secondary:
        title: Value secondary
        description: Secondary value (e.g., diastolic BP)
        type: string
        format: decimal
        x-nullable: true
      unit:
        title: Unit
        type: string
        maxLength: 20
        minLength: 1
      measured_at:
        title: Measured at
        type: string
        format: date-time
      measured_by:
        title: Measured by
        description: Who measured (patient, provider, device)
        type: string
        maxLength: 50
      device_type:
        title: Device type
        type: string
        maxLength: 50
      notes:
        title: Notes
        type: string
      created_at:
        title: Created at
        type: string
        format: date-time
        readOnly: true
