openapi: "3.0.3"
info:
  description: "SentiOne Automate gateway API"
  version: "1.0.4"
  title: "SentiOne Automate gateway API"
tags:
  - name: "Gateway"
    description: "Bot gateway"
paths:
  /gateway:
    post:
      operationId: api.get_bot_response
      tags:
        - "Gateway"
      summary: "Interaction with bot"
      description: >
        "Endpoint used to conduct conversation with bot. It accepts user input and responds with bot answers."
      requestBody:
        description: "Bot gateway request"
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/GatewayRequest"
      responses:
        200:
          description: "Success"
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/BotResponse"
        400:
          description: "Bad Request"
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiValidationError"
        401:
          description: "Unauthorized"
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/AuthenticationError"
  /gateway/stream:
    post:
      tags:
        - "Gateway"
      summary: "Interaction with bot"
      description: >
        Endpoint used to conduct conversation with bot. It accepts user input and responds with bot answers.
        Returns response in Sever-sent events format. Stream contains zero or more PartialResponse events followed by exactly one Response or StreamError event.
        The final Response event contains all partial responses.
      requestBody:
        description: "Bot gateway request"
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/GatewayRequest"
      responses:
        200:
          description: "Success"
          content:
            text/event-stream:
              schema:
                type: array
                format: event-stream
                example: |+
                  event: PartialResponse
                  data: {"response":{"quickReplies":[],"text":"To whom do you want ","quick_replies":[],"attachments":[]},"isStart":true,"isEnd":false}

                  event: PartialResponse
                  data: {"response":{"quickReplies":[],"text":"to make the transfer and for what amount?","quick_replies":[],"attachments":[]},"isStart":false,"isEnd":true}

                  event: Response
                  data: {"current_state":{"context":"Transfer","id":"153130655900418","name":"say:dest&amount","tags":["authentication_start","path-A-chosen","custom-tag"]},"responses":[{"text":"To whom do you want to make the transfer and for what amount?","attachments":["https://example.com/cat.jpg"],"quickReplies":[{"title":"Yes!"}],"quick_replies":[{"title":"Yes!"}]}],"used_states":[{"context":"Transfer","id":"153130655900418","name":"say:dest&amount","tags":["authentication_start","path-A-chosen","custom-tag"]}],"intent":{"name":"money-transfer","score":0.2},"tags":["authentication_start","path-A-chosen","custom-tag"],"commands":[{"type":"Redirect","params":"agent-id"}],"process_time":0,"nlu_time":0,"integrations_time":0}

                items:
                  oneOf:
                    - type: object
                      properties:
                        event:
                          type: string
                          enum: [ "PartialResponse" ]
                        data:
                          $ref: "#/components/schemas/BotPartialResponse"
                    - type: object
                      properties:
                        event:
                          type: string
                          enum: [ "Response" ]
                        data:
                          $ref: "#/components/schemas/BotResponse"
                    - type: object
                      properties:
                        event:
                          type: string
                          enum: [ "Error" ]
                        data:
                          $ref: "#/components/schemas/StreamError"
        400:
          description: "Bad Request"
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiValidationError"
  /recording:
    post:
      operationId: api.post_recording
      tags:
        - "Gateway"
      summary: "Attach recording"
      requestBody:
        description: "Recording request"
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/RecordingRequest"
      responses:
        200:
          description: "Success"
        400:
          description: "Bad Request"
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiValidationError"
        401:
          description: "Unauthorized"
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/AuthenticationError"
  /recording/upload:
    post:
      operationId: api.post_recording_upload
      tags:
        - "Gateway"
      summary: "Upload recording"
      requestBody:
        description: "Upload recording request"
        required: true
        content:
          multipart/form-data:
            schema:
              type: object
              properties:
                params:
                  $ref: "#/components/schemas/UploadRecordingRequest"
                recordingFile:
                  type: string
                  format: binary
            encoding:
              recordingFile:
                contentType: audio/mpeg
      responses:
        200:
          description: "Success"
        400:
          description: "Bad Request"
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiValidationError"
        401:
          description: "Unauthorized"
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/AuthenticationError"
  /metadata:
    post:
      operationId: api.post_metadata
      tags:
        - "Gateway"
      summary: "Attach conversation data"
      requestBody:
        description: "Metadata request"
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/MetadataRequest"
      responses:
        200:
          description: "Success"
        400:
          description: "Bad Request"
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiValidationError"
        401:
          description: "Unauthorized"
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/AuthenticationError"
  /call/summary:
    post:
      operationId: api.post_call_summary
      tags:
        - "Gateway"
      summary: "Attach call summary"
      requestBody:
        description: "Call Summary request"
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/CallSummaryRequest"
      responses:
        200:
          description: "Success"
        400:
          description: "Bad Request"
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiValidationError"
        401:
          description: "Unauthorized"
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/AuthenticationError"
  /thread/pass:
    post:
      operationId: api.post_thread_pass
      tags:
        - "Gateway"
      summary: "Pass thread to the specified owner"
      requestBody:
        description: "Object with data specifying which thread should be passed to the new owner"
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/PassThreadRequest"
      responses:
        200:
          description: "Success"
        400:
          description: "Bad Request"
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiValidationError"
        401:
          description: "Unauthorized"
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/AuthenticationError"
  /thread/owner:
    get:
      operationId: api.get_thread_owner
      tags:
        - "Gateway"
      summary: "Get owner of the thread"
      parameters:
        - in: query
          name: threadId
          schema:
            type: string
          description: "Thread ID"
          required: true
        - in: query
          name: sourceType
          schema:
            type: string
          description: "Source Type"
          required: true
        - in: query
          name: date
          schema:
            type: integer
          description: "Optional date in milliseconds used to update thread's ownership date. By default, as date will be used current date"
      responses:
        200:
          description: "Thread owner"
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ThreadOwner"
        400:
          description: "Bad Request"
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiValidationError"
        401:
          description: "Unauthorized"
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/AuthenticationError"

components:
  securitySchemes:
    basicAuth:
      type: http
      scheme: basic
  schemas:
    GatewayRequest:
      type: object
      required:
        - "text"
        - "source_type"
        - "author"
        - "uuid"
        - "suid"
      properties:
        text:
          type: string
          example: "Please make a transfer!"
          description: "Message sent by user"
        source_type:
          $ref: "#/components/schemas/SourceType"
        author:
          type: string
          example: "Jan Kowalski"
          description: "Name of the author of the message."
          maxLength: 128
        uuid:
          type: string
          example: "e12bdeca-a99c-480c-89e1-e26b2f3f76b7"
          description: "Project identifier - uuid of a project for which bot has to respond"
          maxLength: 64
        suid:
          type: string
          example: "43578954378959789875"
          description: "Session identifier. Session is unique identifier for one particular session. It can be an uuid or just random string. <br>
            If bot responds to user and integrator wants to send another message in the same context it has to attach the same suid <br>
            Example: <br>
            1. User sends first message in the conversation - set the suid for ex. \"r123111-a99c-480c-89e1-e26b2f3f76b7\" <br>
            2. Gateway returns message to user <br>
            3. User says something more in that particular conversation - use the same suid as before \"r123111-a99c-480c-89e1-e26b2f3f76b7\"
          "
          maxLength: 64
        extra_data:
          type: object
          example: { pin: 2222, authorId: 321 }
          description: "This is additional and optional field, could be used for additional integration"
    BotResponse:
      type: object
      properties:
        current_state:
          $ref: "#/components/schemas/CurrentState"
        responses:
          type: array
          items:
            $ref: "#/components/schemas/BotSingleResponse"
        used_states:
          type: array
          items:
            $ref: "#/components/schemas/CurrentState"
        intent:
          $ref: "#/components/schemas/NluIntent"
        tags:
          type: array
          items:
            type: string
          example: ["authentication_start", "path-A-chosen", "custom-tag"]
        commands:
          type: array
          items:
            $ref: "#/components/schemas/BotCommand"
        process_time:
          type: number
          description: "Total request time in milliseconds"
        nlu_time:
          type: number
          description: "NLU request time in milliseconds"
        integrations_time:
          type: number
          description: "Integrations request time in milliseconds"
    BotPartialResponse:
      type: object
      properties:
        response:
          $ref: "#/components/schemas/BotSingleResponse"
        isStart:
          type: boolean
          description: "Indicates if this is start of a new message, and not continuation of the previous one"
        isEnd:
          type: boolean
          description: "Indicates if this is the last part of the current message"
    StreamError:
      description: "Represents unexpected HTTP error response that would be returned from non-stream endpoint"
      type: object
      properties:
        code:
          type: number
        error:
          type: object
    BotSingleResponse:
      type: object
      properties:
        text:
          type: string
          example: "To whom do you want to make the transfer and for what amount?"
        attachments:
          type: array
          description: List of URLs
          items:
            type: string
            example: "https://example.com/cat.jpg"
        quickReplies:
          type: array
          description: This field is deprecated and soon will be no more
          items:
            $ref: "#/components/schemas/QuickReply"
        quick_replies:
          type: array
          items:
            $ref: "#/components/schemas/QuickReply"
    QuickReply:
      type: object
      properties:
        title:
          type: string
          example: "Yes!"
    CurrentState:
      type: object
      description: "This field can be null at the end of the conversation"
      properties:
        context:
          type: string
          example: "Transfer"
        id:
          type: string
          example: "153130655900418"
        name:
          type: string
          example: "say:dest&amount"
        tags:
          type: array
          items:
            type: string
          example: ["authentication_start", "path-A-chosen", "custom-tag"]
    NluIntent:
      type: object
      properties:
        name:
          type: string
          example: "money-transfer"
          description: "This is name from admin panel, if no intent id detected there will be 'no_intent'"
        score:
          type: number
          example: 0.2
    BotCommand:
      type: object
      properties:
        type:
          type: string
          example: "Redirect"
          description: "Commands defined in integration documentation. <br>
            Predefined commands are: <br>
              - redirect - it is used for a situation when bot finishes its path and is not able to proceed further,
                so it is going to redirect current conversation to agent. For example when bot encounter Redirect state <br>
              - disconnect - it is used for scenario when bot finished its path at End block, so it assumes that conversation has ended.
          "
        params:
          type: string
          example: "agent-id"
          description: "This field is fluent and can be used depending on needs. For some cases could be object"
    RecordingRequest:
      type: object
      required:
        - "conversationId"
        - "systemName"
        - "fileName"
        - "projectId"
      properties:
        projectId:
          type: string
          example: "e12bdeca-a99c-480c-89e1-e26b2f3f76b7"
          description: "This field corresponds to uuid in GatewayRequest"
        conversationId:
          type: string
          example: "43578954378959789875"
          description: "This field corresponds to suid in GatewayRequest"
        systemName:
          type: string
          description: "Name of the system in which the files are stored"
          enum: ["alior", "tmobile"]
        fileName:
          type: string
          description: "Relative name of the recording file"
    UploadRecordingRequest:
      type: object
      required:
        - "conversationId"
        - "projectId"
      properties:
        projectId:
          type: string
          example: "e12bdeca-a99c-480c-89e1-e26b2f3f76b7"
          description: "This field corresponds to uuid in GatewayRequest"
        conversationId:
          type: string
          example: "43578954378959789875"
          description: "This field corresponds to suid in GatewayRequest"
    MetadataRequest:
      type: object
      required:
        - "conversationId"
        - "projectId"
        - "metadata"
      properties:
        projectId:
          type: string
          example: "e12bdeca-a99c-480c-89e1-e26b2f3f76b7"
          description: "This field corresponds to uuid in GatewayRequest"
        conversationId:
          type: string
          example: "43578954378959789875"
          description: "This field corresponds to suid in GatewayRequest"
        metadata:
          type: object
          example:
            agent: "Jan Kowalski"
            agentId: "5"
            supervisor: "Andrzej Nowak"
          description: "Object with metadata to save. String and list of strings values are supported. Limitations:\n
            - Entry with key containing more than 250 chars is removed.\n
            - Maximum number of metadata entries is 100. If it's exceeded, then 100 random entries is selected.\n 
            - List of strings is trimmed to 100 elements and each string is trimmed to 1000 chars."
    CallSummaryRequest:
      type: object
      required:
        - "conversationId"
        - "projectId"
        - "durationSeconds"
        - "terminationReason"
        - "botNumber"
      properties:
        projectId:
          type: string
          example: "e12bdeca-a99c-480c-89e1-e26b2f3f76b7"
          description: "This field corresponds to uuid in GatewayRequest"
        conversationId:
          type: string
          example: "43578954378959789875"
          description: "This field corresponds to suid in GatewayRequest"
        durationSeconds:
          type: number
          example: 32
          description: "Call duration in seconds"
        terminationReason:
          type: string
          example: Human
          enum: [Human, Bot, Redirect, Error]
          description: "Call termination reason, value from enum"
        botNumber:
          type: string
          example: "123456789"
          description: "Number on which user called"
        transferTo:
          type: string
          example: "123456789"
          description: "Number to which call was redirected. When terminationReason is marked as REDIRECT then this field should be filled"
        errorMessage:
          type: string
          example: "Invalid SSML"
          description: "Error message that explains why the call has been terminated. When terminationReason is marked as Error then this field should be filled"
    PassThreadRequest:
      type: object
      properties:
        threadId:
          type: string
          example: "1"
        sourceType:
          $ref: "#/components/schemas/SourceType"
        to:
          $ref: "#/components/schemas/ThreadOwner"
    ThreadOwner:
      type: string
      enum: [Bot, Agent]
    AuthenticationError:
      type: object
      properties:
        detail:
          type: string
          example: "Wrong OTP token"
        status:
          type: integer
          example: 401
        title:
          type: string
          example: "Unauthorized"
    SourceType:
      type: string
      example: "phone"
      enum: [ "phone", "mobile", "senti1-web-chat", "whatsapp", "facebook", "skype", "alfavox", "twitter", "external" ]
      description: "Type of the source by which user is contacting. For example: <br>
        - phone - user is contacting by phone <br>
        - twitter - user message comes from twitter integration"
    ApiValidationError:
      type: object
      properties:
        detail:
          type: string
          example: "'suid' is a required property"
        status:
          type: integer
          example: 400
        title:
          type: string
          example: "Bad Request"
        type:
          type: string
          example: "about:blank"
security:
  - basicAuth: []
