openapi: 3.0.4

info:
  title: Tmpt.me Agent API (Beta)
  description: |
    ## A REST API for interacting with an Expert's Knowledge Agent in a conversation.

    The API is intended to be as easy to use as other LLM APIs, but is a bit different because it allows you
    as the developer to create multiple stateful conversations on behalf of your end users,
    and interact with the Expert's Agent in those conversations.
    
    **Please note that this API is in beta and may change as we receive user feedback.**
    
    ### Authentication
    Authentication requires an API Key, which Experts can create in the [Tmpt.me application](https://www.tmpt.app).
    Once you have an Expert's API key, you can create a client token and start a conversation with the Expert's Agent.
    The API key must be passed as a Bearer token in the Authorization header. Specifically, the header should be:
    ```
    Authorization: Bearer (your API key)
    ```
    
    ### Using the API
    The basic steps are as follows:
    1. Create a client token using the **/client_token** endpoint. Pass in any string for **external_user_id** that you 
       want to use to identify the client. The client token is used to distinguish conversations that 
       may be started by different users on your app.
    2. Use the client token to create a new thread by POSTing the **/threads** endpoint. The thread is the 
       conversation with the Expert's Agent.
    3. Use the thread ID to POST messages to the Expert's Agent using the **/threads/{threadId}/messages** endpoint.
    4. Use the thread ID to GET messages from the Expert's Agent using the **/threads/{threadId}/messages** endpoint.
       The returned messages array will include the full ordered conversation Agent's greeting, your inputs, and the Agent's responses.
  
    You can call GET on the **/threads** endpoint to see all conversations associated with a client token.
  
    ### Waiting on the Agent reply
    For better client interactivity, once you POST a new message and receive back a message with an ID,
    you can immediately call GET **/threads/{threadId}/reply/{messageId}** with an optional **timeout** 
    to wait for a response. This is useful for waiting for the Expert's Agent to respond to a question.
    Responses generally take from 5 to 15 seconds, but can take longer if the Expert's Agent is complex.
    Omitting the timeout or calling with a timeout of 0 will return immediately.
    
    ### Support
    For questions, comments, or concerns, please use the email address below, or submit a ticket on 
    our [support page](https://help.tmpt.me).

  contact:
    name: Tmpt.me
    url: https://tmpt.me
    email: help@tmpt.me
  version: 1.0.0

servers:
  - url: https://api.tmpt.app/v1
    description: Production server

security:
  - bearerAuth: [] # use the same name as above

paths:
  /client_token:
    post:
      summary: Creates a new token for a client
      requestBody:
          required: true
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ClientTokenRequest'
      responses:
        200:
          description: The created token
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ClientToken'
        default:
          description: Generic error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'

  /threads:
    get:
      summary: Gets the list of all threads associated with the client token
      parameters:
        - in: query
          name: client_token_id
          description: Client token ID obtained from /client_token
          required: true
          schema:
            type: string
      responses:
        200:
          description: List of all threads
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ListThread'
        default:
          description: Generic error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'

    post:
      summary: Creates a new thread
      requestBody:
          required: true
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ClientToken'
      responses:
        200:
          description: The created thread
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Thread'
        default:
          description: Generic error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'

  /threads/{threadId}:
    parameters:
      - in: path
        name: threadId
        description: The id of the thread
        required: true
        schema:
          type: string
    get:
      summary: Gets a thread object using its ID
      parameters:
        - in: query
          name: client_token_id
          description: Client token ID obtained from /client_token
          required: true
          schema:
            type: string
      responses:
        200:
          description: The requested thread
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Thread'
        404:
          description: The requested thread ID was not found
        default:
          description: Generic error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'

  /threads/{threadId}/messages:
    parameters:
      - in: path
        name: threadId
        description: The ID of the thread
        required: true
        schema:
          type: string
    get:
      summary: Get the list of all messages on the given thread
      parameters:
        - in: query
          name: client_token_id
          description: Client token ID obtained from /client_token
          required: true
          schema:
            type: string
      responses:
        200:
          description: The list of all messages in the thread
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ListMessage'
        404:
          description: The requested thread ID was not found
        default:
          description: Generic error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
    post:
      summary: Adds a new message to a thread
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PostMessage'
      responses:
        200:
          description: The newly created message
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Message'
        404:
          description: The requested thread ID was not found
        default:
          description: Generic error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'

  /threads/{threadId}/reply/{messageId}:
    get:
      summary: Returns the reply message for the given message ID. This is the next message in the thread, if it exists.
      parameters:
        - in: path
          name: threadId
          description: The ID of the thread
          required: true
          schema:
            type: string
        - in: path
          name: messageId
          description: The ID of the message to await a reply for
          required: true
          schema:
            type: string
        - in: query
          name: timeout
          description: An amount to wait for a reply, in seconds. Omit or use 0 to return immediately. Use -1 to wait indefinitely.
          required: false
          schema:
            type: integer
        - in: query
          name: client_token_id
          description: Client token ID obtained from /client_token
          required: true
          schema:
            type: string
      responses:
        200:
          description: The reply message for the given message ID
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Message'
        404:
          description: The requested thread was not found, or the reply message is not yet available
        default:
          description: Generic error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'

components:
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer

  schemas:
    ClientTokenRequest:
      description: Data used to uniquely identify a client
      required:
        - external_user_id
      type: object
      properties:
        external_user_id:
          description: Unique client details, for example a client user ID (or a hash of the user ID). The client token is used to by Tmpt.me to distinguish conversations that may be started by different users on your app.
          type: string
          readOnly: true
          example: user123
        is_reviewable:
          description: Whether threads created using this token are visible / reviewable by the Expert
          type: boolean
          example: true

    ClientToken:
      description: A conversation with an Expert's assistant
      required:
        - client_token_id
      type: object
      properties:
        client_token_id:
          description: a client token, must be returned in subsequent calls
          type: string
          readOnly: true
          example: QKEhOo29zWVRUMc4fAzM
    Thread:
        description: A conversation with an Expert's assistant
        required:
        - title
        - updated_at
        - created_at
        type: object
        properties:
          title:
            description: the title of the thread
            type: string
            example: Ask The Expert
          created_at:
            description: when the thread was created
            type: string
            format: date
          updated_at:
            description: when the thread was last updated
            type: string
            format: date
          id:
            description: id of the thread
            type: string
            readOnly: true
            example: tJZ0TZpbp2J9elBIa75s
    ListThread:
      type: array
      items:
        $ref: '#/components/schemas/Thread'
      description: A list of Thread objects
    Message:
        description: A message in a thread
        required:
        - speaker
        - text
        type: object
        properties:
          speaker:
            description: the speaker of the message, either "human" or "assistant"
            type: string
            example: human
          text:
            description: the message text
            type: string
            example: What's a carburetor?
          created_at:
            description: when the message was created
            type: string
            format: date
          id:
            description: id of the message
            type: string
            readOnly: true
            example: tJZ0TZpbp2J9elBIa75s
        additionalProperties: true
    ListMessage:
      type: array
      items:
        $ref: '#/components/schemas/Message'
      description: A list of Message objects
    PostMessage:
      description: Required post body for adding a message
      required:
        - client_token_id
        - text
      type: object
      properties:
        client_token_id:
          description: the client token obtained from /client_token
          type: string
          example: QKEhOo29zWVRUMc4fAzM
        text:
          description: the message text
          type: string
          example: What's a carburetor?
      additionalProperties: false
    Error:
        description: Object representing an error
        type: object
        properties:
          message:
            description: Short description of the error
            type: string
            example: Could not perform the task
          code:
            format: int32
            description: Error code that identify of the error
            type: integer
            example: "1000"
