openapi: 3.0.3
info:
  title: SmartScanPro.ai API
  description: |
    SmartScanPro turns a photo of a medical device or a clinical document
    into clean, validated, FHIR-ready structured JSON. One endpoint, 15+
    device and document types, sub-second latency, HIPAA-aligned infrastructure.

    **Base URL**: `https://api.smartscanpro.ai`

    **Authentication**: All requests require an API key issued from the
    SmartScanPro dashboard. Pass it via the `Authorization: Bearer`
    header (preferred) or the `X-API-Key` header.
  version: 1.0.0
  contact:
    name: SmartScanPro Support
    email: support@smartscanpro.ai
    url: https://smartscanpro.ai/contact.html
  license:
    name: Proprietary
    url: https://smartscanpro.ai/

servers:
  - url: https://api.smartscanpro.ai
    description: Production

security:
  - bearerAuth: []
  - apiKeyHeader: []

tags:
  - name: Extraction
    description: Extract structured data from a device image or clinical document.
  - name: Metadata
    description: Supported device types and service health.

paths:

  /api/v1/extract-medical-data:
    post:
      tags: [Extraction]
      operationId: extractMedicalData
      summary: Extract structured vitals from a medical device or clinical document image.
      description: |
        Accepts a single image (JPEG / PNG / GIF / WebP, ≤ 10 MB) and returns a
        canonical JSON envelope of extracted fields with per-field confidence
        scores. Optionally returns a FHIR R4 `Bundle` of `Observation`
        resources with LOINC codes ready to post to an EHR.
      requestBody:
        required: true
        content:
          multipart/form-data:
            schema:
              type: object
              required: [deviceImage]
              properties:
                deviceImage:
                  type: string
                  format: binary
                  description: The device display or document image.
                deviceType:
                  type: string
                  description: Optional hint. Use `auto-detect` to let the service identify the device.
                  enum:
                    - auto-detect
                    - blood-pressure
                    - glucose-meter
                    - pulse-oximeter
                    - thermometer
                    - scale
                    - peak-flow-meter
                    - ecg-monitor
                    - covid-test-strip
                    - pregnancy-kit
                    - dialysis-machine
                    - vaccine-certificate
                    - prescription
                    - discharge-summary
                    - clinical-notes
                    - progress-notes
                    - imaging-reports
                  default: auto-detect
                confidenceThreshold:
                  type: number
                  minimum: 0
                  maximum: 1
                  description: Fields below this threshold are returned but flagged.
                includeFhir:
                  type: boolean
                  default: false
                  description: When true, the response includes a FHIR R4 Bundle under `fhir`.
      responses:
        '200':
          description: Extraction succeeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ExtractionResponse'
              examples:
                bloodPressure:
                  summary: Blood pressure monitor
                  value:
                    success: true
                    deviceType: blood-pressure
                    data:
                      systolic:  { value: 128, unit: mmHg, confidence: 0.996 }
                      diastolic: { value: 91,  unit: mmHg, confidence: 0.993 }
                      pulse:     { value: 76,  unit: bpm,  confidence: 0.988 }
                    confidence: 0.988
                    timestamp: "2026-04-20T14:32:07Z"
                    processingTime: 487
                pulseOximeter:
                  summary: Pulse oximeter
                  value:
                    success: true
                    deviceType: pulse-oximeter
                    data:
                      spo2:  { value: 99, unit: "%",  confidence: 0.994 }
                      pulse: { value: 65, unit: bpm,  confidence: 0.991 }
                    confidence: 0.991
                    timestamp: "2026-04-20T14:34:11Z"
                    processingTime: 412
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '413':
          $ref: '#/components/responses/PayloadTooLarge'
        '429':
          $ref: '#/components/responses/RateLimited'
        '500':
          $ref: '#/components/responses/ServerError'

  /api/device-types:
    get:
      tags: [Metadata]
      operationId: listDeviceTypes
      summary: List supported device and document types.
      security: []
      responses:
        '200':
          description: List of supported device types.
          content:
            application/json:
              schema:
                type: object
                properties:
                  success: { type: boolean, example: true }
                  supportedDevices:
                    type: array
                    items:
                      type: object
                      properties:
                        type:        { type: string, example: blood-pressure }
                        name:        { type: string, example: Blood Pressure Monitor }
                        description: { type: string, example: Extracts systolic/diastolic pressure and pulse rate }

  /api/health:
    get:
      tags: [Metadata]
      operationId: health
      summary: Service health check.
      security: []
      responses:
        '200':
          description: Service is healthy.
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:    { type: string, example: healthy }
                  version:   { type: string, example: "1.0.0" }
                  timestamp: { type: string, format: date-time }

components:

  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: API key (begins with `dk_`)
      description: Pass your SmartScanPro API key as `Authorization: Bearer dk_...`.
    apiKeyHeader:
      type: apiKey
      in: header
      name: X-API-Key
      description: Alternative to bearer auth. Pass `X-API-Key: dk_...`.

  schemas:

    ExtractionResponse:
      type: object
      required: [success, deviceType, data, confidence, timestamp, processingTime]
      properties:
        success:       { type: boolean, example: true }
        deviceType:    { type: string, example: blood-pressure }
        data:
          type: object
          description: Per-device fields. Keys vary by device type; every field is a value/unit/confidence object.
          additionalProperties:
            $ref: '#/components/schemas/Measurement'
        fhir:
          type: object
          description: Optional FHIR R4 Bundle of Observation resources with LOINC codes. Present when `includeFhir=true` or on pro/enterprise plans.
        confidence:    { type: number, format: float, minimum: 0, maximum: 1, example: 0.988 }
        timestamp:     { type: string, format: date-time }
        processingTime:
          type: integer
          description: Server-side processing time in milliseconds.
          example: 487

    Measurement:
      type: object
      required: [value, unit, confidence]
      properties:
        value:      { oneOf: [ { type: number }, { type: string } ], example: 128 }
        unit:       { type: string, example: mmHg }
        confidence: { type: number, format: float, minimum: 0, maximum: 1, example: 0.996 }

    ErrorResponse:
      type: object
      required: [success, error]
      properties:
        success: { type: boolean, example: false }
        error:   { type: string, example: Invalid or missing API key }
        details: { type: string }
        code:    { type: string, example: unauthorized }

  responses:

    BadRequest:
      description: Request was malformed (missing image, invalid device type, etc.).
      content:
        application/json:
          schema: { $ref: '#/components/schemas/ErrorResponse' }
    Unauthorized:
      description: API key missing, invalid, or expired.
      content:
        application/json:
          schema: { $ref: '#/components/schemas/ErrorResponse' }
    PayloadTooLarge:
      description: Image exceeds 10 MB.
      content:
        application/json:
          schema: { $ref: '#/components/schemas/ErrorResponse' }
    RateLimited:
      description: Rate limit exceeded.
      headers:
        Retry-After:
          schema: { type: integer }
          description: Seconds until the next request is permitted.
      content:
        application/json:
          schema: { $ref: '#/components/schemas/ErrorResponse' }
    ServerError:
      description: Unexpected server error.
      content:
        application/json:
          schema: { $ref: '#/components/schemas/ErrorResponse' }
