openapi: 3.0.3
info:
  title: Order Fulfillment API
  description: >-
    API for managing healthcare product orders and inventory within the Juniper
    Health network.
  version: 1.0.1
  contact:
    name: Juniper Health Engineering Team
    email: engineering@juniperhealth.com
  termsOfService: https://www.juniperhealth.com/terms-of-service-professionals
servers:
  - url: https://api.fulfillment.sandbox.juniperhealth.com/v1
    description: Sandbox API Server for testing
  - url: https://auth.fulfillment.sandbox.juniperhealth.com/oauth2/token
    description: Sandbox Auth Server for testing
  - url: https://api.fulfillment.juniperhealth.com/v1
    description: Production API Server
  - url: https://auth.fulfillment.juniperhealth.com/oauth2/token
    description: Production Auth Server
tags:
  - name: Authentication
    description: OAuth 2.0 token management
  - name: Orders
    description: Create, retrieve, and manage customer orders
  - name: Products
    description: Access product catalog and inventory details
  - name: Shipping
    description: Retrieve available shipping methods
paths:
  /oauth2/token:
    post:
      operationId: getAccessToken
      summary: Obtain OAuth 2.0 Access Token
      description: Exchange client credentials for an access token
      tags:
        - Authentication
      requestBody:
        required: true
        content:
          application/x-www-form-urlencoded:
            schema:
              type: object
              required:
                - grant_type
                - client_id
                - client_secret
              properties:
                grant_type:
                  type: string
                  enum:
                    - client_credentials
                  default: client_credentials
                client_id:
                  type: string
                  description: API client identifier
                client_secret:
                  type: string
                  description: API client secret
      responses:
        '200':
          description: Successfully obtained access token
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TokenResponse'
        '400':
          description: Authentication failed
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AuthError'
  /orders:
    post:
      operationId: createOrder
      summary: Create a New Order
      description: Submit a new customer order with product line items and shipping details
      tags:
        - Orders
      security:
        - oauth2ClientCredentials: []
      requestBody:
        $ref: '#/components/requestBodies/CreateOrder'
      responses:
        '201':
          description: Order successfully created
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Order'
        '400':
          $ref: '#/components/responses/BadRequest'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
    get:
      operationId: listOrders
      summary: Retrieve Orders
      description: Retrieve a list of orders with optional filtering
      tags:
        - Orders
      security:
        - oauth2ClientCredentials: []
      parameters:
        - $ref: '#/components/parameters/PageLimit'
        - $ref: '#/components/parameters/PageCursor'
        - $ref: '#/components/parameters/PageDirection'
        - $ref: '#/components/parameters/OrderStatus'
      responses:
        '200':
          description: Successfully retrieved orders
          content:
            application/json:
              schema:
                type: object
                properties:
                  orders:
                    type: array
                    items:
                      $ref: '#/components/schemas/Order'
                  cursor:
                    $ref: '#/components/schemas/Cursor'
        '400':
          $ref: '#/components/responses/BadRequest'
  /orders/{orderId}:
    get:
      operationId: getOrderById
      summary: Retrieve Order Details
      description: Get detailed information for a specific order
      tags:
        - Orders
      security:
        - oauth2ClientCredentials: []
      parameters:
        - name: orderId
          in: path
          required: true
          schema:
            type: string
            example: 77123129891
      responses:
        '200':
          description: Successfully retrieved order details
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Order'
        '404':
          $ref: '#/components/responses/NotFound'
  /orders/{orderId}/cancel:
    get:
      operationId: cancelOrder
      summary: Cancel an Order
      description: Cancel an order that has not yet entered processing
      tags:
        - Orders
      security:
        - oauth2ClientCredentials: []
      parameters:
        - name: orderId
          in: path
          required: true
          schema:
            type: string
            example: 2vTgd30JFgnwLrgb383PcV9Rken
      responses:
        '204':
          description: Order successfully cancelled
          $ref: '#/components/responses/OrderCancelled'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          description: Order cannot be cancelled due to current status
  /products:
    get:
      operationId: listProducts
      summary: Get Product Catalog
      description: Retrieve paginated list of available products
      tags:
        - Products
      security:
        - oauth2ClientCredentials: []
      parameters:
        - $ref: '#/components/parameters/PageLimit'
        - $ref: '#/components/parameters/PageCursor'
        - $ref: '#/components/parameters/PageDirection'
        - $ref: '#/components/parameters/ProductStatus'
        - $ref: '#/components/parameters/ProductUpdatedAfter'
        - $ref: '#/components/parameters/ProductUpdatedBefore'
      responses:
        '200':
          description: Successfully retrieved product catalog
          content:
            application/json:
              schema:
                type: object
                properties:
                  products:
                    type: array
                    items:
                      $ref: '#/components/schemas/Product'
                  cursor:
                    $ref: '#/components/schemas/Cursor'
        '400':
          $ref: '#/components/responses/BadRequest'
  /products/{productId}:
    get:
      operationId: getProductById
      summary: Get Product Details
      description: Retrieve detailed information for a specific product
      tags:
        - Products
      security:
        - oauth2ClientCredentials: []
      parameters:
        - name: productId
          in: path
          required: true
          schema:
            type: integer
            example: 77123129891
      responses:
        '200':
          description: Successfully retrieved product details
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Product'
        '404':
          $ref: '#/components/responses/NotFound'
  /shipping-methods:
    get:
      operationId: listShippingMethods
      summary: Get Available Shipping Methods
      description: Retrieve list of available shipping methods with details
      tags:
        - Shipping
      security:
        - oauth2ClientCredentials: []
      responses:
        '200':
          description: Successfully retrieved shipping methods
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/ShippingMethod'
components:
  parameters:
    StatusFilter:
      name: status
      in: query
      description: Filter orders by status
      schema:
        type: string
        enum:
          - CREATED
          - CANCELLED
          - PROCESSING
          - FULFILLED
          - AWAITING_SHIPMENT
          - SHIPPED
    StartDateFilter:
      name: startDate
      in: query
      description: Filter results from this date
      schema:
        type: string
        format: date
    EndDateFilter:
      name: endDate
      in: query
      description: Filter results up to this date
      schema:
        type: string
        format: date
    PageLimit:
      name: limit
      in: query
      description: Maximum number of results per page
      schema:
        type: integer
        minimum: 1
        maximum: 100
        default: 10
    PageCursor:
      name: cursor
      in: query
      description: Pagination cursor for retrieving next/previous page
      schema:
        type: string
    PageDirection:
      name: direction
      in: query
      description: Direction for pagination (next or previous)
      schema:
        type: string
        enum:
          - next
          - previous
    ProductStatus:
      name: status
      in: query
      description: Filter products by status
      schema:
        type: string
        enum:
          - ACTIVE
          - DRAFT
          - BACKORDERED
          - DISCONTINUED
    ProductUpdatedAfter:
      name: updatedAfter
      in: query
      description: Filter products updated after this date
      schema:
        type: string
        format: date
        example: '2023-10-01'
    ProductUpdatedBefore:
      name: updatedBefore
      in: query
      description: Filter products updated before this date
      schema:
        type: string
        format: date
        example: '2023-10-01'
    OrderStatus:
      name: status
      in: query
      description: Filter orders by status
      schema:
        type: string
        enum:
          - CREATED
          - CANCELLED
          - PROCESSING
          - FULFILLED
          - AWAITING_SHIPMENT
          - SHIPPED
  requestBodies:
    CreateOrder:
      description: Order details to be created in the system
      required: true
      content:
        application/json:
          schema:
            type: object
            required:
              - customer
              - daysSupply
              - lineItems
              - shippingMethod
              - orderType
            properties:
              customer:
                type: object
                description: Customer information for the order
                required:
                  - sourceId
                  - firstName
                  - lastName
                  - address
                properties:
                  sourceId:
                    type: string
                    description: Unique customer identifier in your system
                    example: '1234567890'
                  firstName:
                    type: string
                    description: Customer's first name
                    example: John
                  lastName:
                    type: string
                    description: Customer's last name
                    example: Doe
                  email:
                    type: string
                    format: email
                    description: Customer's email address
                    example: john.doe@example.com
                  phone:
                    type: string
                    description: Customer's phone number
                    example: '1234567890'
                  address:
                    $ref: '#/components/schemas/Address'
              daysSupply:
                type: integer
                description: Number of days the order is intended to supply
                enum:
                  - 30
                  - 60
                  - 90
              lineItems:
                type: array
                description: Products included in the order
                minItems: 1
                items:
                  type: object
                  required:
                    - productId
                    - quantity
                    - packDescription
                  properties:
                    productId:
                      type: integer
                      description: Unique identifier of the product
                      example: 77123129891
                    quantity:
                      type: integer
                      description: Quantity of the product
                      minimum: 1
                      example: 2
                    packDescription:
                      type: string
                      description: Description of the product packaging
                      example: Whole Body Wellness
                    administration:
                      $ref: '#/components/schemas/Administration'
              shippingMethod:
                type: string
                description: Shipping method for the order
                enum:
                  - STANDARD
                  - EXPRESS
                  - OVERNIGHT
                example: STANDARD
              orderType:
                type: string
                description: >-
                  Type or order (this is currently only used for inventory
                  forecasting by Juniper)
                enum:
                  - ONE_TIME
                  - SUBSCRIPTION
                example: ONE_TIME
  responses:
    Ok:
      description: Successful operation
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/SuccessResponse'
          examples:
            OrderCreated:
              value:
                data: '#/components/schemas/Order'
            orderRetrieved:
              value:
                data: '#/components/schemas/Order'
            productRetrieved:
              value:
                data: '#/components/schemas/Product'
                message: User details retrieved successfully
    BadRequest:
      description: Bad request due to invalid parameters
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/BadRequestErrorResponse'
          examples:
            invalidParameters:
              value:
                detail: Invalid request parameters
            malformedRequest:
              value:
                detail: Malformed request body
    NotFound:
      description: Requested resource was not found
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/NotFoundErrorResponse'
          examples:
            resourceNotFound:
              value:
                message: Order Not Found
            productNotFound:
              value:
                detail: Product with ID 1231212312 not found
            endpointNotFound:
              value:
                detail: The requested endpoint does not exist
    OrderCancelled:
      description: Order successfully cancelled
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/OrderCancelled'
    UnprocessableEntity:
      description: Validation failed due to missing or invalid fields
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ValidationErrorResponse'
          example:
            detail:
              - loc:
                  - body
                  - customer
                type: missing
              - loc:
                  - body
                  - daysSupply
                type: missing
              - loc:
                  - body
                  - orderType
                type: missing
              - loc:
                  - body
                  - lineItems
                type: missing
              - loc:
                  - body
                  - shippingMethod
                type: missing
    OrderCreated:
      description: Order successfully created
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Order'
    OrdersRetrieved:
      description: Orders successfully retrieved
      content:
        application/json:
          schema:
            type: object
            properties:
              orders:
                type: array
                items:
                  $ref: '#/components/schemas/Order'
              cursor:
                $ref: '#/components/schemas/Cursor'
    OrderRetrieved:
      description: Order successfully retrieved
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Order'
  schemas:
    Address:
      type: object
      description: Physical address information
      required:
        - line1
        - city
        - state
        - zip
      properties:
        line1:
          type: string
          description: Primary address line
          example: 437 Lytton
          maxLength: 100
        line2:
          type: string
          description: Secondary address line (optional)
          example: Suite 100
          maxLength: 100
        city:
          type: string
          description: City name
          example: Palo Alto
          maxLength: 50
        state:
          type: string
          description: State or province code
          example: CA
          minLength: 2
          maxLength: 2
        zip:
          type: string
          description: Postal/ZIP code
          example: '94301'
          pattern: ^\d{5}(-\d{4})?$
    Customer:
      type: object
      description: Customer information
      required:
        - id
        - firstName
        - lastName
        - sourceId
        - address
      properties:
        sourceId:
          type: string
          description: Unique customer identifier in the partner system
          example: '1234567890'
        firstName:
          type: string
          description: Customer's first name
          example: John
        lastName:
          type: string
          description: Customer's last name
          example: Doe
        email:
          type: string
          format: email
          description: Customer's email address
          example: john.doe@example.com
        phone:
          type: string
          description: Customer's phone number
          example: '1234567890'
        address:
          $ref: '#/components/schemas/Address'
    Order:
      type: object
      description: Complete order information
      properties:
        id:
          type: string
          description: Unique order identifier
          example: 2vSGym0bH8qVEwCIGlyFoRgJq1A
        discount:
          type: string
          description: Discount percentage applied to the order
          example: 10%
        daysSupply:
          type: integer
          description: Number of days the order is intended to supply
          example: 30
        orderType:
          type: string
          description: Order type (one-time or subscription)
          enum:
            - ONE-TIME
            - SUBSCRIPTION
          example: SUBSCRIPTION
        shippingMethod:
          type: string
          description: Selected shipping method
          enum:
            - STANDARD
            - EXPRESS
            - OVERNIGHT
          example: STANDARD
        status:
          type: string
          description: Current status of the order
          enum:
            - CREATED
            - CANCELLED
            - PROCESSING
            - FULFILLED
            - AWAITING_SHIPMENT
            - SHIPPED
          example: CREATED
        fulfillmentInfo:
          type: object
          description: Details about the order fulfillment process
          properties:
            carrier:
              type: string
              description: Shipping carrier name
              example: UPS
            trackingNumber:
              type: string
              description: Shipping carrier tracking number
              example: 1Z9999999999999999
        lineItems:
          type: array
          description: Products included in the order
          items:
            type: object
            required:
              - productId
              - quantity
              - packDescription
            properties:
              productId:
                type: integer
                description: Unique identifier of the product
                example: 77123129891
              quantity:
                type: integer
                description: Quantity of the product
                minimum: 1
                example: 2
              packDescription:
                type: string
                description: Description of the product packaging
                example: Whole Body Wellness
              price:
                type: string
                description: per pill price of product
                example: '0.37'
              discountedPrice:
                type: string
                description: per pill price of product with partner discount
                example: '0.37'
              administration:
                $ref: '#/components/schemas/Administration'
        customer:
          $ref: '#/components/schemas/Customer'
        subtotalPrice:
          type: string
          description: Order subtotal amount
          example: '30.00'
        totalDiscount:
          type: string
          description: Order subtotal amount
          example: '27.00'
        totalFees:
          type: string
          description: >-
            Total for handling fees on external products. Each external item has
            a $5 handling fee.
          example: '5.00'
        totalShipping:
          type: string
          description: Shipping cost
          example: '9.99'
        totalVolumeDiscount:
          type: string
          description: >-
            Additional discount as for purchasing a days supply over the
            specified volume discount limits.
          example: '12.10'
        totalPrice:
          type: string
          description: Total order amount (subtotal + shipping)
          example: '36.99'
        createdAt:
          type: string
          format: date-time
          description: Order creation timestamp
          example: '2023-10-01T12:00:00Z'
        updatedAt:
          type: string
          format: date-time
          description: Order last update timestamp
          example: '2023-10-01T12:00:00Z'
    LineItem:
      type: object
      description: Individual product line item in an order
      properties:
        productId:
          type: integer
          description: Identifier of the associated product
          example: 77123129891
        quantity:
          type: integer
          description: Quantity of the product
          minimum: 1
          example: 2
        packDescription:
          type: string
          description: Description of the product packaging
          example: Whole Body Wellness
        administration:
          $ref: '#/components/schemas/Administration'
      required:
        - productId
        - quantity
        - packDescription
        - administration
    Administration:
      type: object
      description: Dosage schedule information
      required:
        - morning
        - afternoon
        - evening
        - sleep
      properties:
        morning:
          type: integer
          description: Morning dosage quantity
          minimum: 0
          example: 1
        afternoon:
          type: integer
          description: Afternoon dosage quantity
          minimum: 0
          example: 0
        evening:
          type: integer
          description: Evening dosage quantity
          minimum: 0
          example: 1
        sleep:
          type: integer
          description: Bedtime dosage quantity
          minimum: 0
          example: 0
    Product:
      type: object
      description: Detailed product information
      properties:
        id:
          type: integer
          description: Unique product identifier
          example: 77123129891
        name:
          type: string
          description: Product name
          example: Elite EPA
        description:
          type: string
          description: Detailed product description
          example: A comprehensive wellness supplement
        packDescription:
          type: string
          description: Description of the product packaging
          example: Whole Body Wellness
        price:
          type: string
          description: Discounted price of the product
          example: '0.53'
        external:
          type: boolean
          description: If the product is external to the pill packs. i.e. powder or liquid
          example: false
        productImage:
          type: string
          format: uri
          description: URL to the product image
          example: https://example.com/images/elite-epa.jpg
        recommendedUsage:
          $ref: '#/components/schemas/Administration'
        form:
          type: string
          description: Physical form of the supplement
          enum:
            - tablet
            - capsule
            - softgel
            - gummy
          example: softgel
        certifications:
          type: array
          description: Product certifications and standards
          items:
            type: string
          example:
            - kosher
            - halal
            - non_gmo
            - vegan
        allergens:
          type: array
          description: Allergy related information
          items:
            type: string
          example:
            - gluten_free
            - dairy_free
            - soy_free
        SupplementFactsPanel:
          $ref: '#/components/schemas/SupplementFactsPanel'
        status:
          type: string
          description: Current product availability status
          enum:
            - ACTIVE
            - DRAFT
            - BACKORDERED
            - DISCONTINUED
          example: ACTIVE
        createdAt:
          type: string
          format: date-time
          description: Product creation timestamp
          example: '2023-10-01T17:02:56.866619Z'
        updatedAt:
          type: string
          format: date-time
          description: Product last update timestamp
          example: 2023-10-01T17:02:56.866619ZZ
    SupplementFactsPanel:
      type: object
      description: Detailed nutritional and ingredient information
      properties:
        servingSize:
          type: integer
          description: Recommended serving size
          minimum: 1
          example: 2
        type:
          type: string
          description: Physical form of the supplement
          enum:
            - softgel
            - tablet
            - capsule
            - gummy
            - scoop
          example: softgel
        otherIngredients:
          type: array
          description: Additional ingredients not listed in the main panel
          items:
            type: string
          example:
            - Fish oil
            - Gelatin
            - Glycerin
        ingredientInformation:
          type: array
          description: Active ingredients with nutritional information
          items:
            type: object
            properties:
              name:
                type: string
                description: Ingredient name
                example: Fish oil
              value:
                type: string
                description: Amount per serving
                example: '100.1'
              unit:
                type: string
                description: Unit of measurement
                example: mg
              daily_value:
                type: string
                description: Percentage of recommended daily value
                example: '23'
        nutritionInformation:
          type: array
          description: Basic nutritional information
          items:
            type: object
            properties:
              name:
                type: string
                description: Nutrient name
                example: Carbohydrates
              value:
                type: string
                description: Amount per serving
                example: '10'
              unit:
                type: string
                description: Unit of measurement
                example: g
              daily_value:
                type: string
                description: Percentage of recommended daily value
                example: '10'
    TokenResponse:
      type: object
      description: Authentication token response
      properties:
        access_token:
          type: string
          description: JWT access token for API authentication
          example: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
        expires_in:
          type: integer
          description: Token expiration time in seconds
          example: 3600
        token_type:
          type: string
          description: Type of token returned
          enum:
            - Bearer
          example: Bearer
    ShippingMethod:
      type: object
      properties:
        name:
          type: string
          description: Shipping method name
          example: STANDARD
        description:
          type: string
          description: Shipping method details
          example: 5-8 business days
        price:
          type: string
          description: Shipping cost
          example: '9.99'
    Cursor:
      type: string
      description: Pagination cursor for retrieving next/previous page
      example: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
    ErrorDetail:
      type: object
      properties:
        loc:
          type: array
          description: Location of the error in the request body
          items:
            type: string
        type:
          type: string
          description: Type of validation error
          enum:
            - missing
            - invalid
            - type_error
      required:
        - loc
        - type
    SuccessResponse:
      type: object
      properties:
        data:
          type: object
          example:
            id: '12345'
            status: processed
      required:
        - data
    BadRequestErrorResponse:
      type: object
      properties:
        detail:
          type: string
          description: Detailed error message explaining the bad request
          example: Invalid request parameters
      required:
        - detail
    NotFoundErrorResponse:
      type: object
      properties:
        detail:
          type: string
          description: Detailed error message explaining the resource not found
          example: The requested resource could not be found
      required:
        - detail
    OrderCancelled:
      type: object
      properties:
        order_id:
          type: string
          description: ID of the cancelled order
          example: 2vTYQiGzufR4cn1cloW97DtSOYF
        status:
          type: string
          description: order status
          example: Cancelled
    ValidationErrorResponse:
      type: object
      properties:
        detail:
          type: array
          description: List of specific validation errors
          items:
            $ref: '#/components/schemas/ErrorDetail'
    AuthError:
      type: object
      description: Error response details
      properties:
        error:
          type: string
          description: Human-readable error message
          example: invalid_client
  securitySchemes:
    oauth2ClientCredentials:
      type: oauth2
      description: OAuth 2.0 Client Credentials flow for API authentication
      flows:
        clientCredentials:
          tokenUrl: https://auth.fulfillment.sandbox.juniperhealth.com/oauth2/token
          scopes: {}
security:
  - oauth2ClientCredentials: []
