openapi: 3.0.0
info:
  title: Messages API
  version: '1.0'
  description: >-
    The Tidepool API is an HTTP REST API used by Tidepool clients use to
    communicate with the Tidepool Platform.


    For more information, see the [Getting Started](../docs/quick-start.md)
    section.
  contact:
    name: API Support
    url: https://support.tidepool.org/
    email: support@tidepool.org
  license:
    name: BSD-2-Clause
    url: https://github.com/tidepool-org/message-api/blob/master/LICENSE
  x-tidepool-service: https://github.com/tidepool-org/message-api/
servers:
  - url: https://external.integration.tidepool.org
    description: integration
  - url: https://api.tidepool.org
    description: production
  - url: https://dev1.dev.tidepool.org
    description: dev1
  - url: https://qa1.development.tidepool.org
    description: qa1
  - url: https://qa2.development.tidepool.org
    description: qa2
tags:
  - name: Internal
    description: APIs intended for internal use by Tidepool.
  - name: Messages
    description: >-
      List, create and manage messages (also known as notes) in the user's
      account.


      All APIs require a valid session token provided via the
      `X-Tidepool-Session-Token` header.

      There is currently no unauthenticated access to messages.


      The common API input parameter `userId` is a Tidepool User ID that
      identifies the user whose account contains the messages.

      That user may have shared their account with (=given permission to) other
      users who can view and manage messages in their account.

      Therefore, in each API request the user ID identified with the session
      token must either a) match the `userId` parameter,

      or b) the corresponding user must have been granted the `note` permission
      to manage messages in the user account identified by `userId`.


      Similarly, in the API responses the `groupid` field is a Tidepool User ID
      that identifies the user whose account contains the messages,
      corresponding to the `userId` parameter in requests.

      The `userid` field identifies the user who actually created the message,
      corresponding to the user ID encoded within the session token.

      The message was created by the owner of the account if these two fields
      match.


      Each message has a unique message ID, and the messages can be threaded.

      A user can create either a new message, or create a reply to another
      message.

      Each message contains a `parentmessage` field that contains the message ID
      of previous message in the thread.

      Messages that have no `parentmessage` field value (i.e. it is `null`) are
      top-level messages, that is, the beginning of a message thread.


      See the Authorization API for details on how permissions are managed.
paths:
  /message/all/{userId}:
    parameters:
      - $ref: '#/components/parameters/tidepooluserid'
      - $ref: '#/components/parameters/starttime.v1'
      - $ref: '#/components/parameters/endtime.v1'
    get:
      operationId: ListAllMessages
      summary: List All Messages
      description: >-
        List all messages in the user account identified by `userId`, optionally
        within the time range bounded by `starttime` and/or `endtime`.
      responses:
        '200':
          $ref: '#/components/responses/MessageList'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
      security:
        - sessionToken: []
      tags:
        - Messages
  /message/notes/{userId}:
    parameters:
      - $ref: '#/components/parameters/tidepooluserid'
      - $ref: '#/components/parameters/starttime.v1'
      - $ref: '#/components/parameters/endtime.v1'
    get:
      operationId: ListTopLevelMessages
      summary: List Top-Level Messages
      description: >-
        List only the top-level message threads in the user account identified
        by `userId`, optionally within the time range bounded by `starttime`
        and/or `endtime`. Top-level messages are the starting point of each
        message thread (i.e. `parentmessage` == `null`), that is, messages that
        are not responses to other messages.
      responses:
        '200':
          $ref: '#/components/responses/MessageList'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
      security:
        - sessionToken: []
      tags:
        - Messages
  /message/send/{userId}:
    parameters:
      - $ref: '#/components/parameters/tidepooluserid'
    post:
      operationId: CreateMessage
      summary: Create New Top-Level Message
      description: >-
        Creates a new top-level message (thread) in the account identified by
        `userId`. Top-level messages are the starting point of a message thread
        (i.e. `parentmessage` == `null`), that is, not a response to any other
        message.
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/newmessage.v1'
      responses:
        '201':
          $ref: '#/components/responses/MessageCreated'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
      security:
        - sessionToken: []
      tags:
        - Messages
  /message/reply/{messageId}:
    parameters:
      - $ref: '#/components/parameters/messageid.v1'
    post:
      operationId: ReplyToMessage
      summary: Reply to Message
      description: Adds a reply to an existing message identified by `messageId`.
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/newmessage.v1'
      responses:
        '201':
          $ref: '#/components/responses/MessageCreated'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
      security:
        - sessionToken: []
      tags:
        - Messages
  /message/read/{messageId}:
    parameters:
      - $ref: '#/components/parameters/messageid.v1'
    get:
      operationId: FindMessageById
      summary: Get Message by ID
      description: Returns message identified by `messageId`
      responses:
        '200':
          $ref: '#/components/responses/Message'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
      security:
        - sessionToken: []
      tags:
        - Messages
  /message/thread/{messageId}:
    parameters:
      - $ref: '#/components/parameters/messageid.v1'
    get:
      operationId: GetMessageThread
      summary: Get Message Thread by ID
      description: Returns message thread identified by `messageId`
      responses:
        '200':
          $ref: '#/components/responses/MessageList'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
      security:
        - sessionToken: []
      tags:
        - Messages
  /message/edit/{messageId}:
    parameters:
      - $ref: '#/components/parameters/messageid.v1'
    put:
      operationId: UpdateMessage
      summary: Update Message
      description: >-
        Updates the message identified by `messageId`. Either the `timestamp` or
        the `messagetext` field or both must be supplied in the request body. No
        other fields of the message may be updated. The `modifiedtime` field of
        the message will indicate when the message was last modified.
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/editmessage.v1'
      responses:
        '200':
          description: Success
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
      security:
        - sessionToken: []
      tags:
        - Messages
  /message/remove/{messageId}:
    parameters:
      - $ref: '#/components/parameters/messageid.v1'
    delete:
      operationId: DeleteMessage
      summary: Delete Message
      description: Deletes the message identified by `messageId`.
      responses:
        '202':
          description: Success
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
      security:
        - sessionToken: []
      tags:
        - Messages
components:
  securitySchemes:
    sessionToken:
      description: Tidepool Session Token
      type: apiKey
      name: X-Tidepool-Session-Token
      in: header
  responses:
    MessageCreated:
      description: Message created
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/messageresponse.v1'
    Message:
      description: Message.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/message.v1'
    MessageList:
      description: Message list.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/messagelist.v1'
    NotFound:
      description: Not Found. The requested account or message was not found.
      content:
        application/json:
          schema:
            type: object
            properties:
              messages:
                type: array
                items:
                  type: string
    Unauthorized:
      description: Unauthorized. The session token is either not present, or it is invalid.
      content:
        application/json:
          schema:
            type: object
            properties:
              messages:
                type: array
                items:
                  type: string
    Forbidden:
      description: >-
        Forbidden. The session token is valid, but not authorized to access this
        account.
      content:
        application/json:
          schema:
            type: object
            properties:
              messages:
                type: array
                items:
                  type: string
  schemas:
    tidepooluserid:
      type: string
      title: Tidepool User ID
      pattern: >-
        ^([0-9a-f]{10}|[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})$
      description: >-
        String representation of a Tidepool User ID. Old style IDs are 10-digit
        strings consisting of only hexadeximcal digits. New style IDs are
        36-digit [UUID
        v4](https://en.wikipedia.org/wiki/Universally_unique_identifier#Version_4_(random))
      readOnly: true
      x-go-type: string
    datetime.v1:
      title: Date/Time
      description: >-
        [RFC 3339](https://www.ietf.org/rfc/rfc3339.txt) / [ISO
        8601](https://www.iso.org/iso-8601-date-and-time-format.html) timestamp
        _with_ timezone information
      type: string
      format: date-time
      example: '2017-02-06T02:37:46Z'
      x-go-type: string
    messageid.v1:
      title: Message ID
      type: string
      pattern: ^[0-9a-f]{24}$
      minLength: 24
      maxLength: 24
      example: 60e64ddf98b2350011b0f37f
    guid.v1:
      title: GUID
      description: UUID v4 as defined in [RFC 4122](https://www.ietf.org/rfc/rfc4122.txt).
      type: string
      format: uuid
      pattern: ^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$
      example: b9468a76-4afc-4c33-8d1d-1f08324d9160
      x-go-type: string
    nullablemessageid.v1:
      title: Optional Message ID
      type: string
      pattern: ^[0-9a-f]{24}$
      minLength: 24
      maxLength: 24
      example: 60e64ddf98b2350011b0f37f
      nullable: true
    message.v1:
      title: Message
      description: >-
        The `id` field is a unique message ID that identifies this message. The
        `groupid` is the Tidepool User ID of the user who owns the account that
        contains this message. The `userid` is the Tidepool User ID of the user
        who created this message. They may differ. Messages may be chained
        togeher to form a message thread. The `parentmessage` is either `null`
        to indicate that this is a top-level message (=start of a message
        thread), or it is the message ID of the parent of this message.
      type: object
      properties:
        message:
          type: object
          properties:
            id:
              $ref: '#/components/schemas/messageid.v1'
            guid:
              $ref: '#/components/schemas/guid.v1'
            parentmessage:
              $ref: '#/components/schemas/nullablemessageid.v1'
            userid:
              $ref: '#/components/schemas/tidepooluserid'
            groupid:
              $ref: '#/components/schemas/tidepooluserid'
            timestamp:
              $ref: '#/components/schemas/datetime.v1'
            createdtime:
              $ref: '#/components/schemas/datetime.v1'
            modifiedtime:
              $ref: '#/components/schemas/datetime.v1'
            messagetext:
              type: string
              example: I ate a taco with 10g of carbs
            user:
              type: object
              properties:
                fullName:
                  type: string
                  example: James Jellyfish
              required:
                - fullName
          required:
            - id
            - guid
            - parentmessage
            - userid
            - groupid
            - timestamp
            - createdtime
            - messagetext
    messagelist.v1:
      title: Message List
      description: >-
        This list may be empty, for example if no matching messages are being
        returned. Messages, if present, are sorted in descending order by the
        `timestamp` field.
      type: object
      properties:
        messages:
          type: array
          items:
            $ref: '#/components/schemas/message.v1'
      required:
        - messages
    newmessage.v1:
      title: New Message
      type: object
      properties:
        message:
          type: object
          properties:
            messagetext:
              type: string
            timestamp:
              $ref: '#/components/schemas/datetime.v1'
            guid:
              $ref: '#/components/schemas/guid.v1'
          required:
            - messagetext
            - timestamp
            - guid
    messageresponse.v1:
      title: Message Response
      description: >-
        The `id` identifies the new message and can be used in subsequent
        requests to find this message.
      type: object
      properties:
        id:
          $ref: '#/components/schemas/messageid.v1'
      required:
        - id
    editmessage.v1:
      title: Edit Message
      type: object
      properties:
        message:
          anyOf:
            - type: object
              properties:
                messagetext:
                  type: string
                timestamp:
                  $ref: '#/components/schemas/datetime.v1'
              required:
                - messagetext
            - type: object
              properties:
                messagetext:
                  type: string
                timestamp:
                  $ref: '#/components/schemas/datetime.v1'
              required:
                - timestamp
  parameters:
    tidepooluserid:
      description: Tidepool User ID
      name: userId
      in: path
      required: true
      schema:
        $ref: '#/components/schemas/tidepooluserid'
    starttime.v1:
      description: Start Time. Start date/time of the range for messages
      name: starttime
      in: query
      required: false
      schema:
        $ref: '#/components/schemas/datetime.v1'
    endtime.v1:
      description: End Time. End date/time of the range for messages
      name: endtime
      in: query
      required: false
      schema:
        $ref: '#/components/schemas/datetime.v1'
    messageid.v1:
      description: Message ID
      name: messageId
      in: path
      required: true
      schema:
        $ref: '#/components/schemas/messageid.v1'
