openapi: 3.1.0
info:
  title: NovaMed Partner API
  version: 1.0.0
  description: >
    The NovaMed Partner API enables healthcare partners to integrate with
    NovaMed for patient care management, prescription fulfillment, and order
    tracking.


    **Authentication:** All requests require an `x-api-key` header with your API
    key.


    **Base URLs:**

    - Development: `https://novamed-feapidev.stackmod.info`

    - Production: `https://feapi.novamed.care`


    For detailed guides, see the [Getting Started](/guides/quickstart)
    documentation.
  contact:
    name: NovaMed API Support
    email: api@nimbus-os.com
  license:
    name: API License Terms & Conditions
    url: https://developer.nimbus-os.com/api-terms
servers:
  - url: https://novamed-feapidev.stackmod.info
    description: Development environment
  - url: https://feapi.novamed.care
    description: Production environment
security:
  - ApiKeyAuth: []
tags:
  - name: Practitioners
    description: Manage practitioners (doctors, veterinarians) in the system
  - name: Patients
    description: Patient registration and management
  - name: Medication Requests
    description: Medication order management
  - name: Refills
    description: Prescription refill request management
  - name: Webhooks
    description: Webhook configuration for receiving event notifications
paths:
  /api/external/practitioner:
    post:
      tags:
        - Practitioners
      summary: Create Practitioner
      description: >
        Creates a new practitioner (doctor or veterinarian) in the system. This
        endpoint is used to onboard practitioners by collecting their personal,
        professional, and contact information.


        **Notes:**

        - All required fields must be provided and valid

        - `assigned_clinic` must reference an existing clinic UUID

        - Validation errors will return descriptive messages for each field
      operationId: createPractitioner
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PractitionerRequest'
            examples:
              basic:
                summary: Create a new practitioner
                value:
                  first_name: Sarah
                  last_name: Johnson
                  email: dr.johnson@partnerclinic.com
                  phone: +1-555-0123
                  npi_number: '1234567890'
                  dea_number: FJ1234563
                  license_number: MD-12345
                  license_state: CA
                  signature_image: base64_encoded_image_string
                  assigned_clinic: 550e8400-e29b-41d4-a716-446655440000
      responses:
        '200':
          description: Practitioner created successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PractitionerResponse'
              examples:
                success:
                  summary: Successful creation
                  value:
                    success: true
                    data:
                      practitioner_id: 660e8400-e29b-41d4-a716-446655440001
                    message: Practitioner created successfully
        '400':
          description: Bad request (validation error)
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '401':
          description: Unauthorized (missing or invalid API key)
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
  /api/external/patient:
    post:
      tags:
        - Patients
      summary: Create Patient
      description: |
        Register a new patient in NovaMed under your partner account.

        **Notes:**
        - All required fields must be provided
        - `clinic_id` must reference an existing clinic UUID
        - Address information is required for shipping
      operationId: createPatient
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PatientRequest'
            examples:
              basic:
                summary: Create a new patient
                value:
                  clinic_id: 550e8400-e29b-41d4-a716-446655440000
                  first_name: John
                  last_name: Smith
                  date_of_birth: '1985-03-15'
                  gender: male
                  email: john.smith@email.com
                  phone: +1-555-0199
                  address_line1: 123 Main Street
                  address_line2: Apt 4B
                  city: San Francisco
                  state: CA
                  zip: '94102'
      responses:
        '200':
          description: Patient created successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PatientResponse'
              examples:
                success:
                  summary: Successful creation
                  value:
                    success: true
                    data:
                      patient_id: 770e8400-e29b-41d4-a716-446655440002
                    message: Patient created successfully
        '400':
          description: Bad request (validation error)
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
  /api/external/medication-request:
    post:
      tags:
        - Medication Requests
      summary: Create Medication Request
      description: >
        Create a new medication request for a patient. This endpoint initiates
        the prescription and fulfillment process.


        **Notes:**

        - Patient and practitioner must already exist in the system

        - Medication details must be valid

        - The request will be validated against the clinic's available
        medications
      operationId: createMedicationRequest
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/MedicationRequest'
            examples:
              basic:
                summary: Create medication request
                value:
                  clinic_id: 550e8400-e29b-41d4-a716-446655440000
                  patient_id: 770e8400-e29b-41d4-a716-446655440002
                  practitioner_id: 660e8400-e29b-41d4-a716-446655440001
                  medication_name: Testosterone Cypionate
                  medication_strength: 200mg/ml
                  quantity: 1
                  refills: 3
                  days_supply: 30
                  instructions: Inject 0.5ml (100mg) intramuscularly twice weekly
      responses:
        '200':
          description: Medication request created successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/MedicationRequestResponse'
              examples:
                success:
                  summary: Successful creation
                  value:
                    success: true
                    data:
                      medication_request_id: 880e8400-e29b-41d4-a716-446655440003
                    message: Medication request created successfully
        '400':
          description: Bad request (validation error)
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: Patient or practitioner not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
  /api/external/refill-request:
    post:
      tags:
        - Refills
      summary: Create Refill Request
      description: >
        Request a refill for an existing medication order that has been shipped
        or delivered.


        **Eligibility Requirements:**

        - Medication must have been shipped or delivered

        - Refills must be authorized on the original prescription

        - No pending refill request already exists


        The refill request will create a new prescription and medication order
        automatically.
      operationId: createRefillRequest
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/RefillRequest'
            examples:
              basic:
                summary: Basic refill request
                value:
                  medication_request_id: 880e8400-e29b-41d4-a716-446655440003
      responses:
        '200':
          description: Refill request created successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RefillResponse'
              examples:
                success:
                  summary: Successful refill request
                  value:
                    success: true
                    message: Refill request was created successfully.
                    data:
                      refill_request_id: 990e8400-e29b-41d4-a716-446655440004
                      medication_order_id: aa0e8400-e29b-41d4-a716-446655440005
        '400':
          description: Bad request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              examples:
                medicationNotFound:
                  summary: Medication request not found
                  value:
                    success: false
                    error:
                      message: Medication request not found
                notEligible:
                  summary: Refill not eligible
                  value:
                    success: false
                    error:
                      message: Refills are not possible for pending medication requests
                duplicateRefill:
                  summary: Duplicate refill request
                  value:
                    success: false
                    error:
                      message: Refill request already exists
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
  /api/external/webhook:
    post:
      tags:
        - Webhooks
      summary: Register Webhook
      description: >
        Register a webhook URL to receive real-time event notifications.


        Once registered, you will receive webhook events for:

        - Shipment creation and updates

        - Prescription status changes

        - Medication order status updates


        Webhooks are sent via HTTPS POST requests with an `x-api-key` header for
        authentication.
      operationId: createWebhook
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/WebhookRequest'
            examples:
              basic:
                summary: Basic webhook registration
                value:
                  clinic_id: 550e8400-e29b-41d4-a716-446655440000
                  webhook_url: https://partner.example.com/webhooks/novamed
      responses:
        '200':
          description: Webhook registered successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WebhookResponse'
              examples:
                success:
                  summary: Successful webhook registration
                  value:
                    success: true
                    data:
                      webhook_id: bb0e8400-e29b-41d4-a716-446655440006
                    message: Webhook created successfully
        '400':
          description: Bad request (validation error or clinic not found)
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '401':
          description: Unauthorized (missing or invalid API key)
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
    delete:
      tags:
        - Webhooks
      summary: Delete Webhook
      description: >
        Remove a webhook configuration. The webhook will stop receiving events
        immediately.
      operationId: deleteWebhook
      parameters:
        - name: id
          in: query
          required: true
          description: Webhook ID to delete
          schema:
            type: string
            format: uuid
            example: bb0e8400-e29b-41d4-a716-446655440006
      responses:
        '200':
          description: Webhook deleted successfully
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    example: true
                  message:
                    type: string
                    example: Webhook deleted successfully
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: Webhook not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
components:
  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      in: header
      name: x-api-key
      description: >-
        Partner API key for authentication. Contact api@nimbus-os.com to obtain
        your API key.
  schemas:
    PractitionerRequest:
      type: object
      required:
        - first_name
        - last_name
        - email
        - npi_number
        - assigned_clinic
      properties:
        first_name:
          type: string
          description: Practitioner's first name
          example: Sarah
        last_name:
          type: string
          description: Practitioner's last name
          example: Johnson
        email:
          type: string
          format: email
          description: Practitioner's email address
          example: dr.johnson@partnerclinic.com
        phone:
          type: string
          description: Practitioner's phone number
          example: +1-555-0123
        npi_number:
          type: string
          description: National Provider Identifier (10 digits)
          example: '1234567890'
        dea_number:
          type: string
          description: DEA registration number
          example: FJ1234563
        license_number:
          type: string
          description: State medical license number
          example: MD-12345
        license_state:
          type: string
          description: State of licensure (2-letter code)
          example: CA
        signature_image:
          type: string
          description: Base64 encoded signature image
        assigned_clinic:
          type: string
          format: uuid
          description: UUID of the clinic to assign this practitioner
          example: 550e8400-e29b-41d4-a716-446655440000
    PatientRequest:
      type: object
      required:
        - clinic_id
        - first_name
        - last_name
        - date_of_birth
        - email
      properties:
        clinic_id:
          type: string
          format: uuid
          description: UUID of the clinic
          example: 550e8400-e29b-41d4-a716-446655440000
        first_name:
          type: string
          description: Patient's first name
          example: John
        last_name:
          type: string
          description: Patient's last name
          example: Smith
        date_of_birth:
          type: string
          format: date
          description: Patient's date of birth (YYYY-MM-DD)
          example: '1985-03-15'
        gender:
          type: string
          enum:
            - male
            - female
            - other
          description: Patient's gender
          example: male
        email:
          type: string
          format: email
          description: Patient's email address
          example: john.smith@email.com
        phone:
          type: string
          description: Patient's phone number
          example: +1-555-0199
        address_line1:
          type: string
          description: Street address line 1
          example: 123 Main Street
        address_line2:
          type: string
          description: Street address line 2 (optional)
          example: Apt 4B
        city:
          type: string
          description: City
          example: San Francisco
        state:
          type: string
          description: State (2-letter code)
          example: CA
        zip:
          type: string
          description: ZIP/Postal code
          example: '94102'
    MedicationRequest:
      type: object
      required:
        - clinic_id
        - patient_id
        - practitioner_id
        - medication_name
        - quantity
      properties:
        clinic_id:
          type: string
          format: uuid
          description: UUID of the clinic
          example: 550e8400-e29b-41d4-a716-446655440000
        patient_id:
          type: string
          format: uuid
          description: UUID of the patient
          example: 770e8400-e29b-41d4-a716-446655440002
        practitioner_id:
          type: string
          format: uuid
          description: UUID of the prescribing practitioner
          example: 660e8400-e29b-41d4-a716-446655440001
        medication_name:
          type: string
          description: Name of the medication
          example: Testosterone Cypionate
        medication_strength:
          type: string
          description: Medication strength/concentration
          example: 200mg/ml
        quantity:
          type: integer
          description: Quantity to dispense
          example: 1
        refills:
          type: integer
          description: Number of refills authorized
          example: 3
        days_supply:
          type: integer
          description: Days supply per fill
          example: 30
        instructions:
          type: string
          description: Dosing instructions for the patient
          example: Inject 0.5ml (100mg) intramuscularly twice weekly
    RefillRequest:
      type: object
      required:
        - medication_request_id
      properties:
        medication_request_id:
          type: string
          format: uuid
          description: UUID of the medication request to refill
          example: 880e8400-e29b-41d4-a716-446655440003
        shipment_group_id:
          type: string
          description: Optional shipment group ID for grouping multiple refills
          example: optional-group-id
    WebhookRequest:
      type: object
      required:
        - clinic_id
        - webhook_url
      properties:
        clinic_id:
          type: string
          format: uuid
          description: UUID of the clinic associated with this webhook
          example: 550e8400-e29b-41d4-a716-446655440000
        webhook_url:
          type: string
          format: uri
          description: HTTPS URL where webhook events will be sent
          example: https://partner.example.com/webhooks/novamed
    PractitionerResponse:
      type: object
      properties:
        success:
          type: boolean
          example: true
        data:
          type: object
          properties:
            practitioner_id:
              type: string
              format: uuid
              description: Unique identifier for the created practitioner
              example: 660e8400-e29b-41d4-a716-446655440001
        message:
          type: string
          example: Practitioner created successfully
    PatientResponse:
      type: object
      properties:
        success:
          type: boolean
          example: true
        data:
          type: object
          properties:
            patient_id:
              type: string
              format: uuid
              description: Unique identifier for the created patient
              example: 770e8400-e29b-41d4-a716-446655440002
        message:
          type: string
          example: Patient created successfully
    MedicationRequestResponse:
      type: object
      properties:
        success:
          type: boolean
          example: true
        data:
          type: object
          properties:
            medication_request_id:
              type: string
              format: uuid
              description: Unique identifier for the medication request
              example: 880e8400-e29b-41d4-a716-446655440003
        message:
          type: string
          example: Medication request created successfully
    RefillResponse:
      type: object
      properties:
        success:
          type: boolean
          example: true
        message:
          type: string
          example: Refill request was created successfully.
        data:
          type: object
          properties:
            refill_request_id:
              type: string
              format: uuid
              description: Unique identifier for the refill request
              example: 990e8400-e29b-41d4-a716-446655440004
            medication_order_id:
              type: string
              format: uuid
              description: Unique identifier for the new medication order
              example: aa0e8400-e29b-41d4-a716-446655440005
    WebhookResponse:
      type: object
      properties:
        success:
          type: boolean
          example: true
        data:
          type: object
          properties:
            webhook_id:
              type: string
              format: uuid
              description: Unique identifier for the registered webhook
              example: bb0e8400-e29b-41d4-a716-446655440006
        message:
          type: string
          example: Webhook created successfully
    ErrorResponse:
      type: object
      properties:
        success:
          type: boolean
          example: false
        error:
          type: object
          properties:
            message:
              type: string
              description: Human-readable error message
              example: Validation error
            details:
              type: object
              description: Additional error details
              example: {}
    WebhookEvent:
      type: object
      description: Base structure for all webhook events sent to partners
      properties:
        event_name:
          type: string
          description: Type of webhook event
          enum:
            - shipment:created
            - shipment:cancelled
            - medication:updated
        event_data:
          type: object
          description: Event-specific data payload
    ShipmentCreatedEvent:
      allOf:
        - $ref: '#/components/schemas/WebhookEvent'
        - type: object
          properties:
            event_name:
              type: string
              example: shipment:created
            event_data:
              type: object
              properties:
                shipment_id:
                  type: string
                  format: uuid
                  description: Unique identifier for the shipment
                medication_orders:
                  type: array
                  items:
                    type: string
                    format: uuid
                  description: Array of medication order IDs in this shipment
                shipment_status:
                  type: string
                  description: Current status of the shipment
                  example: pending
                shipped_at:
                  type: string
                  format: date-time
                  description: Timestamp when shipment was created
                tracking_number:
                  type: string
                  description: Carrier tracking number
                  example: 1Z999AA10123456784
                tracking_url:
                  type: string
                  format: uri
                  description: URL to track the shipment
                shipping_partner:
                  type: string
                  description: Shipping carrier name
                  example: FedEx
                delivery_method:
                  type: string
                  description: Delivery method
                  example: next-day
    MedicationUpdatedEvent:
      allOf:
        - $ref: '#/components/schemas/WebhookEvent'
        - type: object
          properties:
            event_name:
              type: string
              example: medication:updated
            event_data:
              type: object
              properties:
                medication_order_id:
                  type: string
                  format: uuid
                prescription_id:
                  type: string
                  format: uuid
                medication_request_id:
                  type: string
                  format: uuid
                status:
                  type: string
                  description: New status of the medication
                  enum:
                    - validated
                    - submitted
                    - filled
                    - shipped
                    - delivered
                    - cancelled
                  example: shipped
                previous_status:
                  type: string
                  description: Previous status before update
                updated_at:
                  type: string
                  format: date-time
                tracking_number:
                  type: string
                  description: Tracking number (if shipped)
