openapi: "3.1.0"
info:
  title: Telephony MiniApp — Outgoing Requests
  description: >
    Outgoing requests from our application to the external one (Acloud → MiniApp).
    Sent as POST requests to the endpoint_url configured in the integration.
    Authorization: Bearer {api_token}
  version: "1.0.0"

x-retry-policy:
  max_retries: 3
  strategy: exponential backoff
  delays_seconds: [1, 2, 4]

x-expected-response:
  success_codes: [200, 201, 202]
  description: >
    Any 2xx response is considered successful.
    4xx errors are not retried. 5xx errors are retried according to the retry policy.

webhooks:

  call.init:
    post:
      summary: Initiate Outbound Call
      description: >
        Requests the external application to initiate a call on behalf of an employee.
        Sent when the user clicks the call button in the Acloud interface.
      x-headers:
        Content-Type: application/json
        Authorization: Bearer {api_token}
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - method
                - payload
              properties:
                method:
                  type: string
                  enum:
                    - call.init
                payload:
                  $ref: '#/components/schemas/CallInitPayload'
            examples:
              call_init:
                summary: Initiate employee-to-client call
                value:
                  method: call.init
                  payload:
                    to: "+79995556677"
                    from: "101"
      responses:
        "200":
          description: Call initiation request accepted

  call.list:
    post:
      summary: Get Call List
      description: >
        Requests the list of calls for the specified period.
        Used to sync calls from the external system.
      x-headers:
        Content-Type: application/json
        Authorization: Bearer {api_token}
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - method
                - payload
              properties:
                method:
                  type: string
                  enum:
                    - call.list
                payload:
                  $ref: '#/components/schemas/CallListPayload'
            examples:
              call_list_by_days:
                summary: Calls for the last 7 days
                value:
                  method: call.list
                  payload:
                    days_left: 7
              call_list_by_range:
                summary: Calls for a date range
                value:
                  method: call.list
                  payload:
                    from_date: "2026-04-01"
                    to_date: "2026-04-09"
      responses:
        "200":
          description: Call list
          content:
            application/json:
              schema:
                type: object
                properties:
                  calls:
                    type: array
                    items:
                      $ref: '#/components/schemas/CallItem'
              examples:
                call_list_response:
                  summary: Call list
                  value:
                    calls:
                      - call_id: call_abc123
                        direction: in
                        from: "+79990001234"
                        to: "101"
                        timestamp: "2026-04-09T10:30:00Z"
                        call_duration: 295
                        status: terminated
                        has_record: true
                      - call_id: call_abc124
                        direction: out
                        from: "102"
                        to: "+79991112233"
                        timestamp: "2026-04-09T11:00:00Z"
                        call_duration: 0
                        status: missed
                        has_record: false

  call.get:
    post:
      summary: Get Call Details
      description: >
        Requests data for a single call by its identifier.
      x-headers:
        Content-Type: application/json
        Authorization: Bearer {api_token}
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - method
                - payload
              properties:
                method:
                  type: string
                  enum:
                    - call.get
                payload:
                  $ref: '#/components/schemas/CallGetPayload'
            examples:
              call_get:
                summary: Get call by ID
                value:
                  method: call.get
                  payload:
                    call_id: call_abc123
      responses:
        "200":
          description: Call data (null if not found)
          content:
            application/json:
              schema:
                type: object
                properties:
                  call:
                    oneOf:
                      - $ref: '#/components/schemas/CallItem'
                      - type: "null"
              examples:
                call_found:
                  summary: Call found
                  value:
                    call:
                      call_id: call_abc123
                      direction: in
                      from: "+79990001234"
                      to: "101"
                      timestamp: "2026-04-09T10:30:00Z"
                      call_duration: 295
                      status: terminated
                      has_record: true
                call_not_found:
                  summary: Call not found
                  value:
                    call: null

  sip.employees.list:
    post:
      summary: Get SIP Employees List
      description: >
        Requests the list of employees configured in the external phone system.
        Used to map employee extensions to Acloud users.
      x-headers:
        Content-Type: application/json
        Authorization: Bearer {api_token}
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - method
                - payload
              properties:
                method:
                  type: string
                  enum:
                    - sip.employees.list
                payload:
                  type: object
                  description: Empty payload
            examples:
              sip_employees_list:
                summary: Request employee list
                value:
                  method: sip.employees.list
                  payload: {}
      responses:
        "200":
          description: SIP employees list
          content:
            application/json:
              schema:
                type: object
                properties:
                  employees:
                    type: array
                    items:
                      $ref: '#/components/schemas/SipEmployee'
              examples:
                employees_list:
                  summary: Employee list
                  value:
                    employees:
                      - id: "emp_001"
                        name: John Smith
                        email: john@example.com
                        extension: "101"
                      - id: "emp_002"
                        name: Jane Smith
                        email: jane@example.com
                        extension: "102"

  integration.status:
    post:
      summary: Get Integration Status
      description: >
        Checks availability and status of the integration with the external application.
        Used for health check and diagnostics.
      x-headers:
        Content-Type: application/json
        Authorization: Bearer {api_token}
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - method
                - payload
              properties:
                method:
                  type: string
                  enum:
                    - integration.status
                payload:
                  type: object
                  description: Empty payload
            examples:
              integration_status:
                summary: Integration status request
                value:
                  method: integration.status
                  payload: {}
      responses:
        "200":
          description: Integration status
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/IntegrationStatusResponse'
              examples:
                status_active:
                  summary: Integration active
                  value:
                    status: active
                    message: ""
                status_inactive:
                  summary: Integration inactive
                  value:
                    status: inactive
                    message: "API token is invalid"


components:
  schemas:

    OutgoingEvent:
      type: object
      required:
        - method
        - payload
      properties:
        method:
          type: string
          enum:
            - call.init
            - call.list
            - call.get
            - sip.employees.list
            - integration.status
          description: Request type
        payload:
          oneOf:
            - $ref: '#/components/schemas/CallInitPayload'
            - $ref: '#/components/schemas/CallListPayload'
            - $ref: '#/components/schemas/CallGetPayload'
          discriminator:
            propertyName: method

    # ─── call.init ────────────────────────────────────────────────────────────

    CallInitPayload:
      type: object
      description: Parameters for initiating an outbound call
      required:
        - to
        - from
      properties:
        to:
          type: string
          description: Phone number to call
          example: "+79995556677"
        from:
          type: string
          description: Employee extension (internal number) on behalf of whom the call is made
          example: "101"

    # ─── call.list ────────────────────────────────────────────────────────────

    CallListPayload:
      type: object
      description: >
        Filter parameters for the call list. All fields are optional.
        If not specified — all available calls are returned.
      properties:
        days_left:
          type: ["integer", "null"]
          description: Number of days back from the current date for call selection
          example: 7
        from_date:
          type: ["string", "null"]
          description: Start date for the selection period (format YYYY-MM-DD)
          example: "2026-04-01"
        to_date:
          type: ["string", "null"]
          description: End date for the selection period (format YYYY-MM-DD)
          example: "2026-04-09"

    # ─── call.get ─────────────────────────────────────────────────────────────

    CallGetPayload:
      type: object
      description: Parameters for retrieving a specific call's data
      required:
        - call_id
      properties:
        call_id:
          type: string
          description: Unique call identifier in the external system
          example: call_abc123

    # ─── Shared types ─────────────────────────────────────────────────────────

    CallItem:
      type: object
      description: Data for a single call from the external system
      required:
        - call_id
        - direction
        - from
        - to
        - timestamp
        - call_duration
        - status
        - has_record
      properties:
        call_id:
          type: string
          description: Unique call identifier
          example: call_abc123
        direction:
          type: string
          enum:
            - in
            - out
          description: Call direction
        from:
          type: string
          description: Call source (phone number or extension)
          example: "+79990001234"
        to:
          type: string
          description: Call recipient (phone number or extension)
          example: "101"
        timestamp:
          type: string
          description: Call date and time in ISO 8601 format
          example: "2026-04-09T10:30:00Z"
        call_duration:
          type: integer
          description: Call duration in seconds
          example: 295
        status:
          type: string
          enum:
            - active
            - terminated
            - missed
          description: Call status
        has_record:
          type: boolean
          description: Flag indicating whether a call recording exists
          example: true
        record_url:
          type: string
          description: Download link for the call recording
          example: https://domain/call_id
          nullable: true

    SipEmployee:
      type: object
      description: Employee data in the SIP system of the external application
      required:
        - id
        - name
        - email
        - extension
      properties:
        id:
          type: string
          description: Unique employee identifier in the external system
          example: "emp_001"
        name:
          type: string
          description: Employee display name
          example: John Smith
        email:
          type: string
          description: Employee email
          example: john@example.com
        extension:
          type: string
          description: Employee internal SIP number
          example: "101"

    IntegrationStatusResponse:
      type: object
      description: Integration status response
      required:
        - status
      properties:
        status:
          type: string
          enum:
            - active
            - inactive
          description: >
            Current integration status.
            `active` — integration is working normally;
            `inactive` — integration is unavailable or disabled.
        message:
          type: string
          description: Additional status message (e.g., reason for inactivity)
          example: ""
