openapi: 3.0.0
info:
  description: |
    DataBag provides storage for decentralized identity based self-hosting apps.
    It is intended to support sharing of personal data and hosting group
    conversations.
  version: "0.0.1"
  title: DataBag
  contact:
    email: roland.osborne@gmail.com
  license:
    name: Apache 2.0
    url: 'http://www.apache.org/licenses/LICENSE-2.0.html'
tags:
  - name: status
    description: websocket endpoint for receiving module revision events
  - name: admin
    description: account creation for portal backend.
  - name: account
    description: account configuration for portal backend. supports app attachment
  - name: authenticate
    description: authenticate holder of identity for external service
  - name: profile
    description: getting and setting of the public profile
  - name: share
    description: access control for personal subjects, associates content and cards
    
  - name: contact
    description: connection to other identities, hook receiver
  - name: content
    description: posting and listing of personal subjects, group and tag managment
    
  - name: converstaion
    description: group sharing of subjects
    
paths:

  # Concetps:
  ## access tokens for bearer auth:prefix for bearer tokens types
  ### app: app_
  ### contact: cnt_
  ### attach: atc_
  ### reset: res_
  ### create: act_
  ## subject based content provides external definition of datatypes

  /status:
    get:
      tags:
        - status
      description: Websocket placeholder endpoint for receiving account status updates
      operationId: status
      responses:
        '200':
          description: Awaiting announce
              
  /admin/claimable:
    get:
      tags:
        - admin
      description: Check if portal params have been set
      operationId: get-node-claimable
      responses:
        '200':
          description: success
        '406':
          description: node already claimed
        '500':
          description: internal server error
          
  /admin/config:
    post:
      tags:
        - admin
      description: Set admin password and node domain
      operationId: set-node-config
      security:
        - basicAuth: []
      parameters:
        - name: domain
          in: query
          description: domain of node
          required: true
          schema:
            type: string
      responses:
        '200':
          description: success
        '401':
          description: permission denied
        '500':
          description: internal server error
          
  /admin/config/domain:
    put:
      tags:
        - admin
      description: Set portal domain to be set in profile queries. Access granted to admin username and password.
      operationId: set-node-config-domain
      security:
        - basicAuth: []
      responses:
        '200':
          description: success
        '401':
          description: permission denide
        '500':
          description: internal server error
      requestBody:
        content:
          application/json:
            schema:
              type: string
          
  /admin/accounts:
    get:
      tags:
        - admin
      description: Get list of accounts hosted on node. Access granted to admin username and password. 
      operationId: get-node-accounts
      security:
        - basicAuth: []
      responses:
        '200':
          description: successful operation
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Account'
        '401':
          description: invalid password
        '404':
          description: handle not found
        '500':
          description: internal server error
    post:
      tags:
        - admin
      description: Gernerate a url for creating a new account. Access granted to admin username and password.
      operationId: add-node-account
      security:
        - basicAuth: []
      responses:
        '201':
          description: generated
          content:
            application/json:
              schema:
                type: string
        '401':
          description: invalid password
        '500':
          description: internal server error
          
  /admin/accounts/{accountId}/reset:
    put:
      tags:
        - admin
      description: Generate a password reset url for specified account. Access granted to admin username and password.
      operationId: set-node-account
      security:
        - basicAuth: []
      parameters:
        - name: accountId
          in: path
          description: id of profile to access
          required: true
          schema:
            type: string
      responses:
        '201':
          description: generated
          content:
            application/json:
              schema:
                type: string
        '401':
          description: invalid password
        '404':
          description: unknown portal
        '500':
          description: internal server error
          
  /admin/accounts/{accountId}/image:
    get:
      tags:
        - admin
      description: Get profile image of specified account. Access granted to admin username and password
      operationId: get-node-account-image
      security:
        - basicAuth: []
      parameters:
        - name: accountId
          in: path
          description: id of specified account
          required: true
          schema:
            type: string
      responses: 
        '200':
          description: success
          content:
            application/octet-stream: # content specific
              schema:
                type: string
                format: binary
        '401':
          description: permission denied
        '405':
          description: invalid image
        '500':
          description: internal server error
          
  /admin/accounts/{accountId}:
    delete:
      tags:
        - admin
      description: Remove account from node. Access granted to admin username and password.
      operationId: remove-node-account
      security:
        - basicAuth: []
      parameters:
        - name: accountId
          in: path
          description: id of account to delete
          required: true
          schema:
            type: string
      responses:
        '200':
          description: successful operation
        '401':
          description: invalid authentication
        '404':
          description: account not found
        '500':
          description: internal server error
          
  /account/claimable:
    get:
      tags:
        - account
      description: Check if username is available. Access granted account reset token or account create token.
      operationId: get-account-username
      security:
        - bearerAuth: []
      parameters:
        - name: username
          in: query
          description: username to check 
          required: true
          schema:
            type: string
      responses:
        '200':
          description: success
        '401':
          description: permission denied
        '406':
          description: username already claimed
        '500':
          description: internal server error
          
  /account/token:
    get:
      tags:
        - account
      description: Check if account reset token or account create token is valid. Access granted to valid create or reset token.
      operationId: get-account-token
      security:
        - bearerAuth: []
      responses:
        '200':
          description: success
        '401':
          description: permission denied
        '500':
          description: internal server error
          
  /account/profile:
    get:
      tags:
        - account
      description: Get account profile. Access granted to account's username and password.
      operationId: get-account-profile
      security:
        - basicAuth: []
      responses:
        '200':
          description: successful operation
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Profile'
        '401':
          description: authentication error
        '500':
          description: internal server error
    post:
      tags:
        - account
      description: Add a new account. Basic auth will be used for the accounts username and password. Access granted to valid create account token.
      operationId: add-account
      security:
        - bearerAuth: []
        - basicAuth: []
      responses:
        '201':
          description: successful operation
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Profile'
        '400':
          description: invalid handle or password
        '401':
          description: invalid bearer token
        '500':
          description: internal server error
                
  /account/profile/image:
    get:
      tags:
        - account
      description: Get profile image. Access granted to account's username and password
      operationId: get-account-image
      security:
        - basicAuth: []
      responses: 
        '200':
          description: success
          content:
            application/octet-stream: # content specific
              schema:
                type: string
                format: binary
        '401':
          description: permission denied
        '405':
          description: invalid image
        '500':
          description: internal server error
          
  /account/auth:
    post:
      tags:
        - account
      description: Generate token to reset authentication. Access granted to account's login and password.
      operationId: add-account-authentication
      security:
        - basicAuth: []
      responses:
        '201':
          description: generated
          content:
            application/json:
              schema:
                type: string
        '401':
          description: invalid password
        '500':
          description: internal server error
    put:
      tags:
        - account
      description: Apply account reset token to set handle and password. Basic auth will be used for new login and password. Access granted to valid reset token.
      operationId: set-account-authentication
      security:
        - bearerAuth: []
        - basicAuth: []
      responses:
        '201':
          description: success
        '401':
          description: permission denied
        '500':
          description: internal server error
          
  /account/apps:
    get:
      tags:
        - account
      description: Get list of attached apps to account. Access granted to account's username and password.
      operationId: get-account-apps
      security:
        - basicAuth: []
      responses:
        '200':
          description: success
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/App'
        '401':
          description: permission denied
        '500':
          description: internal server error
    post:
      tags:
        - account
      description: Generate token to attach an app to the account. Access granted to account's username and password.
      operationId: add-account-app
      security:
        - basicAuth: []
      responses:
        '201':
          description: generated
          content:
            application/json:
              schema:
                type: string
        '401':
          description: invalid password
        '500':
          description: internal server error
    put:
      tags:
        - account
      description: Apply the token to attach an app to the account. Access granted to valid attach token.
      operationId: set-account-app
      security:
        - bearerAuth: []
      responses:
        '201':
          description: generated
          content:
            application/json:
              schema:
                type: string
        '401':
          description: invalid token
        '406':
          description: app limit reached
        '500':
          description: internal server error
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/AppData'
          
  /account/apps/{appId}:
    delete:
      tags:
        - account
      description: Get list of attached apps. Access granted to account's username and password.
      operationId: remove-account-app
      security:
        - basicAuth: []
      parameters:
        - name: appId
          in: path
          description: specified app id 
          required: true
          schema:
            type: string
      responses:
        '200':
          description: successful operation
        '401':
          description: invalid password
        '404':
          description: app not found
        '500':
          description: internal server error
          
  /authenticate:
    put:
      tags:
        - authenticate
      description: Retrieve an authenticate data messaging verifying the account holder is accepting the action referenced by the token.
      operationId: authenticate
      security:
        - bearerAuth: []
      responses:
        '200':
          description: success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DataMessage'
        '401':
          description: permission denied
        '500':
          description: internal server error
      requestBody:
        content:
          application/json:
            schema:
              type: string
          
  /profile:
    get:
      tags:
        - profile
      description: Get profile of accunt. Access granted to app token of account holder.
      operationId: get-profile
      security:
        - bearerAuth: []
      responses:
        '200':
          description: success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Profile'
        '401':
          description: permission denied
        '500':
          description: internal server error
    put:
      tags:
        - profile
      description: Set profile data. Access granted to app tokens of account holder.
      operationId: set-profile
      security:
        - bearerAuth: []
      responses:
        '200':
          description: success
        '401':
          description: permission denied
        '500':
          description: internal server error
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ProfileData'
          
  /profile/image:
    get:
      tags:
        - profile
      description: Download base64 decoded data of profile image. Access granted to app tokens of account holder.
      operationId: get-profile-image
      security:
        - bearerAuth: []
      responses:
        '200':
          description: success
          content:
            application/octet-stream: # content specific
              schema:
                type: string
                format: binary
        '401':
          description: permission denied
        '405':
          description: invalid image
        '500':
          description: internal server error
          
  /profile/message:
    get:
      tags:
        - profile
      description: Get a profile data message. Access granted to app token of account holder or contact token of connected contact.
      operationId: get-profile-message
      security:
        - bearerAuth: []
      responses:
        '200':
          description: success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DataMessage'
        '401':
          description: permission denied
        '500':
          description: internal server error
          
  /share/groups:
    get:
      tags:
        - share
      description: Get groups for sharing. Access granted to app tokens of the account holder.
      operationId: get-groups
      security:
        - bearerAuth: []
      responses:
        '200':
          description: successful operation
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Group'
        '401':
          description: invalid token
        '500':
          description: internal server error
    post:
      tags:
        - share
      description: Add a group for sharing. Access granted to app tokens of account holder.
      operationId: add-group
      security:
        - bearerAuth: []
      responses:
        '200':
          description: entry created
        '401':
          description: permission denied
        '500':
          description: internal server error
      requestBody:
        content:
          application/json:
            schema:
              type: object
              required:
                - type
                - data
              properties:
                type:
                  type: string
                data:
                  type: string
          
  /share/groups/{groupId}:
    put:
      tags:
        - share
      description: Update group description for sharing. Access granted to app tokens of account holder.
      operationId: update-group
      security:
        - bearerAuth: []
      parameters:
        - name: groupId
          in: path
          description: specified group id 
          required: true
          schema:
            type: string
      responses:
        '200':
          description: success
        '401':
          description: permission denied
        '404':
          description: group not found
        '500':
          description: internal server error
      requestBody:
        content:
          application/json:
            schema:
              type: object
              required:
                - type
                - data
              properties:
                type:
                  type: string
                data:
                  type: string
    delete:
      tags:
        - share
      description: Remove sharing group
      operationId: remove-group
      security:
        - bearerAuth: []
      parameters:
        - name: groupId
          in: path
          description: specified group id 
          required: true
          schema:
            type: string
      responses:
        '200':
          description: success
        '401':
          description: permission denied
        '404':
          description: group not found
        '500':
          description: internal server error
          
  /contact/cards:
    post:
      tags:
        - contact
      description: Add a contact card. Access granted to app tokens of account holder.
      operationId: add-card
      security:
        - bearerAuth: []
      responses:
        '200':
          description: success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DataMessage'
        '400':
          description: invalid data message
        '401':
          description: permission denied
        '500':
          description: internal server error
          
  /contact/cards/view:
    get:
      tags:
        - contact
      description: Get list of card views. Access granted to app tokens of account holder.
      operationId: get-card-view
      security:
        - bearerAuth: []
      responses:
        '200':
          description: successful operation
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/CardView'
        '401':
          description: permission denied
        '500':
          description: internal server error
          
  /contact/cards/{cardId}:
    get:
      tags:
        - contact
      description: Retieve card entry. Permission granted to app tokens for account holder.
      operationId: get-card
      security:
        - bearerAuth: []
      parameters:
        - name: cardId
          in: path
          description: specified card id 
          required: true
          schema:
            type: string
      responses:
        '200':
          description: successful operation
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Card'
        '401':
          description: permission denied
        '404':
          description: card not found
        '500':
          description: internal server error
    delete:
      tags:
        - contact
      description: Remove card entry. Access granted to app tokens of account holder.
      operationId: remove-card
      security:
        - bearerAuth: []
      parameters:
        - name: cardId
          in: path
          description: specified card id 
          required: true
          schema:
            type: string
      responses:
        '200':
          description: success
        '401':
          description: permission denied
        '404':
          description: card not found
        '500':
          description: internal server error
  
  /contact/cards/{cardId}/status:
    put:
      tags:
        - contact
      description: Updated connected status of contact. Access granted to app tokens of account holder.
      operationId: set-card-status
      security:
        - bearerAuth: []
      parameters:
        - name: cardId
          in: path
          description: specified card id 
          required: true
          schema:
            type: string
        - name: token
          in: query
          description: token for accessing card
          required: false # required for connected 
          schema:
            type: string
      responses:
        '200':
          description: success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CardData'
        '401':
          description: permission denied
        '404':
          description: card not found
        '500':
          description: internal server error
      requestBody:
        content:
          application/json:
            schema:
              type: string
              enum: [ pending, confirmed, connecting, connected ]
          
  /contact/cards/{cardId}/openMessage:
    get:
      tags:
        - contact
      description: Get message for connecting to other contacts. Access granted to app tokens for account holder.
      operationId: get-open-message
      security:
        - bearerAuth: []
      parameters:
        - name: cardId
          in: path
          description: specified card id 
          required: true
          schema:
            type: string
      responses:
        '200':
          description: success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DataMessage'
        '401':
          description: permission denied
        '404':
          description: card not found
        '500':
          description: internal server error
          
  /contact/openMessage:
    put:
      tags:
        - contact
      description: Set message for connecting to a contact. If card has not already been added, the card will be created in the pending state. Access granted to public.
      operationId: set-open-message
      responses:
        '200':
          description: successful operation
          content:
            application/json:
              schema:
                type: object
                required:
                  - status
                properties:
                  token:
                    type: string
                  status:
                    type: string
                    enum: [ pending, confirmed, requested, connecting, connected ]
        '400':
          description: invalid data message
        '500':
          description: internal server error
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/DataMessage'
          
  /contact/cards/{cardId}/closeMessage:
    get:
      tags:
        - contact
      description: Get message for closing connection with contact. Access granted to app tokens for account holder.
      operationId: get-close-message
      security:
        - bearerAuth: []
      parameters:
        - name: cardId
          in: path
          description: specified card id 
          required: true
          schema:
            type: string
      responses:
        '200':
          description: successful operation
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DataMessage'
        '401':
          description: permission denied
        '404':
          description: card not found
        '500':
          description: internal server error
          
  /contact/closeMessage:
    put:
      tags:
        - contact
      description: Set message for closing card connection. Access granted to public.
      operationId: set-close-message
      responses:
        '200':
          description: successful operation
          content:
            application/json:
              schema:
                type: object
                required:
                  - status
                properties:
                  token:
                    type: string
                  status:
                    type: string
                    enum: [ pending, confirmed, requested, connecting, connected ]
        '400':
          description: invalid data message
        '500':
          description: internal server error
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/DataMessage'
          
  /contact/cards/{cardId}/profile:
    get:
      tags:
        - contact
      description: Get profile of card entry. Access granted to app tokens of account holder.
      operationId: get-card-profile
      security:
        - bearerAuth: []
      parameters:
        - name: cardId
          in: path
          description: specified card id 
          required: true
          schema:
            type: string
      responses:
        '200':
          description: successful operation
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CardProfile'
        '401':
          description: permission denied
        '404':
          description: not found
        '500':
          description: internal server error
    put:
      tags:
        - contact
      description: Set profile of card entry. Access granted to app tokens of account holder.
      operationId: set-card-profile
      security:
        - bearerAuth: []
      parameters:
        - name: cardId
          in: path
          description: specified card id 
          required: true
          schema:
            type: string
      responses:
        '200':
          description: success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DataMessage'
        '401':
          description: permission denied
        '404':
          description: card not found
        '500':
          description: internal server error
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Profile'
          
  /contact/cards/{cardId}/profile/image:
    get:
      tags:
        - contact
      description: Get image of card profile. Access granted to app tokens of account holder.
      operationId: get-card-profile-image
      security:
        - bearerAuth: []
      parameters:
        - name: cardId
          in: path
          description: specified card id 
          required: true
          schema:
            type: string
      responses:
        '200':
          description: success
          content:
            application/octet-stream: #asset specific
              schema:
                type: string
                format: binary
        '401':
          description: permission denied
        '404':
          description: card not found
        '405':
          description: invalid image
        '500':
          description: internal server error
          
  /contact/cards/{cardId}/data:
    get:
      tags:
        - contact
      description: Get specified card data. Access granted to app tokens for account holder.
      operationId: get-card-data
      security:
        - bearerAuth: []
      parameters:
        - name: cardId
          in: path
          description: specified card id 
          required: true
          schema:
            type: string
      responses:
        '200':
          description: success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CardData'
        '401':
          description: permission denied
        '404':
          description: card not found
        '500':
          description: internal server error
          
  /contact/cards/{cardId}/notes:
    put:
      tags:
        - contact
      description: Update card notes for specified card. Access granted to app tokens for account holder.
      operationId: set-card-notes
      security:
        - bearerAuth: []
      parameters:
        - name: cardId
          in: path
          description: specified card id 
          required: true
          schema:
            type: string
      responses:
        '200':
          description: success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CardData'
        '401':
          description: permission denied
        '404':
          description: card not found
        '500':
          description: internal server error
      requestBody:
        content:
          application/json:
            schema:
              type: string
    delete:
      tags:
        - contact
      description: Clear notes for specified card. Access granted to app tokens of account holder.
      operationId: clear-card-notes
      security:
        - bearerAuth: []
      parameters:
        - name: cardId
          in: path
          description: specified card id 
          required: true
          schema:
            type: string
      responses:
        '200':
          description: success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CardData'
        '401':
          description: permission denied
        '404':
          description: card not found
        '500':
          description: internal server error
            
  /contact/cards/{cardId}/groups/{groupId}:
    put:
      tags:
        - contact
      description: Set sharing group for contact. Access granted to app tokens for account holder. 
      operationId: set-card-group
      security:
        - bearerAuth: []
      parameters:
        - name: cardId
          in: path
          description: specified card id 
          required: true
          schema:
            type: string
        - name: groupId
          in: path
          description: specified group id 
          required: true
          schema:
            type: string
      responses:
        '200':
          description: success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CardData'
        '401':
          description: permission denied
        '404':
          description: card or group not found
        '500':
          description: internal server error
    delete:
      tags:
        - contact
      description: Clear sharing group for card. Access granted to app tokens for account holder.
      operationId: clear-card-group
      security:
        - bearerAuth: []
      parameters:
        - name: cardId
          in: path
          description: specified card id 
          required: true
          schema:
            type: string
        - name: groupId
          in: path
          description: specified share id 
          required: true
          schema:
            type: string
      responses:
        '200':
          description: success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CardData'
        '401':
          description: permission denied
        '404':
          description: card or group not found
        '500':
          description: internal server error
          
  /contact/profile/revision:
    put:
      tags:
        - contact
      description: Set profile revision for contact. This is intend to be invoked automatically anytime a contact updates their profile. Access granted to contact tokens.
      operationId: set-profile-revision
      security:
        - bearerAuth: []
      responses:
        '200':
          description: revision set
        '401':
          description: not authorized
        '500':
          description: internal server error
      requestBody:
        content:
          application/json:
            schema:
              type: integer
              format: int64
        
  /contact/content/revision:
    put:
      tags:
        - contact
      description: Set content revision for contact. This is intend to be invoked automatically anytime a contact updates their content or sharing. Access granted to contact tokens.
      operationId: set-content-revision
      security:
        - bearerAuth: []
      responses:
        '200':
          description: revision set
        '401':
          description: not authorized
        '500':
          description: internal server error
      requestBody:
        content:
          application/json:
            schema:
              type: integer
              format: int64
              
  /content/articleBlocks/view:
    get:
      tags:
        - content
      description: Get article block views. Acess granted to account token or contact token. When the request is made with a contact token the account view revision will be added to the block revision.
      operationId: get-article-block-view
      security:
        - bearerAuth: []
      responses:
        '200':
          description: successful operation
          content:
            application/json:
              schema:
                type: array
                items:
                  type: object
                  properties:
                    id:
                      type: string
                    revision:
                      type: integer
                      format: int64
        '401':
          description: permission denied
        '500':
          description: internal server error
          
  /content/articleBlocks/{blockId}:
    get:
      tags:
        - content
      description: Get the articles within specified block. Access granted for app token or contact token. All of the articles are returned for the app token, but only the shared articles are returned for the contact token. An article is shared by assigning a common group to an article or assigning a label to an article that has assigned a common group.
      operationId: get-articles
      security:
        - bearerAuth: []
      parameters:
        - name: blockId
          in: path
          description: specified group id 
          required: true
          schema:
            type: string
      responses:
        '200':
          description: successful operation
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Article'
        '401':
          description: permission denied
        '404':
          description: block not found
        '500':
          description: internal server error
          
  /content/articleBlocks/{blockId}/view:
    get:
      tags:
        - content
      description: Get the article views within specified block. Access granted for app token or contact token. All of the articles are returned for the app token, but only the shared articles are returned for the contact token. An article is shared by assigning a common group to an article or assigning a label to an article that has assigned a common group.
      operationId: get-article-views
      security:
        - bearerAuth: []
      parameters:
        - name: blockId
          in: path
          description: specified group id 
          required: true
          schema:
            type: string
      responses:
        '200':
          description: successful operation
          content:
            application/json:
              schema:
                type: array
                items:
                  type: object
                  properties:
                    id:
                      type: string
                    revision:
                      type: integer
                      format: int64
        '401':
          description: permission denied
        '404':
          description: block not found
        '500':
          description: internal server error
          
  /content/articles:
    post:
      tags:
        - content
      description: Add a content article. Access granted to app token of the account holder.
      operationId: add-article
      security:
        - bearerAuth: []
      responses:
        '201':
          description: entry created
          content:
            application/json:
              schema:
                type: object
                properties:
                  blockId:
                    type: string
                  blockRevision:
                    type: integer
                    format: int64
                  article:
                    $ref: '#/components/schemas/Article'
        '401':
          description: permission denied
        '500':
          description: internal server error
      requestBody:
        content:
          application/json:
            schema:
              type: object
              required:
                - labels
                - groups
              properties:
                labels:
                  type: array
                  items:
                    type: string
                groups:
                  type: array
                  items:
                    type: string
              
  /content/articles/{articleId}:
    get:
      tags:
        - content
      description: Get specified article. Access granted to app token of account holder or contact token of account the article is shared with.
      operationId: get-article
      security:
        - bearerAuth: []
      parameters:
        - name: articleId
          in: path
          description: specified article id 
          required: true
          schema:
            type: string
      responses:
        '200':
          description: success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Article'
        '401':
          description: permission denied
        '404':
          description: article not found
        '500':
          description: internal server error
    delete:
      tags:
        - content
      description: Remove specified article. Access granted to app token of account holder.
      operationId: remove-article
      security:
        - bearerAuth: []
      parameters:
        - name: articleId
          in: path
          description: specified article id 
          required: true
          schema:
            type: string
      responses:
        '200':
          description: success
        '401':
          description: invalid password
        '404':
          description: article not found
        '500':
          description: internal server error
  
  /content/articles/{articleId}/subject/{field}:
    get:
      tags:
        - content
      description: Base64 decode and download specified field from the article's subject. Access granted to app token of account holder or contact token of account the article is shared with.
      operationId: get-article-subject-field
      security:
        - bearerAuth: []
      parameters:
        - name: articleId
          in: path
          description: specified article id 
          required: true
          schema:
            type: string
        - name: field
          in: path
          description: field from subject to base64 decode and download 
          required: true
          schema:
            type: string
      responses:
        '200':
          description: success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Article'
        '401':
          description: permission denied
        '404':
          description: field, article not found
        '405':
          description: invalid field
        '500':
          description: internal server error
          
  /content/articles/{articleId}/subject:
    put:
      tags:
        - content
      description: Set subject for article. Access granted to app token of account holder.
      operationId: set-article-subject
      security:
        - bearerAuth: []
      parameters:
        - name: articleId
          in: path
          description: specified article id 
          required: true
          schema:
            type: string
      responses:
        '200':
          description: success
        '401':
          description: permission denied
        '404':
          description: article not found
        '500':
          description: internal server error
      requestBody:
        content:
          application/json:
            schema:
              type: object
              required:
                - type
                - data
              properties:
                type:
                  type: string
                data:
                  type: string
                  
  /content/articles/{articleId}/groups/{groupId}:
    post:
      tags:
        - content
      description: Assign a sharing group for the specified article. Contacts with the same sharing group will have access to the article. Access granted to app token of account holder.
      operationId: set-article-group
      security:
        - bearerAuth: []
      parameters:
        - name: articleId
          in: path
          description: specified article id 
          required: true
          schema:
            type: string
        - name: groupId
          in: path
          description: specified share group id 
          required: true
          schema:
            type: string
      responses:
        '200':
          description: success
        '401':
          description: permission denied
        '404':
          description: group or article not found
        '500':
          description: internal server error
    delete:
      tags:
        - content
      description: Remove article from sharing group. Unless the article is shared through other groups or labels contacts within that group will no longer have access to the article. Access granted to app tokens of the account holder.
      operationId: clear-article-group
      security:
        - bearerAuth: []
      parameters:
        - name: articleId
          in: path
          description: specified article id 
          required: true
          schema:
            type: string
        - name: groupId
          in: path
          description: specified share id 
          required: true
          schema:
            type: string
      responses:
        '200':
          description: success
        '401':
          description: permission denied
        '404':
          description: group or article not found
        '500':
          description: internal server error
  
  /content/articles/{articleId}/labels/{labelId}:
    post:
      tags:
        - content
      description: Assign a label to an article. If the label has been assigned a sharing group the article will be accessible by contacts within that group. Access is granted to app tokens of the account holder.
      operationId: set-article-label
      security:
        - bearerAuth: []
      parameters:
        - name: articleId
          in: path
          description: specified article id 
          required: true
          schema:
            type: string
        - name: labelId
          in: path
          description: specified label id 
          required: true
          schema:
            type: string
      responses:
        '200':
          description: success
        '401':
          description: permission denied
        '404':
          description: label or article not found
        '500':
          description: internal server error
    delete:
      tags:
        - content
      description: Remove a label from an article. If the label has been assigned a sharing group the article and the article is not shared in another way, the article will no longer be accessible to that group's contacts. Access is granted to app tokens of the account holder.
      operationId: clear-article-label
      security:
        - bearerAuth: []
      parameters:
        - name: articleId
          in: path
          description: specified article id 
          required: true
          schema:
            type: string
        - name: labelId
          in: path
          description: specified label id 
          required: true
          schema:
            type: string
      responses:
        '200':
          description: success
        '401':
          description: permission denied
        '404':
          description: label or article not found
        '500':
          description: internal server error
          
  /content/articles/{articleId}/assets:
    get:
      tags:
        - content
      description: Get list of assets assigned to an article. The original assets will only be available to the account holder to provent the accidental sharing of content metadata. Access is granted to the app token of the account holder and the contact token of accounts the article has been shared with.
      operationId: get-article-assets
      security:
        - bearerAuth: []
      parameters:
        - name: articleId
          in: path
          description: specified article id 
          required: true
          schema:
            type: string
      responses:
        '201':
          description: entry created
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Asset'
        '401':
          description: invalid token
        '500':
          description: internal server error
    post:
      tags:
        - content
      description: Add an an asset to the to an article. The original posted asset is referenced in the asset list with a null transform. The transformed assets are referenced accordingly. Transforming the asset strips it of metadata and transcodes it into a specified format. Access is granted to the app token of the account holder.
      operationId: add-article-asset
      security:
        - bearerAuth: []
      parameters:
        - name: articleId
          in: path
          description: specified article id 
          required: true
          schema:
            type: string
        - name: transforms
          in: query
          description: transforms to apply
          required: false
          schema:
            type: array
            items:
              type: string
      responses:
        '201':
          description: success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Asset'
        '401':
          description: permission denied
        '404':
          description: article not found
        '406':
          description: storage limit reached
        '500':
          description: internal server error
      requestBody:
        content:
          multipart/form-data:
            schema:
              type: object
              properties:
                fileName:
                  type: string
                  format: binary
          
  /content/articles/{articleId}/assets/{assetId}:
    get:
      tags:
        - content
      description: Get asset assigned to an article. The endpoint supports byte-range requests and responds with the content-type set appropriatly. Access granted to the app tokens of the account holder and in the case of non-original assets, the contact token for accounts with which the article is shared.
      operationId: get-article-asset
      security:
        - bearerAuth: []
      parameters:
        - name: articleId
          in: path
          description: specified article id 
          required: true
          schema:
            type: string
        - name: assetId
          in: path
          description: specified asset id 
          required: true
          schema:
            type: string
      responses:
        '200':
          description: success
          content:
            application/octet-stream: #asset specific
              schema:
                type: string
                format: binary
        '401':
          description: permission denied
        '404':
          description: asset or article not found
        '500':
          description: internal server error
    delete:
      tags:
        - content
      description: Remove an asset from an article. Access granted to app tokens of the account holder.
      operationId: remove-article-asset
      security:
        - bearerAuth: []
      parameters:
        - name: articleId
          in: path
          description: specified article id 
          required: true
          schema:
            type: string
        - name: assetId
          in: path
          description: specified asset id 
          required: true
          schema:
            type: string
      responses:
        '200':
          description: success
        '401':
          description: permission denied
        '404':
          description: asset or article not found
        '500':
          description: internal server error
          
  /content/articles/{articleId}/confirmed:
    put:
      tags:
        - content
      description: Set confirmed state of the article. Until the confirmed state has been set to true, the article will not be visible to contacts with which the article is shared. Access granted to the app tokens of the acocunt holder.
      operationId: set-article-confirmed
      security:
        - bearerAuth: []
      parameters:
        - name: articleId
          in: path
          description: specified article id 
          required: true
          schema:
            type: string
      responses:
        '200':
          description: success
        '401':
          description: permission denied
        '404':
          description: article not found
        '500':
          description: internal server error
      requestBody:
        content:
          application/json:
            schema:
              type: boolean
          
  /content/articles/{articleId}/tagBlocks/view:
    get:
      tags:
        - content
      description: Get view of tag blocks associated with specified article. Access granted to app tokens of account holder and contact tokens of account with which the article is shared. 
      operationId: get-article-tag-block-view
      security:
        - bearerAuth: []
      parameters:
        - name: articleId
          in: path
          description: specified article id 
          required: true
          schema:
            type: string
        - name: types
          in: query
          description: limit results to tags of types
          required: false
          schema:
            type: array
            items:
              type: string
      responses:
        '200':
          description: success
          content:
            application/json:
              schema:
                type: array
                items:
                  type: object
                  properties:
                    id:
                      type: string
                    revision:
                      type: integer
                      format: int64
        '401':
          description: permission denied
        '404':
          description: article not found
        '500':
          description: internal server error
          
  /content/articles/{articleId}/tagBlocks/{blockId}/view:
    get:
      tags:
        - content
      description: Get view of tags within speicified block. Access granted to app tokens of account holder and contact token of accounts with which the article is shared. 
      operationId: get-article-tag-view
      security:
        - bearerAuth: []
      parameters:
        - name: articleId
          in: path
          description: specified article id 
          required: true
          schema:
            type: string
        - name: blockId
          in: path
          description: specified block id 
          required: true
          schema:
            type: string
        - name: types
          in: query
          description: limit results to tags of types
          required: false
          schema:
            type: array
            items:
              type: string
      responses:
        '200':
          description: success
          content:
            application/json:
              schema:
                type: array
                items:
                  type: object
                  properties:
                    id:
                      type: string
                    revision:
                      type: integer
                      format: int64
        '401':
          description: permission denied
        '404':
          description: block or article not found
        '500':
          description: internal server error
          
  /content/articles/{articleId}/tagBlocks/{blockId}:
    get:
      tags:
        - content
      description: Get tags within specified block. Access granted to app tokens of account holder and contact tokens of accounts with which the article is shared.
      operationId: get-article-tags
      security:
        - bearerAuth: []
      parameters:
        - name: articleId
          in: path
          description: specified article id 
          required: true
          schema:
            type: string
        - name: blockId
          in: path
          description: specified block id 
          required: true
          schema:
            type: string
        - name: types
          in: query
          description: limit results to tags of types
          required: false
          schema:
            type: array
            items:
              type: string
      responses:
        '200':
          description: success
          content:
            application/json:
              schema:
                type: array
                items:
                  type: object
                  properties:
                    id:
                      type: string
                    revision:
                      type: integer
                      format: int64
        '401':
          description: permission denied
        '404':
          description: block or article not found
        '500':
          description: internal server error
          
  /content/articles/{articleId}/tags:
    post:
      tags:
        - content
      description: Add a tag to an article. Access granted to app tokens of the account holder and contact tokens of accounts with which the article is shared.
      operationId: add-article-tag
      security:
        - bearerAuth: []
      parameters:
        - name: articleId
          in: path
          description: specified article id 
          required: true
          schema:
            type: string
      responses:
        '200':
          description: success
          content:
            application/json:
              schema:
                type: object
                properties:
                  blockId:
                    type: string
                  blockRevision:
                    type: integer
                    format: int64
                  tag:
                    $ref: '#/components/schemas/Tag'
        '401':
          description: permission denied
        '404':
          description: article not found
        '500':
          description: internal server error
              
  /content/articles/{articleId}/tags/{tagId}:
    get:
      tags:
        - content
      description: Get specified tag. Access granted to app tokens of account holder and contact tokens of accounts with which the article is shared.
      operationId: get-article-tag
      security:
        - bearerAuth: []
      parameters:
        - name: articleId
          in: path
          description: specified article id 
          required: true
          schema:
            type: string
        - name: tagId
          in: path
          description: specified tag id 
          required: true
          schema:
            type: string
      responses:
        '200':
          description: success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Tag'
        '401':
          description: permission denied
        '404':
          description: tag or article not found
        '500':
          description: internal server error
    delete:
      tags:
        - content
      description: Remove a tag from an article. Access granted to app tokens of account holder and the contact tokens of the account that created the tag.
      operationId: remove-article-tag
      security:
        - bearerAuth: []
      parameters:
        - name: articleId
          in: path
          description: specified article id 
          required: true
          schema:
            type: string
        - name: tagId
          in: path
          description: specified tag id 
          required: true
          schema:
            type: string
      responses:
        '200':
          description: success
        '401':
          description: permission denied
        '404':
          description: tag or article not found
        '500':
          description: internal server error
              
  /content/articles/{articleId}/tags/{tagId}/subject/{field}:
    get:
      tags:
        - content
      description: Base64 decode and retrieve specified tag on the article. Access granted to app tokens of account holder and contact tokens of accounts with which the article is shared.
      operationId: get-article-tag-subject-field
      security:
        - bearerAuth: []
      parameters:
        - name: articleId
          in: path
          description: specified article id 
          required: true
          schema:
            type: string
        - name: tagId
          in: path
          description: specified tag id 
          required: true
          schema:
            type: string
        - name: field
          in: path
          description: field to base64 decode and transfer 
          required: true
          schema:
            type: string
      responses:
        '200':
          description: success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Tag'
        '401':
          description: permission denied
        '404':
          description: field, tag or article not found
        '405':
          description: invalid field
        '500':
          description: internal server error
          
  /content/labels:
    get:
      tags:
        - content
      description: Get labels with which to organize the articles. Contacts requesting the labels will only retrieve the labels with which they are shared. Access granted to the app tokens of the account holder and connected contact tokens.
      operationId: get-labels
      security:
        - bearerAuth: []
      responses:
        '200':
          description: successful operation
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Label'
        '401':
          description: invalid token
        '500':
          description: internal server error
    post:
      tags:
        - content
      description: Add a new label for organizing the articles. Access granted to the app tokens of the account holder.
      operationId: add-label
      security:
        - bearerAuth: []
      responses:
        '200':
          description: success
        '401':
          description: permission denied
        '500':
          description: internal server error
      requestBody:
        content:
          application/json:
            schema:
              type: object
              required:
                - type
                - data
              properties:
                type:
                  type: string
                data:
                  type: string
          
  /content/labels/{labelId}:
    put:
      tags:
        - content
      description: Update specified label. Access granted to app tokens of the account holder.
      operationId: update-label
      security:
        - bearerAuth: []
      parameters:
        - name: labelId
          in: path
          description: specified group id 
          required: true
          schema:
            type: string
      responses:
        '200':
          description: successful operation
        '401':
          description: invalid token
        '500':
          description: internal server error
      requestBody:
        content:
          application/json:
            schema:
              type: object
              required:
                - type
                - data
              properties:
                type:
                  type: string
                data:
                  type: string
    delete:
      tags:
        - content
      description: Remove specified label. Access granted the the app tokens of the account holder.
      operationId: remove-label
      security:
        - bearerAuth: []
      parameters:
        - name: labelId
          in: path
          description: specified label id 
          required: true
          schema:
            type: string
      responses:
        '200':
          description: success
        '401':
          description: permission denied
        '404':
          description: label not found
        '500':
          description: internal server error
          
                  
  /content/labels/{labelId}/groups/{groupId}:
    post:
      tags:
        - content
      description: Set a sharing group for the label and articles assigned to the label. Access granted to app tokens of the account holder.
      operationId: set-label-group
      security:
        - bearerAuth: []
      parameters:
        - name: labelId
          in: path
          description: specified label id 
          required: true
          schema:
            type: string
        - name: groupId
          in: path
          description: specified group id 
          required: true
          schema:
            type: string
      responses:
        '200':
          description: success
        '401':
          description: permission denied
        '404':
          description: group or label not found
        '500':
          description: internal server error
    delete:
      tags:
        - content
      description: Clear a sharing group from a label. Access granted to app tokens of the account holder.
      operationId: clear-label-group
      security:
        - bearerAuth: []
      parameters:
        - name: labelId
          in: path
          description: specified label id 
          required: true
          schema:
            type: string
        - name: groupId
          in: path
          description: specified group id 
          required: true
          schema:
            type: string
      responses:
        '200':
          description: success
        '401':
          description: permission denied
        '404':
          description: group or label not found
        '500':
          description: internal server error
              
  /conversation/dialogues:
    get:
      tags:
        - conversation
      description: Retrieve all dialogues.
      operationId: get-dialogues
      security:
        - bearerAuth: []
      responses:
        '200':
          description: success
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Dialogue'
        '401':
          description: permission denied
        '500':
          description: internal server error
    post:
      tags:
        - conversation
      description: Create and host a new dialogue. Authroization granted to an app token of the account holder.
      operationId: add-dialogue
      security:
        - bearerAuth: []
      responses:
        '200':
          description: success
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Dialogue'
        '401':
          description: permission denied
        '500':
          description: internal server error
          
  /conversation/dialogues/{dialogueId}/subject:
    put:
      tags:
        - conversation
      description: Set the subject for a dialogue. Authorization granted the an app token for the account holder.
      operationId: set-dialogue-subject
      security:
        - bearerAuth: []
      parameters:
        - name: dialogueId
          in: path
          description: specified dialogue id 
          required: true
          schema:
            type: string
      responses:
        '201':
          description: success
        '401':
          description: permission denied
        '404':
          description: dialogue not found
        '500':
          description: internal server error
      requestBody:
        content:
          application/json:
            schema:
              type: object
              required:
                - type
                - data
              properties:
                type:
                  type: string
                data:
                  type: string
    
  /conversation/dialogues/{dialogueId}/active:
    put:
      tags:
        - conversation
      description: Set active state of dialogue. If a dialogue is inactive any update to the topics will fail. Authorization is granted to an app token of the account holder.
      operationId: set-dialogue-active
      security:
        - bearerAuth: []
      parameters:
        - name: dialogueId
          in: path
          description: specified dialogue id 
          required: true
          schema:
            type: string
      responses:
        '200':
          description: success
        '401':
          description: permission denied
        '404':
          description: dialogue not found
        '500':
          description: internal server error
      requestBody:
        content:
          application/json:
            schema:
              type: boolean
                  
  /conversation/dialogues/{dialogueId}/cards/{cardId}:
    put:
      tags:
        - conversation
      description: Add insight to a dialogue. This endpoint will automatically invoke the add insight on the contact's node. Authorization is granted to the app token of the account holder. 
      operationId: add-dialogue-insight
      security:
        - bearerAuth: []
      parameters:
        - name: dialogueId
          in: path
          description: specified dialogue id 
          required: true
          schema:
            type: string
        - name: cardId
          in: path
          description: specified card id
          required: true
          schema:
            type: string
      responses:
        '200':
          description: success
        '401':
          description: permission denied
        '404':
          description: cardId or dialogue not found
        '500':
          description: internal server error
    delete:
      tags:
        - conversation
      description: Remove an insight from a dialogue. This endpoint will authomatically invoke the delete insight endpoint on the contact's node. Authorization is granted to the app token of the accoun holder. 
      operationId: remove-dialogue-insight
      security:
        - bearerAuth: []
      parameters:
        - name: dialogueId
          in: path
          description: specified dialogue id 
          required: true
          schema:
            type: string
        - name: cardId
          in: path
          description: specified contact id 
          required: true
          schema:
            type: string
      responses:
        '200':
          description: success
        '401':
          description: permission denied
        '404':
          description: cardId or dialogue not found
        '500':
          description: internal server error
          
  /conversation/dialogues/{dialogueId}/status:
    put:
      tags:
        - conversation
      description: Set active status for contact on the host node. Access is granted to a contact token for an account with the specified contact
      operationId: set-dialogue-insight-status
      security:
        - bearerAuth: []
      parameters:
        - name: dialogueId
          in: path
          description: specified dialogue id 
          required: true
          schema:
            type: string
      responses:
        '200':
          description: success
        '401':
          description: permission denied
        '404':
          description: dialogue not found
        '500':
          description: internal server error
      requestBody:
        content:
          application/json:
            schema:
              type: string
              enum: [ active, inactive, dismissed ]
          
  /conversation/dialogues/{dialogueId}:
    delete:
      tags:
        - conversation
      description: Remove specified dialogue. This endpoint will authomatically invoke the delete insight endpoint on all of the contacts' nodes. Access is granted to an app token for the account holder.
      operationId: remove-dialogue
      security:
        - bearerAuth: []
      parameters:
        - name: dialogueId
          in: path
          description: specified dialogue id 
          required: true
          schema:
            type: string
      responses:
        '200':
          description: success
        '401':
          description: permission denied
        '404':
          description: dialogue not found
        '500':
          description: internal server error
  
  /conversation/insights:
    get:
      tags:
        - conversation
      description: Retrieve all insights. Access granted to app token for the account holder.
      operationId: get-insights
      security:
        - bearerAuth: []
      paramters:
        - name: dismissed
          in: query
          description: if dismissed insights should be included 
          required: false
          schema:
            type: string
      responses:
        '200':
          description: success
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Insight'
        '401':
          description: permission denied
        '500':
          description: internal server error
          
  /conversation/insights/{dialogueId}:
    post:
      tags:
        - conversation
      description: Create or update an insight. Because the insightId is not know by the contact, it is determined from the token and the dialogueId. Access granted to a connected contact token.
      operationId: add-insight-dialogue
      security:
        - bearerAuth: []
      parameters:
        - name: dialogueId
          in: path
          description: dialogue with insight id to update
          required: true
          schema:
            type: string
      responses:
        '200':
          description: success
          content:
            application/json:
              schema:
                type: string
                enum: [ active, inactive, dismissed ]
        '401':
          description: permission denied
        '404':
          description: dialogue not found
        '500':
          description: internal server error
      requestBody:
        content:
          application/json:
            schema:
              type: integer
              format: int64
    delete:
      tags:
        - conversation
      description: Remove a specified insight. If the referenced dialogue is still active, the insight will get recreated with the next hook receiver update. Access granted to contact token of a connected card.
      operationId: set-insight-dialogue
      security:
        - bearerAuth: []
      parameters:
        - name: dialogueId
          in: path
          description: insight id to update
          required: true
          schema:
            type: string
      responses:
        '200':
          description: success
        '401':
          description: permission denied
        '404':
          description: dialogue not found
        '500':
          description: internal server error
  
  /conversation/insights/{insightId}/status:
    put:
      tags:
        - conversation
      description: Set the status of an insight. This will cause the hook receiver to return an inactive status. Access granted to app token of account holder. 
      operationId: set-insight-status
      security:
        - bearerAuth: []
      parameters:
        - name: insightId
          in: path
          description: dialogue with insight id to update
          required: true
          schema:
            type: string
      responses:
        '200':
          description: success
        '401':
          description: permission denied
        '403':
          description: invalid state # once dismissed always dismissed
        '404':
          description: insight not found
        '500':
          description: internal server error
      requestBody:
        content:
          application/json:
            schema:
              type: string
              enum: [ active, inactive, dismissed ]
              
  /conversation/dialogues/{dialogueId}/topicBlocks/view:
    get:
      tags:
        - conversation
      description: Get a view of the topicBlocks within a dialogue. Authorization granted to account holder app token or dialogue member contact token who is also a member of the dialogue
      operationId: get-topic-block-view
      security:
        - bearerAuth: []
      parameters:
        - name: dialogueId
          in: path
          description: specified dialogue id
          required: true
          schema:
            type: string
        - name: types
          in: query
          description: limit results to topics of types
          required: false
          schema:
            type: array
            items:
              type: string
      responses:
        '200':
          description: success
          content:
            application/json:
              schema:
                type: array
                items:
                  type: object
                  properties:
                    id:
                      type: string
                    revision:
                      type: integer
                      format: int64
        '401':
          description: permission denied
        '404':
          description: dialogue not found
        '500':
          description: internal server error
          
  /conversation/dialogues/{dialogueId}/topicBlocks/{blockId}:
    get:
      tags:
        - conversation
      description: Get the topics within a topicBlock. Only the account holder and the topic creator will retrieve pending topics. Authorization granted to account holder app token or dialogue member contact token who is also a member of the dialogue
      operationId: get-topic-block
      security:
        - bearerAuth: []
      parameters:
        - name: dialogueId
          in: path
          description: specified dialogue id
          required: true
          schema:
            type: string
        - name: blockId
          in: path
          description: specified group id 
          required: true
          schema:
            type: string
        - name: types
          in: query
          description: limit results to topics of types
          required: false
          schema:
            type: array
            items:
              type: string
      responses:
        '200':
          description: successful operation
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Topic'
        '401':
          description: permission denied
        '404':
          description: block or dialogue not found
        '500':
          description: internal server error
          
  /conversation/dialogues/{dialogueId}/topicBlocks/{blockId}/view:
    get:
      tags:
        - conversation
      description: Get a view of the topics within a topicBlock. Authorization granted to account holder app token or dialogue member contact token who is also a member of the dialogue.
      operationId: get-topic-views
      security:
        - bearerAuth: []
      parameters:
        - name: dialogueId
          in: path
          description: specified dialogue id
          required: true
          schema:
            type: string
        - name: blockId
          in: path
          description: specified group id 
          required: true
          schema:
            type: string
        - name: types
          in: query
          description: limit results to topics of types
          required: false
          schema:
            type: array
            items:
              type: string
      responses:
        '200':
          description: successful operation
          content:
            application/json:
              schema:
                type: array
                items:
                  type: object
                  properties:
                    id:
                      type: string
                    revision:
                      type: integer
                      format: int64
        '401':
          description: permission denied
        '404':
          description: block or dialogue not found
        '500':
          description: internal server error
          
  /conversation/dialogues/{dialogueId}/topics:
    post:
      tags:
        - conversation
      description: Add a topic to a dialogue. The response contains the topicBlock ID and topicBlock revision to which the topic is assigned. Authorization granted to account holder app token or dialogue member contact token who is a member of the dialogue.
      operationId: add-dialogue-topic
      security:
        - bearerAuth: []
      parameters:
        - name: dialogueId
          in: path
          description: specified dialogue id
          required: true
          schema:
            type: string
      responses:
        '201':
          description: entry created
          content:
            application/json:
              schema:
                type: object
                properties:
                  blockId:
                    type: string
                  blockRevision:
                    type: integer
                    format: int64
                  topic:
                    $ref: '#/components/schemas/Topic'
        '401':
          description: permission denied
        '403':
          description: inactive dialogue
        '404':
          description: dialogue not found
        '500':
          description: internal server error
              
  /conversation/dialogues/{dialogueId}/topics/{topicId}:
    get:
      tags:
        - conversation
      description: Retrieve a specified dialogue topic. Authorization granted to account holder app token or dialogue member contact token who is a member of the dialogue.
      operationId: get-dialogue-topic
      security:
        - bearerAuth: []
      parameters:
        - name: dialogueId
          in: path
          description: specified dialogue id
          required: true
          schema:
            type: string
        - name: topicId
          in: path
          description: specified topic id 
          required: true
          schema:
            type: string
      responses:
        '200':
          description: successful operation
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Topic'
        '401':
          description: permission denied
        '404':
          description: topic or dialogue not found
        '500':
          description: internal server error
    delete:
      tags:
        - conversation
      description: Remove a topic from a dialogue. Authorization granted to account holder app token or dialogue member contact token who is either the topic createor or the account holder.
      operationId: remove-dialogue-topic
      security:
        - bearerAuth: []
      parameters:
        - name: dialogueId
          in: path
          description: specified dialogue id
          required: true
          schema:
            type: string
        - name: topicId
          in: path
          description: specified topic id 
          required: true
          schema:
            type: string
      responses:
        '200':
          description: successful operation
        '401':
          description: permission denied
        '403':
          description: inactive dialogue
        '404':
          description: topic or dilaogue not found
        '500':
          description: internal server error
  
  /conversation/dialogues/{dialogueId}/topics/{topicId}/subject/{field}:
    get:
      tags:
        - conversation
      description: Base64 decode and retrieve a specified field from subject of dialogue topic. Authorization granted to account holder app token or dialogue member contact token who is a member of the dialogue.
      operationId: get-dialogue-topic-subject-field
      security:
        - bearerAuth: []
      parameters:
        - name: dialogueId
          in: path
          description: specified dialogue id
          required: true
          schema:
            type: string
        - name: topicId
          in: path
          description: specified topic id 
          required: true
          schema:
            type: string
        - name: field
          in: path
          description: field to base64 decode and retrieve 
          required: true
          schema:
            type: string
      responses:
        '200':
          description: success
          content:
            application/octet-stream: #asset specific
              schema:
                type: string
                format: binary
        '401':
          description: permission denied
        '404':
          description: field, topic or dialogue not found
        '405':
          description: invalid field
        '500':
          description: internal server error
          
  /conversation/dialogues/{dialogueId}/topics/{topicId}/subject:
    put:
      tags:
        - conversation
      description: Set the subject for a topic. Authorization granted to account holder app token or dialogue member contact token who is also the creator of the topic.
      operationId: set-topic-subject
      security:
        - bearerAuth: []
      parameters:
        - name: dialogueId
          in: path
          description: specified dialogue id
          required: true
          schema:
            type: string
        - name: topicId
          in: path
          description: specified topic id 
          required: true
          schema:
            type: string
      responses:
        '201':
          description: entry created
        '401':
          description: invalid token
        '403':
          description: inactive dialogue
        '404':
          description: topic or dialogue not found
        '500':
          description: internal server error
      requestBody:
        content:
          application/json:
            schema:
              type: object
              required:
                - type
                - data
              properties:
                type:
                  type: string
                data:
                  type: string
                  
  /conversation/dialogues/{dialogueId}/topics/{topicId}/assets:
    get:
      tags:
        - conversation
      description: Get all assets associated with the specified topic. Authorization granted to account holder app token or dialogue member contact token who has access to the topic.
      operationId: get-topic-assets
      security:
        - bearerAuth: []
      parameters:
        - name: dialogueId
          in: path
          description: specified dialogue id
          required: true
          schema:
            type: string
        - name: topicId
          in: path
          description: specified topic id 
          required: true
          schema:
            type: string
      responses:
        '201':
          description: success
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Asset'
        '401':
          description: permission denied
        '404':
          description: topic or dialogue not found
        '500':
          description: internal server error
    post:
      tags:
        - conversation
      description: Add an asset to a topic. The asset will be processed and transcoded according to the specified transformation. Authorization granted to account holder app token or dialogue member contact token who is also the creator of the topic.
      operationId: add-topic-asset
      security:
        - bearerAuth: []
      parameters:
        - name: dialogueId
          in: path
          description: specified dialogue id
          required: true
          schema:
            type: string
        - name: topicId
          in: path
          description: specified topic id 
          required: true
          schema:
            type: string
        - name: transforms
          in: query
          description: transforms to apply
          required: false
          schema:
            type: array
            items:
              type: string
      responses:
        '201':
          description: success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Asset'
        '401':
          description: permission denied
        '403':
          description: inactive dialogue
        '404':
          description: topic or dialogue not found
        '500':
          description: internal server error
      requestBody:
        content:
          multipart/form-data:
            schema:
              type: object
              properties:
                fileName:
                  type: string
                  format: binary
          
  /conversation/dialogues/{dialogueId}/topics/{topicId}/assets/{assetId}:
    get:
      tags:
        - conversation
      description: Retrieve an asset associated with a topic. All transformed assets can be retrieved by anyone with access to the topic, but the original asset can only be retrieved by the author of the topic. Authorization granted to account holder app token or dialogue member contact token who is also the creator of the topic.
      operationId: get-topic-asset
      security:
        - bearerAuth: []
      parameters:
        - name: dialogueId
          in: path
          description: specified dialogue id
          required: true
          schema:
            type: string
        - name: topicId
          in: path
          description: specified topic id 
          required: true
          schema:
            type: string
        - name: assetId
          in: path
          description: specified asset id 
          required: true
          schema:
            type: string
      responses:
        '200':
          description: success
          content:
            application/octet-stream: #asset specific
              schema:
                type: string
                format: binary
        '401':
          description: permission denied
        '404':
          description: asset, topic or dialogue not found
        '500':
          description: internal server error
    delete:
      tags:
        - conversation
      description: Remove and delete an asset associated with a topic. Authorization granted to account holder app token or dialogue member contact token who is also the creator of the topic.
      operationId: remove-topic-asset
      security:
        - bearerAuth: []
      parameters:
        - name: dialogueId
          in: path
          description: specified dialogue id
          required: true
          schema:
            type: string
        - name: topicId
          in: path
          description: specified topic id 
          required: true
          schema:
            type: string
        - name: assetId
          in: path
          description: specified asset id 
          required: true
          schema:
            type: string
      responses:
        '200':
          description: success
        '401':
          description: permission denied
        '403':
          description: inactive dialogue
        '404':
          description: asset, topic or dialogue not found
        '500':
          description: internal server error
          
  /conversation/dialogues/{dialogueId}/topics/{topicId}/confirmed:
    put:
      tags:
        - conversation
      description: After the assets have been uploaded and the subject has been set, the topic should be set to confirmed (true) to make the topic available to others. Authorization granted to account holder app token or dialogue member contact token who is also the creator of the topic.
      security:
        - bearerAuth: []
      parameters:
        - name: dialogueId
          in: path
          description: specified dialogue id
          required: true
          schema:
            type: string
        - name: topicId
          in: path
          description: specified topic id 
          required: true
          schema:
            type: string
      responses:
        '200':
          description: success
        '401':
          description: permission denied
        '403':
          description: inactive dialogue
        '404':
          description: topic or dialogue not found
        '500':
          description: internal server error
      requestBody:
        content:
          application/json:
            schema:
              type: boolean
              
  /conversation/dialogues/{dialogueId}/topics/{topicId}/tagBlocks/view:
    get:
      tags:
        - conversation
      description: Get a view of all of all tagBlocks. Authorization granted to account holder app token or dialogue member contact token who has access to the topic. 
      operationId: get-topic-tag-block-view
      security:
        - bearerAuth: []
      parameters:
        - name: dialogueId
          in: path
          description: specified dialogue id
          required: true
          schema:
            type: string
        - name: topicId
          in: path
          description: specified topic id 
          required: true
          schema:
            type: string
        - name: types
          in: query
          description: limit results to articles of types
          required: false
          schema:
            type: array
            items:
              type: string
      responses:
        '200':
          description: successful operation
          content:
            application/json:
              schema:
                type: array
                items:
                  type: object
                  properties:
                    id:
                      type: string
                    revision:
                      type: integer
                      format: int64
        '401':
          description: permission denied
        '404':
          description: topic or dialogue not found
        '500':
          description: internal server error
          
  /conversation/dialogues/{dialogueId}/topics/{topicId}/tagBlocks/{blockId}/view:
    get:
      tags:
        - conversation
      description: Get a view of all of the tags within a block. Authorization granted to account holder app token or dialogue member contact token who has access to the topic. 
      operationId: get-topic-tag-view
      security:
        - bearerAuth: []
      parameters:
        - name: dialogueId
          in: path
          description: specified dialogue id
          required: true
          schema:
            type: string
        - name: topicId
          in: path
          description: specified topic id 
          required: true
          schema:
            type: string
        - name: blockId
          in: path
          description: specified block id 
          required: true
          schema:
            type: string
        - name: types
          in: query
          description: limit results to tags of types
          required: false
          schema:
            type: array
            items:
              type: string
      responses:
        '200':
          description: successful operation
          content:
            application/json:
              schema:
                type: array
                items:
                  type: object
                  properties:
                    id:
                      type: string
                    revision:
                      type: integer
                      format: int64
        '401':
          description: permission denied
        '404':
          description: block, topic or dialogue not found
        '500':
          description: internal server error
          
  /conversation/dialogues/{dialogueId}/topics/{topicId}/tagBlocks/{blockId}:
    get:
      tags:
        - conversation
      description: Get all of the tags within a tag block. Authorization granted to account holder app token or dialogue member contact token who has access to the topic. 
      operationId: get-topic-tags
      security:
        - bearerAuth: []
      parameters:
        - name: dialogueId
          in: path
          description: specified dialogue id
          required: true
          schema:
            type: string
        - name: topicId
          in: path
          description: specified topic id 
          required: true
          schema:
            type: string
        - name: blockId
          in: path
          description: specified block id 
          required: true
          schema:
            type: string
        - name: types
          in: query
          description: limit results to tags of types
          required: false
          schema:
            type: array
            items:
              type: string
      responses:
        '200':
          description: successful operation
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Tag'
        '401':
          description: permission denied
        '404':
          description: block, topic, or dialogue not found
        '500':
          description: internal server error
          
  /conversation/dialogues/{dialogueId}/topics/{topicId}/tags:
    post:
      tags:
        - conversation
      description: Add a tag to specified topic. Authorization granted to account holder app token or dialogue member contact token who has access to the topic. The body of the post contains the subject of the tag, which can have no associated assets.
      operationId: add-topic-tag
      security:
        - bearerAuth: []
      parameters:
        - name: dialogueId
          in: path
          description: specified dialogue id
          required: true
          schema:
            type: string
        - name: topicId
          in: path
          description: specified topic id 
          required: true
          schema:
            type: string
      responses:
        '201':
          description: entry created
          content:
            application/json:
              schema:
                type: object
                properties:
                  blockId:
                    type: string
                  blockRevision:
                    type: integer
                    format: int64
                  tag:
                    $ref: '#/components/schemas/Tag'
        '401':
          description: permission denied
        '403':
          description: inactive dialogue
        '404':
          description: topic or dialogue not found
        '500':
          description: internal server error
      requestBody:
        content:
          application/json:
            schema:
              type: object
              required:
                - type
                - data
              properties:
                type:
                  type: string
                data:
                  type: string
              
  /conversation/dialogues/{dialogueId}/topics/{topicId}/tags/{tagId}:
    get:
      tags:
        - conversation
      description: Retrieve specified tag on the topic. Authorization granted to account holder app token or dialogue member contact token who has access to the topic.
      operationId: get-topic-tag
      security:
        - bearerAuth: []
      parameters:
        - name: dialogueId
          in: path
          description: specified dialogue id
          required: true
          schema:
            type: string
        - name: topicId
          in: path
          description: specified topic id 
          required: true
          schema:
            type: string
        - name: tagId
          in: path
          description: specified tag id 
          required: true
          schema:
            type: string
      responses:
        '201':
          description: success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Tag'
        '401':
          description: permission denied
        '404':
          description: tag, topic, or dialogue not found
        '500':
          description: internal server error
    delete:
      tags:
        - conversation
      description: Remove specified tag from the topic. Authorization granted to account holder app token or dialogue member contact token who has access to the topic.
      operationId: remove-topic-tag
      security:
        - bearerAuth: []
      parameters:
        - name: dialogueId
          in: path
          description: specified dialogue id
          required: true
          schema:
            type: string
        - name: topicId
          in: path
          description: specified topic id 
          required: true
          schema:
            type: string
        - name: tagId
          in: path
          description: specified tag id 
          required: true
          schema:
            type: string
      responses:
        '200':
          description: success
        '401':
          description: permission denied
        '403':
          description: inactive dialogue
        '404':
          description: tag, topic, or dialogue not found
        '500':
          description: internal server error
              
  /conversation/dialogues/{dialogueId}/topics/{topicId}/tags/{tagId}/subject/{field}:
    get:
      tags:
        - conversation
      description: Base64 decode and retrieve specified field of tag subject on the topic. Authorization granted to account holder app token or dialogue member contact token who has access to the topic.
      operationId: get-topic-tag-subject-field
      security:
        - bearerAuth: []
      parameters:
        - name: dialogueId
          in: path
          description: specified dialogue id
          required: true
          schema:
            type: string
        - name: topicId
          in: path
          description: specified topic id 
          required: true
          schema:
            type: string
        - name: tagId
          in: path
          description: specified tag id 
          required: true
          schema:
            type: string
        - name: field
          in: path
          description: field to base64 decode and download 
          required: true
          schema:
            type: string
      responses:
        '201':
          description: success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Tag'
        '401':
          description: permission denied
        '404':
          description: field, tag, topic, or dialogue not found
        '405':
          description: invalid field
        '500':
          description: internal server error
          
externalDocs:
  description: App overview
  url: ''

components:
  schemas:
  
    Announce:
      type: object
      required:
        - appToken
      properties:
        appToken:
          type: string
          
    Status:    
      type: object
      required:
        - profile
        - content
        - view # revision increment on sharing changes
        - share
        - label
        - card
        - dialogue
        - insight
      properties:
        profile:
          type: integer
          format: int64
        content:
          type: integer
          format: int64
        label:
          type: integer
          format: int64
        share:
          type: integer
          format: int64
        card:
          type: integer
          format: int64
        dialogue:
          type: integer
          format: int64
        insight: 
          type: integer
          format: int64
      
    Profile:
      type: object
      required:
        - did
        - revision
        - node
      properties:
        did:
          type: string
        handle:
          type: string
        name:
          type: string
        description:
          type: string
        location:
          type: string
        image:
          type: string
          format: base64 encoded data
        revision:
          type: integer
          format: int64
        version:
          type: string
        node:
          type: string
          
    ProfileData:
      type: object
      properties:
        handle:
          type: string
        name:
          type: string
        description:
          type: string
        location:
          type: string
        image:
          type: string
          
    Account:
      type: object
      required:
        - accountId
        - profile
      properties:
        accountId:
          type: string
        profile:
          $ref: '#/components/schemas/Profile'
        
    App:
      type: object
      required:
        - appId
        - appData
        - attached
      properties:
        appId:
          type: string
        appData:
          $ref: '#/components/schemas/AppData'
        attached:
          type: integer
          format: int32
          
    AppData:
      type: object
      properties:
        name:
          type: string
        description:
          type: string
        url:
          type: string
        image:
          type: string
          format: base64 encoded image
          
    CardView:
      type: object
      required:
        - cardId
        - profileRevision
        - contentRevision
        - cardRevision
      properties:
        cardId:
          type: string
        cardRevision:
          type: integer
          format: int64
        profileRevision:
          type: integer
          format: int64
        contentRevision:
          type: integer
          format: int64
        converstaionRevision:
          type: integer
          format: int64
          
    CardProfile:
      type: object
      required:
        - node
      properties:
        handle:
          type: string
        name:
          type: string
        description:
          type: string
        location:
          type: string
        revision:
          type: integer
          format: int64
        imageSet:
          type: boolean
        node:
          type: string
          
    CardData:
      type: object
      required:
        - status
      properties:
        revision:
          type: integer
          format: int64
        status:
          type: string
          enum: [ pending, confirmed, requested, connecting, connected ]
        notes:
          type: string
        token:
          type: string
        groups:
          type: array
          items:
            type: string
          
    Card:
      type: object
      required:
        - cardId
        - cardProfile
        - cardData
        - contentRevision
        - conversationRevision
      properties:
        cardId:
          type: string
        cardProfile:
          $ref: '#/components/schemas/CardProfile'
        cardData:
          $ref: '#/components/schemas/CardData'
        contentRevision:
          type: integer
          format: int64
        converstaionRevision:
          type: integer
          format: int64
            
    Subject:
      type: object
      required:
        - subjectId
        - revision
        - type
        - data
        - created
        - modified
      properties:
        subjectId:
          type: string
        revision:
          type: integer
          format: int64
        type:
          type: string
        data:
          type: string
        created:
          type: integer
          format: int32
          
    Asset:
      type: object
      required:
        - assetId
      properties:
        assetId:
          type: string
        transform:
          type: string
        status:
          type: string
          enum: [ pending, processing, ready, error ]
          
    Tag:
      type: object
      required:
        - cardId
        - subject
      properties:
        cardId:
          type: string
        subject:
          $ref: '#/components/schemas/Subject'
          
    Insight:
      type: object
      required:
        - insightId
        - revision
        - cardId
        - status
      properties:
        insightId:
          type: string
        revision:
          type: integer
          format: int64
        cardId:
          type: string
        status:
          type: string
          enum: [ active, inactive, dismissed ]
          
    Dialogue:
      type: object
      required:
        - dialogueId
        - revision
        - active
        - subject
        - insights
      properties:
        dialogueId:
          type: string
        revision:
          type: integer
          format: int64
        active:
          type: boolean
        subject:
          $ref: '#/components/schemas/Subject'
        insights:
          type: array
          items:
            type: object
            properties:
              cardId:
                type: string
              status:
                type: string
                enum: [ active, offsync, inactive, dismissed ]
    
    Tunnel:
      type: object
      required:
        - cardId
        - type
      properties:
        cardId:
          type: string
        type:
          type: string
        data:
          type: string
          
    Topic:
      type: object
      required:
        - topicId
        - revision
        - status
        - subject
        - tagCount
        - tagUpdated
        - tagRevision
      properties:
        articleId:
          type: string
        revision:
          type: integer
          format: int64
        status:
          type: string
          enum: [ unconfirmed, confirmed, complete, error ]
        subject:
          $ref: '#/components/schemas/Subject'
        tagCount:
          type: integer
          format: int32
        tagUpdate:
          type: integer
          format: int32
        tagRevision:
          type: integer
          format: int64
          
    Article:
      type: object
      required:
        - articleId
        - revision
        - status
        - subject
        - labels
        - tagCount
        - tagUpdated
        - tagRevision
      properties:
        articleId:
          type: string
        revision:
          type: integer
          format: int64
        status:
          type: string
          enum: [ unconfirmed, confirmed, complete, error ]
        subject:
          $ref: '#/components/schemas/Subject'
        labels:
          type: array
          items:
            type: string
        groups:  # present only in account holder responses
          type: array
          items:
            type: string
        tagCount:
          type: integer
          format: int32
        tagUpdate:
          type: integer
          format: int32
        tagRevision:
          type: integer
          format: int64
          
    Group:
      type: object
      required:
        - subject
      properties:
        subject:
          $ref: '#/components/schemas/Subject'
          
    Label:
      type: object
      required:
        - subject
      properties:
        subject:
          $ref: '#/components/schemas/Subject'
        groups:  # present only in account holder responses
          type: array
          items:
            type: string
      
    Authenticate:
      type: object
      required: 
        - did
        - token
        - timestamp
      properties:
        token:
          type: string
        timestamp:
          type: integer
          format: int32
          
    Connect:
      type: object
      required:
        - requestorId
        - requestedId
        - timestamp
        - profile
        - token
        - contentRevision
      properties:
        requestorcardId:
          type: string
        requestedcardId:
          type: string
        timestamp: 
          type: integer
          format: int32
        profile:
          $ref: '#/components/schemas/Profile'
        token:
          type: string
        contentRevision:
          type: integer
          format: int64
          
    Disconnect:
      type: object
      required:
        - requestorId
        - requestedId
        - timestamp
      properties:
        requestorId:
          type: string
        requestedId:
          type: string
        timestamp: 
          type: integer
          format: int32
          
    DataMessage:
      type: object
      required:
        - message
        - messageType
        - keyType
        - publicKey
        - signature
      properties:
        messageType:
          type: string
          enum: [Connect, Disconnect, Profile, Authenticate]
        message:
          type: string
          format: base64 encoded object
        keyType:
          type: string
          enum: [RSA4096, RSA2048]
        publicKey:
          type: string
          format: base64 encoding of account key
        signature:
          type: string
          format: base64 encoding of message signature
          
          
  securitySchemes:
  
    basicAuth:
      type: http
      scheme: basic
      
    bearerAuth: 
      type: http
      scheme: bearer