openapi: 3.1.0
info:
  title: quote-personalcyber-service
  version: 1.0.0
servers:
  - url: https://api-sandbox.k2cyber.co/quote/personalcyber
    description: Sandbox
paths:
  /submit:
    post:
      summary: Create a personalcyber-quote
      security:
        - OAuth2ClientCredentials:
            - quote
      requestBody:
        content:
          application/json:
            example:
              brokerEmail: youremail@example.com
              effective: 2026-10-23
              insuredName: Firstname Lastname
              insuredLocation: 123 Main St., Anytown, USA
              limit: 1000000
              retention: 500
              contactMethod: Email
              email: youremail@example.com
              phone: 555-555-5555
            schema:
              type: object
              properties:
                brokerEmail:
                  type: string
                  format: email
                  pattern: ^(?!\.)(?!.*\.\.)([A-Za-z0-9_'+\-\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\-]*\.)+[A-Za-z]{2,}$
                effective:
                  description: Defaults to tomorrow's date.
                  type: string
                insuredName:
                  type: string
                  minLength: 1
                insuredLocation:
                  anyOf:
                    - type: string
                    - type: object
                      properties:
                        addressLine1:
                          type: string
                        addressLine2:
                          type: string
                        city:
                          type: string
                        state:
                          type: string
                        postalCode:
                          type: string
                        country:
                          type: string
                      required:
                        - addressLine1
                limit:
                  anyOf:
                    - type: number
                    - type: string
                retention:
                  anyOf:
                    - type: number
                    - type: string
                contactMethod:
                  type: string
                email:
                  type: string
                  format: email
                  pattern: ^(?!\.)(?!.*\.\.)([A-Za-z0-9_'+\-\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\-]*\.)+[A-Za-z]{2,}$
                phone:
                  type: string
              required:
                - brokerEmail
                - insuredName
                - insuredLocation
                - limit
                - retention
                - email
      responses:
        "200":
          description: Quote created
          content:
            application/json:
              example:
                data:
                  id: 70274e93-b049-4651-934c-a8d559fa4aa3
                  quote_status: pending
                  premium: 150
                  policyfee: 50
                  eligible: true
                  checkoutUrl: https://checkout.example.com
              schema:
                type: object
                properties:
                  data:
                    type: object
                    properties:
                      id:
                        type: string
                        format: uuid
                        pattern: ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$
                      quote_status:
                        type: string
                        const: pending
                      premium:
                        type: number
                      policyfee:
                        type: number
                      eligible:
                        type: boolean
                      checkoutUrl:
                        type: string
                    required:
                      - id
                      - quote_status
                      - premium
                      - policyfee
                      - eligible
                      - checkoutUrl
                    additionalProperties: false
                required:
                  - data
                additionalProperties: false
        "401":
          description: Unauthorized
        "403":
          description: Forbidden - missing 'quote' scope
  /status/{id}:
    get:
      summary: Get personalcyber-quote
      security:
        - OAuth2ClientCredentials:
            - quote
      parameters:
        - in: path
          name: id
          schema:
            type: string
          required: true
      responses:
        "200":
          description: "Poll this endpoint to get the status of the quote (one of:
            [pending, published, pendingBindAndIssue, issued, failed])"
          content:
            application/json:
              example:
                data:
                  id: 70274e93-b049-4651-934c-a8d559fa4aa3
                  quote_status: published
                  premium: 150
                  policyfee: 50
                  eligible: true
                  checkoutUrl: https://checkout.example.com
              schema:
                oneOf:
                  - type: object
                    properties:
                      data:
                        type: object
                        properties:
                          id:
                            type: string
                            format: uuid
                            pattern: ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$
                          quote_status:
                            type: string
                            enum:
                              - pending
                              - published
                              - pendingBindAndIssue
                              - issued
                          premium:
                            anyOf:
                              - type: number
                              - type: "null"
                          policyfee:
                            anyOf:
                              - type: number
                              - type: "null"
                          eligible:
                            anyOf:
                              - type: boolean
                              - type: "null"
                          checkoutUrl:
                            type: string
                        required:
                          - id
                          - quote_status
                          - premium
                          - policyfee
                          - eligible
                          - checkoutUrl
                        additionalProperties: false
                    required:
                      - data
                    additionalProperties: false
                  - type: object
                    properties:
                      data:
                        type: object
                        properties:
                          id:
                            type: string
                            format: uuid
                            pattern: ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$
                          quote_status:
                            type: string
                            enum:
                              - failed
                          failed_quote_reason:
                            anyOf:
                              - type: string
                              - type: "null"
                          checkoutUrl:
                            type: string
                        required:
                          - id
                          - quote_status
                          - failed_quote_reason
                          - checkoutUrl
                        additionalProperties: false
                    required:
                      - data
                    additionalProperties: false
                type: object
        "400":
          description: Bad Request - invalid id parameter
        "401":
          description: Unauthorized
        "403":
          description: Forbidden - missing 'quote' scope
        "404":
          description: Not Found - quote does not exist
  /bind/{id}:
    put:
      summary: Bind a personalcyber-quote
      security:
        - OAuth2ClientCredentials:
            - quote
      parameters:
        - in: path
          name: id
          schema:
            type: string
          required: true
      responses:
        "202":
          description: Accepted - quote bind initiated
          content:
            application/json:
              example:
                data:
                  id: 70274e93-b049-4651-934c-a8d559fa4aa3
                  quote_status: pendingBindAndIssue
              schema:
                type: object
                properties:
                  data:
                    type: object
                    properties:
                      id:
                        type: string
                        format: uuid
                        pattern: ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$
                      quote_status:
                        type: string
                        enum:
                          - pendingBindAndIssue
                    required:
                      - id
                      - quote_status
                    additionalProperties: false
                required:
                  - data
                additionalProperties: false
        "400":
          description: Bad Request - invalid id parameter
        "401":
          description: Unauthorized
        "403":
          description: Forbidden - missing 'quote' scope
        "404":
          description: Not Found - quote does not exist
        "409":
          description: Conflict - quote already issued or still processing
        "500":
          description: Internal Server Error - quote in failed state
components:
  securitySchemes:
    OAuth2ClientCredentials:
      type: oauth2
      flows:
        clientCredentials:
          tokenUrl: https://api-sandbox.k2cyber.co/auth/token
          scopes:
            quote: Access to quote APIs
