NAV

Introduction

This Ultimate public API offers an advanced feature set for building automation bots using the latest AI technology.

To get started you need to have an account and at least one bot, head to Ultimate.ai to create an account or contact sales.

Once you have created your first chat bot go ahead and create a custom CRM integration, this integration allows you to define the webhook URLs to receive messages and events from the bot & you can define actions that can be used within bots. To read more on this checkout this help article

Having created a custom CRM integration now you can select it as the CRM of choice from your bot, you'll then receive an Access token that allows accessing the API to send messages to the bot will then reply through the predefined webhook url.

CHAT API Converse endpoint

This endpoint of the Chat API allows external customers to converse with a chat automation virtual agent. It requires an Authorization header, a botid header and a JSON request body which will be used to initiate a conversation with the virtual agent. The endpoint returns the response asynchronously to a webhook defined by the customer, which allows them to handle the response as per their requirement.

HTTP Request endpoint

Method: POST

Endpoint /converse/chat

Authorization header

This endpoint is protected by API Key.

When becoming a client, you will get an API Key that you will keep safe, and use it in all the requests as an Authorization header value

Request definition

Headers

[
  {"Authorization":"YOUR_API_KEY"},
  {"botId":"YOUR_BOT_ID"}
]

In the header of your request you need to send:

Your botId is a 24-digit identifier for your bot. You can find your botID by logging into the Ultimate Dashboard, selecting your bot and copying the botId from the URL.

Body

The request body needs to be sent JSON format as per defined in this table.

Field Type Required Description
platformConversationId string true An ID provided by customer to identify the conversation.
The customer can decide the format.
eventType enum [startSession, message, endSession] true Use startSession when the conversation is created. The welcomeMessage will be given as a response in case there is one for the given bot.
Use message if sending a visitor message.
Use endSession to end the session. Otherwise the Session will end automatically after 2 hours.
text string true
if eventType is message
The text message that the visitor typed into the chat.
The text is optional and not used if the eventType is startSession or endSession.
If a button was pressed (also in carousels), send the value of the button as text (unless it’s a link button).
cardIndex number? false The card index of the card that the visitor clicked in the chat.
The card index is optional and not used if the eventType is startSession or endSession.
Card index start in 0
metadata array[MetaData]? false Sending metadata gives you the ability to send metadata on the user or the session of the conversation. These params will be saved on the session and can be used by the bot to personalize the conversation flows.

Each object of type MetaData in the array needs to contain the following fields:
key string - name the session parameter can be referenced by to personalize a conversation
value string - value of the session parameter, note that we only support values of type string at this moment
sanitize bool - optional field, should be set as true for PII data
{
   "platformConversationId": "123-456-789",
   "eventType":"startSession|message|endSession|metadata",
   "text?":"Hello! I want to make a refund, please",
   "cardIndex?": 1,
   "metadata?":[
      {
         "key":"userId",
         "value":"54321"
      }
   ]
}

You can find an example of a request body on the right.








Response codes

Webhooks

When the bot emit an event (sendMessage, escalation, is team online, action), it notifies the customer via webhook. Two webhooks need to be defined, one for chat events (sendMessage, escalation and is team online) and one for actions.

Webhook messages format

Chat API will send to the webhooks the events generated. The events can be:

Field Type Required Description
botId string true The ID of the bot that is sending the event.
data Object true Object containing the payload of the event. Depending on the event type, it will contain different values

Message

In the sendMessage event we can receive 3 types of messages from the bot inside the data field. The webhook should return code 200 if the operation was successful

Message with text only
Field Type Description
eventType string
Set to sendMessage
Event of type sendMessage.
platformConversationId string The ID of the conversation
conversationId string ULTIMATE internal ID
type string
Set to text
Simple text message type.
replyId string The ID of the reply in Ultimate system that triggered this text message.
buttons Button[] The buttons array will be empty for a simple text message
text string The text of the message.
carouselCards CarouselCard[] The carousel cards array will be empty for a simple text message
predictedIntents PredictedIntent[] Predicted intents for visitor message. Each object of type PredictedIntent in the array needs to contain the following fields:
value string - the intent id
name string - name of the intent
confidence number - confidence in the intent
{
  "botId": "618a30beee4e8e87d2f94015",
  "data": {
    "eventType": "sendMessage",
    "platformConversationId": "session1",
    "conversationId": "conversation1",
    "type": "text",
    "replyId": "618a30be1c2ffe001ab1078f",
    "buttons": [],
    "text": "Hello, this is a bot text message",
    "carouselCards": [],
    "predictedIntents": [{"value": "1234", "name": "intent name", "confidence": 1}]
  }
}

You can find an example in JSON format of the text message with only text on the right.








Message with buttons
Field Type Description
eventType string
Set to sendMessage
Event of type sendMessage.
platformConversationId string The ID of the conversation
conversationId string ULTIMATE internal ID (can be ignored)
type string
Set to text
Simple text message type.
replyId string The ID of the reply in Ultimate system that triggered this text message.
buttons Button[] The buttons array will be empty for a simple text message. Each object of type Button in the array needs to contain the following fields:
type string - set to the value button
text string - text of the button
text string The text of the message with buttons. Not mandatory to exist.
carouselCards carouselCard[] The carousel cards array will be empty for a simple text message.
predictedIntets PredictedIntent[] Predicted intents for visitor message. Each object of type PredictedIntent in the array needs to contain the following fields:
value string - the intent id
name string - name of the intent
confidence number - confidence in the intent
{
  "botId": "610abae7527db9ce033024e1",
  "data": {
    "eventType": "sendMessage",
    "platformConversationId": "session1",
    "conversationId": "conversation1",
    "type": "text",
    "replyId": "610abc338851860016485d79",
    "buttons": [
      {
        "type": "button",
        "text": "YES" 
      },
      {
        "type": "button",
        "text": "NO"
      }
    ],
    "text": "its a bot text message with 2 buttons",
    "carouselCards": [],
    "predictedIntents": [{"value": "1234", "name": "intent name", "confidence": 1}]
  }
}

You can find an example in JSON format of the text message with text and two buttons on the right.


















Field Type Description
eventType string
Set to sendMessage
Event of type sendMessage.
platformConversationId string The ID of the conversation
conversationId string ULTIMATE internal ID (can be ignored)
type string
Set to carousel
Carousel message type.
replyId string The ID of the reply in Ultimate system that triggered this text message.
buttons Button[] The buttons array will be empty for a simple text message.
text string The text of the message with buttons. Not mandatory to exist.
carouselCards CarouselCard[] The carousel cards array will contain a list of cards. See table below with the fields of CarouselCards
predictedIntets PredictedIntent[] Predicted intents for visitor message. Each object of type PredictedIntent in the array needs to contain the following fields:
value string - the intent id
name string - name of the intent
confidence number - confidence in the intent


Each object of type CarouselCard in the array needs to contain the following fields:

Field Type Description
title string Title of the carousel.
description string Event of type sendMessage
imageUrl string Url of the card image.
buttons Button[] Each object of type Button in the array needs to contain the following fields:
type string - set to the value button
text string - text of the button
{
  "botId": "618a30beee4e8e87d2f94015",
  "data": {
    "eventType": "sendMessage",
    "platformConversationId": "session1",
    "conversationId": "conversation1",
    "type": "carousel",
    "replyId": "61e5439dce4387001311d6db",
    "buttons": [],
    "text": "",
    "carouselCards": [
      {
        "title": "card 1",
        "description": "card 1 description",
        "imageUrl": "URL",
        "buttons": [
          {
            "text": "button 1",
            "type": "button"
          },
          {
            "text": "button 2",
            "type": "button"
          }
        ]
      },
      {
        "title": "card 2",
        "description": "card 2 description",
        "imageUrl": "URL",
        "buttons": [
          {
            "text": "button 1",
            "type": "button"
          },
          {
            "text": "button 2",
            "type": "button"
          }
        ]
      }
    ],
    "predictedIntents": [{"value": "1234", "name": "intent name", "confidence": 1}]
  }
}

You can find an example in JSON format of the carousel message with two cards on the right.


































Escalate

In the escalate event we can receive one type of message from the bot inside the data field:

Field Type Description
eventType string
Set to escalate
Event of type escalate.
platformConversationId string The ID of the conversation
conversationId string ULTIMATE internal ID (can be ignored)
escalateTo? string The ID of the escalation team (OPTIONAL)
{
  "botId": "string",
  "data": {
    "eventType": "escalate",
    "platformConversationId": "string",
    "escalateTo": "string"
  }
}

You can find an example in JSON format of the escalation message on the right.






The webhook should return code 200 if the operation was successful

Is Team Online

In the isTeamOnline event we can receive one type of message from the bot inside the data field:

Field Type Description
eventType string
Set to isTeamOnline
Event of type isTeamOnline.
conversationId string ULTIMATE internal ID (can be ignored)
teamId? string The ID of the team to check (OPTIONAL)
{
  "botId": "string",
  "data": {
    "eventType": "isTeamOnline",
    "teamId": "string"
  }
}

You can find an example in JSON format of the is team online message on the right.





The webhook should return code 200 if the operation was successful and return a response body containing the boolean field

Action

In the Action event we receive one type of message from the bot inside:

Field Type Description
botId string The ID of the bot
conversationId string ULTIMATE internal ID (can be ignored)
platformConversationId string The ID of the conversation
name string The name of the action
data ActionData[] The parameters of the Action request. Each object of type ActionData in the array needs to contain the following fields:
key string - key of the parameter
value string - value of the parameter, and optionally the parameter
saveAs string - value for this parameter when saved in conversation
{
  "botId" : "string",
  "conversationId": "string",
  "platformConversationId": "string",
  "name": "string",
  "data": [
    {
      "key": "string",
      "value": [ "any" ],
      "saveAs?": "string"
    }
  ]
}

You can find an example in JSON format of an action message on the right.








The webhook will return 200 if the action was successful. Optionally, the webhook can return in the response an array of key/value pairs that will be stored in the conversation session. This array need to be defined:

Field Type Description
results ActionResult[] List of key/value pairs to be stored in Ultimate conversation session

Each actionResult object need to be defined:

Field Type Description
key string Name of the variable to create in the conversation session
value string or number or boolean Value of the variable to create in the conversation session
sanitize boolean Marks if the value should be sanitised
{
  "results": [
    {
      "key": "userId",
      "value": "12345",
      "sanitize?": false
    },
    {
      "key": "userEmail",
      "value": "email@email.email",
      "sanitize?": true
    }
  ]
}

You can find an example in JSON format of an action webhook response.







Usage

First of all you need to have the apiKey for the Authorization header and the bot ID for the botid header.

Start conversation

To start a new conversation (ie: when the chat widget is opened) create a new platformConversationId of type string. This ID needs to be unique to identify a single conversation, but the format of it is up to you. Also you need to send eventType:"startSession". All subsequent visitor messages sent in the conversation, should use the same platformConversationId as the one used to start the conversation.

Request body example to start a conversation

{
  "platformConversationId": "00000001",
  "eventType": "startSession"
}

You can find a payload example in JSON format of starting a new conversation on the right.



Message

The payload of the message will depend on if it is a text message, a button selection or a carousel's card selection.

Request body example for a text message

{
  "platformConversationId": "00000001",
  "eventType": "message",
  "text": "I want to make a refund"
}

You can find a payload example in JSON format for sending a text message on the right.




Request body example for clicking a button

{
  "botId": "BOT_ID",
  "data": {
    "type": "text",
    "replyId": "SOME_REPLY_ID",
    "buttons": [
      {
        "type": "button",
        "text": "YES"
      },
      {
        "type": "button",
        "text": "NO"
      },
      {
        "type": "button",
        "text": "Maybe"
      }
    ],
    "text": "This is a virtual agent message text",
    "carouselCards": [],
    "eventType": "sendMessage",
    "platformConversationId": "00000001"
  }
}

If the virtual agent previously sent a message with buttons to the webhook, like the one in the right:





















{
  "platformConversationId": "00000001",
  "eventType": "message",
  "text": "Maybe"
}

To send a button click to the endpoint, we need to pass the text field of the button in the text field of the request, like in the example on the right selecting the third button with the text Maybe.




{
  "botId": "610abae7527db9ce033024e1",
  "data": {
    "type": "carousel",
    "replyId": "6138b04e74b9d100164b6bf5",
    "buttons": [],
    "text": "",
    "carouselCards": [
      {
        "description": "description of first card",
        "imageUrl": "IMAGE_1_URL",
        "title": "title 1",
        "buttons": [
          {
            "type": "button",
            "text": "firstCardButton"
          }
        ]
      },
      {
        "description": "description of second card",
        "imageUrl": "IMAGE_2_URL",
        "title": "title 2",
        "buttons": [
          {
            "type": "button",
            "text": "secondCardButton"
          }
        ]
      }
    ],
    "eventType": "sendMessage",
    "platformConversationId": "00000001"
  }
}

If the virtual agent previously sent a message with a carousel with two cards, like this:





























{
  "platformConversationId": "00000001",
  "eventType": "message",
  "text": "secondCardButton",
  "cardIndex": 1
}

To send a carousel card click to the endpoint, we need to pass the text field of the button of the card in the text field of the request and the card index (starting index in 0) in the cardIndex field as a number, like in this example on the right selecting the second card




End conversation

To end an existing conversation (ie: when the chat widget is closed) you need to send a request with eventType:"endSession" and the platformConversationId of that conversation

Request body example to end a conversation

{
  "platformConversationId": "00000001",
  "eventType": "endSession"
}

Request example on the right to end a conversation




Add metadata

To add custom variables to the session to use them in your dialogues you need to send a request with eventType:"metadata", the platformConversationId of that conversation and the metadata array

Request body example to end a conversation

{
  "platformConversationId": "00000001",
  "eventType": "metadata",
  "metadata": [
    {
      "key": "user_id",
      "value": "1234"
    },
    {
      "key": "user_name",
      "value": "john"
    }
  ]
}

Request example on the right to add 2 variables to the session with the metadata event







API Client code snippets

Typescript

curl -X POST https://api.ultimate.ai/converse/chat -H 'Authorization: YOUR_AUTHORIZATION_TOKEN' -H 'botid: YOUR_BOT_ID' -H 'Content-Type: application/json' -d '{
    "platformConversationId": "YOUR_PLATFORM_CONVERSATION_ID",
    "eventType": "startSession",
    "text": "Hello"
}'

Curl command to start a conversation on the right





curl -X POST https://api.ultimate.ai/converse/chat -H 'Authorization: YOUR_AUTHORIZATION_TOKEN' -H 'botid: YOUR_BOT_ID' -H 'Content-Type: application/json' -d '{
"platformConversationId": "YOUR_PLATFORM_CONVERSATION_ID",
"eventType": "message",
"text": "Hello"
}'

Curl command to send a text message on the right





curl -X POST https://api.ultimate.ai/converse/chat -H 'Authorization: YOUR_AUTHORIZATION_TOKEN' -H 'botid: YOUR_BOT_ID' -H 'Content-Type: application/json' -d '{
    "platformConversationId": "YOUR_PLATFORM_CONVERSATION_ID",
    "eventType": "endSession",
    "text": "Hello"
}'

Curl command to end a conversation on the right





import axios from 'axios';

const headers = {
  Authorization: process.env.AUTHORIZATION_HEADER,
  botid: process.env.BOT_ID
};

const request = {
  platformConversationId: "my-conversation-id",
  eventType: "message",
  text: "Hello, I want to return my shoes",
  metadata: {
    key: "user_id",
    value: "1234"
  }
};

async function converseChat() {
  try {
    const response = await axios.post('https://api.ultimate.com/converse/chat', request, { headers });
    console.log(response.data);
  } catch (error) {
    console.error(error);
  }
}

converseChat();

Code snippet using typescript on the right





















Java

import java.io.IOException;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.HttpClientBuilder;
import org.json.JSONObject;

public class ChatApiExample {
    public static void main(String[] args) {
        final HttpClient httpClient = HttpClientBuilder.create().build();
        final HttpPost request = new HttpPost("https://api.ultimate.ai/converse/chat");

        // Set headers
        final String authorization = System.getenv("AUTHORIZATION");
        request.setHeader("Authorization", authorization);
        final String botId = System.getenv("BOTID");
        request.setHeader("botid", botId);

        // Create request body
        final JSONObject requestBody = new JSONObject();
        requestBody.put("platformConversationId", "123456");
        requestBody.put("eventType", "message");
        requestBody.put("text", "What is the refund policy for the article I bought yesterday?");

        final StringEntity entity = new StringEntity(requestBody.toString());
        request.setEntity(entity);
        try {
            final HttpResponse response = httpClient.execute(request);
            final int statusCode = response.getStatusLine().getStatusCode();
            if (statusCode >= 200 && statusCode < 300) {
                final HttpEntity responseEntity = response.getEntity();
                System.out.println(responseEntity.getContent());
            } else {
                System.err.println("Error: "+response.getStatusLine().getReasonPhrase());
            }
        } catch (IOException e) {
            System.err.println("Error: "+e.getMessage());
        }
    }
}

Code snippet using Java on the right

































Java + Spring

import lombok.Builder;
import lombok.Data;

@Data
@Builder
public class ChatRequest {
    private String platformConversationId;
    private String eventType;
    private String text;
    private MetaData metadata;
    private Integer cardIndex;

    @Data
    @Builder
    public static class MetaData {
        private String key;
        private String value;
    }
}

@Service
public class ChatService {

    private final String authorization;
    private final String botid;
    private final RestTemplate restTemplate;

    @Autowired
    public ChatService(
            @Value("${CHAT_API_AUTHORIZATION}") String authorization,
            @Value("${CHAT_API_BOTID}") String botid,
            RestTemplate restTemplate
    ) {
        this.authorization = authorization;
        this.botid = botid;
        this.restTemplate = restTemplate;
    }

};

    public ResponseEntity<Object> converseChat() {
        final HttpHeaders headers = new HttpHeaders();
        headers.set("Authorization", authorization);
        headers.set("botid", botid);

        final ChatRequest chatRequest = ChatRequest.builder()
            .platformConversationId("YOUR_PLATFORM_CONVERSATION_ID")
            .eventType("message")
            .text("Hello")
            .metadata(ChatRequest.MetaData.builder()
                .key("key")
                .value("value")
                .build())
            .cardIndex(1)
            .build();

        final HttpEntity<ChatRequest> request = new HttpEntity<>(chatRequest, headers);
        return restTemplate.postForEntity("https://api.ultimate.ai/converse/chat", request, Object.class);
    }
}

Code snippet using Java and Spring on the right
















































Java + Spring Webflux

import lombok.Builder;
import lombok.Data;

@Data
@Builder
public class ChatRequest {
    private String platformConversationId;
    private String eventType;
    private String text;
    private MetaData metadata;
    private Integer cardIndex;

    @Data
    @Builder
    public static class MetaData {
        private String key;
        private String value;
    }
}

@Service
public class ChatService {

    private final String authorization;
    private final String botid;
    private final WebClient webClient;

    public ChatService(
            @Value("${CHAT_API_AUTHORIZATION}") String authorization,
            @Value("${CHAT_API_BOTID}") String botid,
            WebClient webClient
    ) {
        this.authorization = authorization;
        this.botid = botid;
        this.webClient = webClient;
    }

    public Mono<ResponseEntity<Object>> converseChat() {
        final ChatRequest chatRequest = ChatRequest.builder()
            .platformConversationId("YOUR_PLATFORM_CONVERSATION_ID")
            .eventType("message")
            .text("Hello")
            .metadata(ChatRequest.MetaData.builder()
                .key("key")
                .value("value")
                .build())
            .cardIndex(1)
            .build();


        return webClient.post()
                .uri("https://api.ultimate.ai/converse/chat")
                .header("Authorization", authorization)
                .header("botid", botid)
                .body(Mono.just(chatRequest), ChatRequest.class)
                .exchange()
                .flatMap(response -> response.toEntity(Object.class));
    }
}

Code snippet using Java and Spring Webflux on the right


















Ticket API Converse endpoint

This endpoint of the Ticket API allows external customers to converse with a ticket automation virtual agent. It requires an Authorization header, a botid header and a JSON request body which will be used to initiate a conversation with the virtual agent. The endpoint returns the response asynchronously to a webhook defined by the customer, which allows them to handle the response as per their requirement.

HTTP Request endpoint

Method: POST

Endpoint /converse/ticket

Authorization header

This endpoint is protected by API Key.

When becoming a client, you will get an API Key that you will keep safe, and use it in all the requests as an Authorization header value

Request definition

Headers

[
  {"Authorization":"YOUR_API_KEY"},
  {"botId":"YOUR_BOT_ID"}
]

In the header of your request you need to send:

Your botId is a 24-digit identifier for your bot. You can find your botID by logging into the Ultimate Dashboard, selecting your bot and copying the botId from the URL.

Body

The request body needs to be sent JSON format as per defined in this table.

Field Type Required Description
platformConversationId string true An ID provided by customer to identify the conversation.
The customer can decide the format.
text string true The text message that the visitor sent.
metadata array[MetaData]? false Sending metadata gives you the ability to send metadata on the user or the session of the conversation. These params will be saved on the session and can be used by the bot to personalize the conversation flows.

Each object of type MetaData in the array needs to contain the following fields:
key string - name the session parameter can be referenced by to personalize a conversation
value string - value of the session parameter, note that we only support values of type string at this moment
sanitize bool - optional field, should be set as true for PII data
{
   "platformConversationId": "123-456-789",
   "text?":"Hello! I want to make a refund, please",
   "metadata?":[
      {
         "key":"userId",
         "value":"54321"
      }
   ]
}

You can find an example of a request body on the right.






Response codes

SendMessage Webhook

When the bot has a response, it notifies the customer via webhook. The customer needs to implement the webhook endpoint to process bot replies.

Webhook message format

Field Type Description
botId string The ID of the bot that is sending the event.
conversationId string ULTIMATE internal ID
platformConversationId string The ID of the conversation
text string The text of the message.
predictedIntents PredictedIntent[] Predicted intents for visitor message. Each object of type PredictedIntent in the array needs to contain the following fields:
value string - the intent id
name string - name of the intent
confidence number - confidence in the intent
attachments Path[] Ticket attachment files paths. Each object of type Path in the array needs to contain the following field:
path string - the path of the file
{
  "botId": "618a30beee4e8e87d2f94015",
  "conversationId": "conversation1",
  "platformConversationId": "session1",
  "text": "Hello, this is a bot text message",
  "predictedIntents": [
    {
      "value": "1234",
      "name": "intent name",
      "confidence": 1
    }
  ],
  "attachments": [
    {
      "path": "path/to/attachment"
    }
  ]
}

You can find an example in JSON format of the message with only text on the right.









API Client code snippets

Typescript

curl -X POST https://api.ultimate.ai/converse/ticket -H 'Authorization: YOUR_AUTHORIZATION_TOKEN' -H 'botid: YOUR_BOT_ID' -H 'Content-Type: application/json' -d '{
    "platformConversationId": "YOUR_PLATFORM_CONVERSATION_ID",\
    "text": "Hello"
}'

Curl command





import axios from 'axios';

const headers = {
  Authorization: process.env.AUTHORIZATION_HEADER,
  botid: process.env.BOT_ID
};

const request = {
  platformConversationId: "my-conversation-id",
  text: "Hello, I want to return my shoes",
  metadata: {
    key: "user_id",
    value: "1234"
  }
};

async function converseTicket() {
  try {
    const response = await axios.post('https://api.ultimate.com/converse/ticket', request, { headers });
    console.log(response.data);
  } catch (error) {
    console.error(error);
  }
}

converseTicket();

Code snippet using typescript on the right





















Java

import java.io.IOException;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.HttpClientBuilder;
import org.json.JSONObject;

public class TicketApiExample {
    public static void main(String[] args) {
        final HttpClient httpClient = HttpClientBuilder.create().build();
        final HttpPost request = new HttpPost("https://api.ultimate.ai/converse/ticket");

        // Set headers
        final String authorization = System.getenv("AUTHORIZATION");
        request.setHeader("Authorization", authorization);
        final String botId = System.getenv("BOTID");
        request.setHeader("botid", botId);

        // Create request body
        final JSONObject requestBody = new JSONObject();
        requestBody.put("platformConversationId", "123456");
        requestBody.put("text", "What is the refund policy for the article I bought yesterday?");

        final StringEntity entity = new StringEntity(requestBody.toString());
        request.setEntity(entity);
        try {
            final HttpResponse response = httpClient.execute(request);
            final int statusCode = response.getStatusLine().getStatusCode();
            if (statusCode >= 200 && statusCode < 300) {
                final HttpEntity responseEntity = response.getEntity();
                System.out.println(responseEntity.getContent());
            } else {
                System.err.println("Error: "+response.getStatusLine().getReasonPhrase());
            }
        } catch (IOException e) {
            System.err.println("Error: "+e.getMessage());
        }
    }
}

Code snippet using Java on the right

































Java + Spring

import lombok.Builder;
import lombok.Data;

@Data
@Builder
public class TicketRequest {
    private String platformConversationId;
    private String text;
    private List<MetaData> metadata;
    private Integer cardIndex;

    @Data
    @Builder
    public static class MetaData {
        private String key;
        private String value;
    }
}

@Service
public class TicketService {

    private final String authorization;
    private final String botid;
    private final RestTemplate restTemplate;

    @Autowired
    public TicketService(
            @Value("${TICKET_API_AUTHORIZATION}") String authorization,
            @Value("${TICKET_API_BOTID}") String botid,
            RestTemplate restTemplate
    ) {
        this.authorization = authorization;
        this.botid = botid;
        this.restTemplate = restTemplate;
    }

};

    public ResponseEntity<Object> converseTicket() {
        final HttpHeaders headers = new HttpHeaders();
        headers.set("Authorization", authorization);
        headers.set("botid", botid);

        final TicketRequest ticketRequest = TicketRequest.builder()
            .platformConversationId("YOUR_PLATFORM_CONVERSATION_ID")
            .text("Hello")
            .build();

        final HttpEntity<TicketRequest> request = new HttpEntity<>(ticketRequest, headers);
        return restTemplate.postForEntity("https://api.ultimate.ai/converse/ticket", request, Object.class);
    }
}

Code snippet using Java and Spring on the right
















































Java + Spring Webflux

import lombok.Builder;
import lombok.Data;

@Data
@Builder
public class TicketRequest {
    private String platformConversationId;
    private String text;
    private List<MetaData> metadata;

    @Data
    @Builder
    public static class MetaData {
        private String key;
        private String value;
    }
}

@Service
public class TicketService {

    private final String authorization;
    private final String botid;
    private final WebClient webClient;

    public TicketService(
            @Value("${CHAT_API_AUTHORIZATION}") String authorization,
            @Value("${CHAT_API_BOTID}") String botid,
            WebClient webClient
    ) {
        this.authorization = authorization;
        this.botid = botid;
        this.webClient = webClient;
    }

    public Mono<ResponseEntity<Object>> converseTicket() {
        final TicketRequest ticketRequest = TicketRequest.builder()
            .platformConversationId("YOUR_PLATFORM_CONVERSATION_ID")
            .text("Hello")
            .build();


        return webClient.post()
                .uri("https://api.ultimate.ai/converse/ticket")
                .header("Authorization", authorization)
                .header("botid", botid)
                .body(Mono.just(ticketRequest), TicketRequest.class)
                .exchange()
                .flatMap(response -> response.toEntity(Object.class));
    }
}

Code snippet using Java and Spring Webflux on the right