The Chat API is deprecated. It will be replaced with a new tutorial using
Completions V2 API.
- Persistent conversations with session management
- Contextual responses that build on previous interactions
- Source integration for grounded, authoritative answers
- Streaming responses for real-time conversation flow
Prerequisites
Before starting, ensure you have:- A Gloo AI Studio account
- Your Client ID and Client Secret from the API Credentials page
- Authentication setup - Complete the Authentication Tutorial first
The Chat and Message APIs require Bearer token authentication. If you haven’t
set up authentication yet, follow the Authentication
Tutorial to learn how to exchange your credentials
for access tokens and manage token expiration.
Step 1: Creating a Chat Session
The Message API can either create a new chat session or continue an existing one. When you don’t provide achat_id, it automatically creates a new session.
MESSAGE_API_URL = "https://platform.ai.gloo.com/ai/v1/message"
def create_chat_session(initial_message):
"""Create a new chat session with an initial message."""
token = ensure_valid_token()
headers = {
"Authorization": f"Bearer {token}",
"Content-Type": "application/json"
}
#- Request body for new chat (no chat_id provided)
payload = {
"query": initial_message,
"character_limit": 1000,
"sources_limit": 5,
"stream": False,
"publishers": [],
"enable_suggestions": 1 #- Enable suggested follow-up questions
}
response = requests.post(MESSAGE_API_URL, headers=headers, json=payload)
response.raise_for_status()
return response.json()
#- Example usage
initial_question = "How can I find meaning and purpose when facing life's greatest challenges?"
chat_response = create_chat_session(initial_question)
print("Chat created successfully!")
print(f"Chat ID: {chat_response['chat_id']}")
print(f"Message ID: {chat_response['message_id']}")
print(f"Response: {chat_response['message']}")
#- Show suggested follow-up questions
if chat_response.get('suggestions'):
print("\nSuggested follow-up questions:")
for i, suggestion in enumerate(chat_response['suggestions'], 1):
print(f"{i}. {suggestion}")
const MESSAGE_API_URL = 'https://platform.ai.gloo.com/ai/v1/message';
async function createChatSession(initialMessage) {
const token = await ensureValidToken();
const payload = {
query: initialMessage,
character_limit: 1000,
sources_limit: 5,
stream: false,
publishers: [],
enable_suggestions: 1, // Enable suggested follow-up questions
};
const response = await axios.post(MESSAGE_API_URL, payload, {
headers: {
Authorization: `Bearer ${token}`,
'Content-Type': 'application/json',
},
});
return response.data;
}
// Example usage
const initialQuestion =
"How can I find meaning and purpose when facing life's greatest challenges?";
const chatResponse = await createChatSession(initialQuestion);
console.log('Chat created successfully!');
console.log(`Chat ID: ${chatResponse.chat_id}`);
console.log(`Message ID: ${chatResponse.message_id}`);
console.log(`Response: ${chatResponse.message}`);
// Show suggested follow-up questions
if (chatResponse.suggestions) {
console.log('\nSuggested follow-up questions:');
chatResponse.suggestions.forEach((suggestion, index) => {
console.log(`${index + 1}. ${suggestion}`);
});
}
const MESSAGE_API_URL = 'https://platform.ai.gloo.com/ai/v1/message';
interface MessageResponse {
chat_id: string;
query_id: string;
message_id: string;
message: string;
timestamp: string;
success: boolean;
suggestions?: string[];
sources?: any[];
}
interface MessageRequest {
query: string;
character_limit?: number;
sources_limit?: number;
stream?: boolean;
publishers?: string[];
chat_id?: string;
enable_suggestions?: number;
}
async function createChatSession(
initialMessage: string,
): Promise<MessageResponse> {
const token = await ensureValidToken();
const payload: MessageRequest = {
query: initialMessage,
character_limit: 1000,
sources_limit: 5,
stream: false,
publishers: [],
enable_suggestions: 1, // Enable suggested follow-up questions
};
const response = await axios.post<MessageResponse>(MESSAGE_API_URL, payload, {
headers: {
Authorization: `Bearer ${token}`,
'Content-Type': 'application/json',
},
});
return response.data;
}
// Example usage
const initialQuestion =
"How can I find meaning and purpose when facing life's greatest challenges?";
const chatResponse = await createChatSession(initialQuestion);
console.log('Chat created successfully!');
console.log(`Chat ID: ${chatResponse.chat_id}`);
console.log(`Message ID: ${chatResponse.message_id}`);
console.log(`Response: ${chatResponse.message}`);
// Show suggested follow-up questions
if (chatResponse.suggestions) {
console.log('\nSuggested follow-up questions:');
chatResponse.suggestions.forEach((suggestion, index) => {
console.log(`${index + 1}. ${suggestion}`);
});
}
$MESSAGE_API_URL = 'https://platform.ai.gloo.com/ai/v1/message';
function createChatSession($initial_message) {
$token = ensureValidToken();
$payload = json_encode([
'query' => $initial_message,
'character_limit' => 1000,
'sources_limit' => 5,
'stream' => false,
'publishers' => [],
'enable_suggestions' => 1 // Enable suggested follow-up questions
]);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $GLOBALS['MESSAGE_API_URL']);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $payload);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Content-Type: application/json',
'Authorization: Bearer ' . $token
]);
$result = curl_exec($ch);
if (curl_errno($ch)) {
throw new Exception(curl_error($ch));
}
curl_close($ch);
return json_decode($result, true);
}
// Example usage
$initial_question = "How can I find meaning and purpose when facing life's greatest challenges?";
$chat_response = createChatSession($initial_question);
echo "Chat created successfully!\n";
echo "Chat ID: " . $chat_response['chat_id'] . "\n";
echo "Message ID: " . $chat_response['message_id'] . "\n";
echo "Response: " . $chat_response['message'] . "\n";
// Show suggested follow-up questions
if (!empty($chat_response['suggestions'])) {
echo "\nSuggested follow-up questions:\n";
foreach ($chat_response['suggestions'] as $index => $suggestion) {
echo ($index + 1) . ". " . $suggestion . "\n";
}
}
const messageAPIURL = "https://platform.ai.gloo.com/ai/v1/message"
type MessageRequest struct {
Query string `json:"query"`
CharacterLimit int `json:"character_limit,omitempty"`
SourcesLimit int `json:"sources_limit,omitempty"`
Stream bool `json:"stream,omitempty"`
Publishers []string `json:"publishers,omitempty"`
ChatID string `json:"chat_id,omitempty"`
EnableSuggestions int `json:"enable_suggestions,omitempty"`
}
type MessageResponse struct {
ChatID string `json:"chat_id"`
QueryID string `json:"query_id"`
MessageID string `json:"message_id"`
Message string `json:"message"`
Timestamp string `json:"timestamp"`
Success bool `json:"success"`
Suggestions []string `json:"suggestions"`
Sources []any `json:"sources"`
}
func createChatSession(initialMessage string) (*MessageResponse, error) {
token, err := ensureValidToken()
if err != nil {
return nil, err
}
payload := MessageRequest{
Query: initialMessage,
CharacterLimit: 1000,
SourcesLimit: 5,
Stream: false,
Publishers: []string{},
EnableSuggestions: 1, // Enable suggested follow-up questions
}
jsonPayload, err := json.Marshal(payload)
if err != nil {
return nil, err
}
req, err := http.NewRequest("POST", messageAPIURL, bytes.NewBuffer(jsonPayload))
if err != nil {
return nil, err
}
req.Header.Add("Authorization", "Bearer "+token)
req.Header.Add("Content-Type", "application/json")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
return nil, err
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return nil, err
}
if resp.StatusCode != http.StatusOK {
return nil, fmt.Errorf("API call failed: %s - %s", resp.Status, string(body))
}
var response MessageResponse
if err := json.Unmarshal(body, &response); err != nil {
return nil, err
}
return &response, nil
}
// Example usage
initialQuestion := "How can I find meaning and purpose when facing life's greatest challenges?"
chatResponse, err := createChatSession(initialQuestion)
if err != nil {
fmt.Printf("Error creating chat: %v\n", err)
return
}
fmt.Println("Chat created successfully!")
fmt.Printf("Query ID: %s\n", chatResponse.QueryID)
fmt.Printf("Message ID: %s\n", chatResponse.MessageID)
fmt.Printf("Response: %s\n", chatResponse.Message)
// Show suggested follow-up questions
if len(chatResponse.Suggestions) > 0 {
fmt.Println("\nSuggested follow-up questions:")
for i, suggestion := range chatResponse.Suggestions {
fmt.Printf("%d. %s\n", i+1, suggestion)
}
}
import java.io.IOException;
import java.net.URI;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.util.List;
public class ChatManager {
private static final String MESSAGE_API_URL = "https://platform.ai.gloo.com/ai/v1/message";
private static final HttpClient httpClient = HttpClient.newHttpClient();
private static final Gson gson = new Gson();
public static class MessageRequest {
public String query;
public Integer character_limit;
public Integer sources_limit;
public Boolean stream;
public List<String> publishers;
public String chat_id;
public Integer enable_suggestions;
}
public static class MessageResponse {
public String chat_id;
public String query_id;
public String message_id;
public String message;
public String timestamp;
public Boolean success;
public List<String> suggestions;
public List<Object> sources;
}
public static MessageResponse createChatSession(String initialMessage) throws IOException, InterruptedException {
String token = AuthManager.ensureValidToken();
MessageRequest payload = new MessageRequest();
payload.query = initialMessage;
payload.character_limit = 1000;
payload.sources_limit = 5;
payload.stream = false;
payload.publishers = List.of();
payload.enable_suggestions = 1; // Enable suggested follow-up questions
String jsonPayload = gson.toJson(payload);
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(MESSAGE_API_URL))
.header("Content-Type", "application/json")
.header("Authorization", "Bearer " + token)
.POST(HttpRequest.BodyPublishers.ofString(jsonPayload))
.build();
HttpResponse<String> response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
if (response.statusCode() != 200) {
throw new IOException("API call failed: " + response.body());
}
return gson.fromJson(response.body(), MessageResponse.class);
}
// Example usage
public static void main(String[] args) {
try {
String initialQuestion = "How can I find meaning and purpose when facing life's greatest challenges?";
MessageResponse chatResponse = createChatSession(initialQuestion);
System.out.println("Chat created successfully!");
System.out.println("Chat ID: " + chatResponse.chat_id);
System.out.println("Message ID: " + chatResponse.message_id);
System.out.println("Response: " + chatResponse.message);
// Show suggested follow-up questions
if (chatResponse.suggestions != null && !chatResponse.suggestions.isEmpty()) {
System.out.println("\nSuggested follow-up questions:");
for (int i = 0; i < chatResponse.suggestions.size(); i++) {
System.out.println((i + 1) + ". " + chatResponse.suggestions.get(i));
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
Step 2: Continuing the Conversation
Once you have a chat session, you can continue the conversation by including thechat_id from the previous response in your next message request. You don’t need to retrieve chat history to continue the conversation - the API maintains context automatically.
def continue_conversation(chat_id, follow_up_message):
"""Continue an existing chat conversation."""
token = ensure_valid_token()
headers = {
"Authorization": f"Bearer {token}",
"Content-Type": "application/json"
}
#- Include chat_id to continue the conversation
payload = {
"chat_id": chat_id,
"query": follow_up_message,
"character_limit": 1000,
"sources_limit": 5,
"stream": False,
"publishers": [],
"enable_suggestions": 1 #- Continue getting suggestions
}
response = requests.post(MESSAGE_API_URL, headers=headers, json=payload)
response.raise_for_status()
return response.json()
#- Example: Continue the conversation using a suggested response
#- Use the first suggestion from the initial response
if chat_response.get('suggestions') and len(chat_response['suggestions']) > 0:
follow_up = chat_response['suggestions'][0] #- Use first suggested question
else:
follow_up = "Can you give me practical steps I can take today to begin this journey?"
follow_up_response = continue_conversation(chat_response['chat_id'], follow_up)
print("\nFollow-up Response:")
print(f"Question: {follow_up}")
print(f"Response: {follow_up_response['message']}")
async function continueConversation(chatId, followUpMessage) {
const token = await ensureValidToken();
const payload = {
chat_id: chatId,
query: followUpMessage,
character_limit: 1000,
sources_limit: 5,
stream: false,
publishers: [],
enable_suggestions: 1, // Continue getting suggestions
};
const response = await axios.post(MESSAGE_API_URL, payload, {
headers: {
Authorization: `Bearer ${token}`,
'Content-Type': 'application/json',
},
});
return response.data;
}
// Example: Continue the conversation with a follow-up
const followUpQuestion =
chatResponse.suggestions && chatResponse.suggestions.length > 0
? chatResponse.suggestions[0]
: 'Can you give me practical steps I can take today to begin this journey?';
const followUpResponse = await continueConversation(
chatResponse.chat_id,
followUpQuestion,
);
console.log('\nFollow-up Response:');
console.log(`Response: ${followUpResponse.message}`);
async function continueConversation(
chatId: string,
followUpMessage: string,
): Promise<MessageResponse> {
const token = await ensureValidToken();
const payload: MessageRequest = {
chat_id: chatId,
query: followUpMessage,
character_limit: 1000,
sources_limit: 5,
stream: false,
publishers: [],
};
const response = await axios.post<MessageResponse>(MESSAGE_API_URL, payload, {
headers: {
Authorization: `Bearer ${token}`,
'Content-Type': 'application/json',
},
});
return response.data;
}
// Example: Continue the conversation with a follow-up
const followUpQuestion =
chatResponse.suggestions && chatResponse.suggestions.length > 0
? chatResponse.suggestions[0]
: 'Can you give me practical steps I can take today to begin this journey?';
const followUpResponse = await continueConversation(
chatResponse.chat_id,
followUpQuestion,
);
console.log('\nFollow-up Response:');
console.log(`Response: ${followUpResponse.message}`);
function continueConversation($chat_id, $follow_up) {
$token = ensureValidToken();
$payload = json_encode([
'chat_id' => $chat_id,
'query' => $follow_up,
'character_limit' => 1000,
'sources_limit' => 5,
'stream' => false,
'publishers' => []
]);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $GLOBALS['MESSAGE_API_URL']);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $payload);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Content-Type: application/json',
'Authorization: Bearer ' . $token
]);
$result = curl_exec($ch);
if (curl_errno($ch)) {
throw new Exception(curl_error($ch));
}
curl_close($ch);
return json_decode($result, true);
}
// Example: Continue the conversation with a follow-up
$follow_up = !empty($chat_response['suggestions'])
? $chat_response['suggestions'][0]
: "Can you give me practical steps I can take today to begin this journey?";
$follow_up_response = continueConversation($chat_response['chat_id'], $follow_up);
echo "\nFollow-up Response:\n";
echo "Response: " . $follow_up_response['message'] . "\n";
func continueConversation(chatID, followUpMessage string) (*MessageResponse, error) {
token, err := ensureValidToken()
if err != nil {
return nil, err
}
payload := MessageRequest{
ChatID: chatID,
Query: followUpMessage,
CharacterLimit: 1000,
SourcesLimit: 5,
Stream: false,
Publishers: []string{},
}
jsonPayload, err := json.Marshal(payload)
if err != nil {
return nil, err
}
req, err := http.NewRequest("POST", messageAPIURL, bytes.NewBuffer(jsonPayload))
if err != nil {
return nil, err
}
req.Header.Add("Authorization", "Bearer "+token)
req.Header.Add("Content-Type", "application/json")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
return nil, err
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return nil, err
}
if resp.StatusCode != http.StatusOK {
return nil, fmt.Errorf("API call failed: %s - %s", resp.Status, string(body))
}
var response MessageResponse
if err := json.Unmarshal(body, &response); err != nil {
return nil, err
}
return &response, nil
}
// Example: Continue the conversation with a follow-up
var followUp string
if len(chatResponse.Suggestions) > 0 {
followUp = chatResponse.Suggestions[0]
} else {
followUp = "Can you give me practical steps I can take today to begin this journey?"
}
followUpResponse, err := continueConversation(chatResponse.ChatID, followUp)
if err != nil {
fmt.Printf("Error continuing conversation: %v\n", err)
return
}
fmt.Println("\nFollow-up Response:")
fmt.Printf("Response: %s\n", followUpResponse.Message)
public static MessageResponse continueConversation(String chatId, String followUpMessage) throws IOException, InterruptedException {
String token = AuthManager.ensureValidToken();
MessageRequest payload = new MessageRequest();
payload.chat_id = chatId;
payload.query = followUpMessage;
payload.character_limit = 1000;
payload.sources_limit = 5;
payload.stream = false;
payload.publishers = List.of();
String jsonPayload = gson.toJson(payload);
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(MESSAGE_API_URL))
.header("Content-Type", "application/json")
.header("Authorization", "Bearer " + token)
.POST(HttpRequest.BodyPublishers.ofString(jsonPayload))
.build();
HttpResponse<String> response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
if (response.statusCode() != 200) {
throw new IOException("API call failed: " + response.body());
}
return gson.fromJson(response.body(), MessageResponse.class);
}
// Modified main
public static void main(String[] args) {
try {
// ... Code from previous step
String followUp = (chatResponse.suggestions != null && !chatResponse.suggestions.isEmpty())
? chatResponse.suggestions.get(0)
: "Can you give me practical steps I can take today to begin this journey?";
MessageResponse followUpResponse = continueConversation(chatId, followUp);
System.out.println("\nFollow-up Response:");
System.out.println("Response: " + followUpResponse.message);
} catch (Exception e) {
e.printStackTrace();
}
}
Step 3: Retrieving Chat History (Optional)
If you want to view the complete conversation history, you can retrieve it using the Chat API. This is useful for displaying conversation logs or analyzing chat patterns.def get_chat_history(chat_id):
"""Retrieve the complete chat history for a conversation."""
token = ensure_valid_token()
headers = {
"Authorization": f"Bearer {token}",
"Content-Type": "application/json"
}
#- Use the chat endpoint to get full conversation history
params = {"chat_id": chat_id}
response = requests.get(CHAT_API_URL, headers=headers, params=params)
response.raise_for_status()
return response.json()
#- Example: Get chat history after the follow-up conversation
print("\n" + "="*50)
print("COMPLETE CONVERSATION HISTORY")
print("="*50)
chat_history = get_chat_history(chat_response['chat_id'])
#- Display the conversation history
for i, message in enumerate(chat_history.get('messages', []), 1):
role = message.get('role', 'unknown')
content = message.get('content', '')
timestamp = message.get('timestamp', '')
print(f"\n{i}. {role.upper()}: {content}")
if timestamp:
print(f" Time: {timestamp}")
async function getChatHistory(chatId) {
const token = await ensureValidToken();
const response = await axios.get(CHAT_API_URL, {
params: { chat_id: chatId },
headers: {
Authorization: `Bearer ${token}`,
'Content-Type': 'application/json',
},
});
return response.data;
}
// Example: Get chat history after the follow-up conversation
console.log('\n' + '='.repeat(50));
console.log('COMPLETE CONVERSATION HISTORY');
console.log('='.repeat(50));
const chatHistory = await getChatHistory(chatResponse.chat_id);
// Display the conversation history
chatHistory.messages?.forEach((message, index) => {
const role = message.role || 'unknown';
const content = message.content || '';
const timestamp = message.timestamp || '';
console.log(`\n${index + 1}. ${role.toUpperCase()}: ${content}`);
if (timestamp) {
console.log(` Time: ${timestamp}`);
}
});
async function getChatHistory(chatId: string): Promise<ChatHistoryResponse> {
const token = await ensureValidToken();
const response = await axios.get<ChatHistoryResponse>(CHAT_API_URL, {
params: { chat_id: chatId },
headers: {
Authorization: `Bearer ${token}`,
'Content-Type': 'application/json',
},
});
return response.data;
}
// Example: Get chat history after the follow-up conversation
console.log('\n' + '='.repeat(50));
console.log('COMPLETE CONVERSATION HISTORY');
console.log('='.repeat(50));
const chatHistory = await getChatHistory(chatResponse.chat_id);
// Display the conversation history
chatHistory.messages?.forEach((message, index) => {
const role = message.role || 'unknown';
const content = message.content || '';
const timestamp = message.timestamp || '';
console.log(`\n${index + 1}. ${role.toUpperCase()}: ${content}`);
if (timestamp) {
console.log(` Time: ${timestamp}`);
}
});
function getChatHistory($chat_id) {
$token = ensureValidToken();
$url = $GLOBALS['CHAT_API_URL'] . '?' . http_build_query(['chat_id' => $chat_id]);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Content-Type: application/json',
'Authorization: Bearer ' . $token
]);
$result = curl_exec($ch);
if (curl_errno($ch)) {
throw new Exception(curl_error($ch));
}
curl_close($ch);
return json_decode($result, true);
}
// Example: Get chat history after the follow-up conversation
echo "\n" . str_repeat("=", 50) . "\n";
echo "COMPLETE CONVERSATION HISTORY\n";
echo str_repeat("=", 50) . "\n";
$chat_history = getChatHistory($chat_response['chat_id']);
// Display the conversation history
foreach ($chat_history['messages'] ?? [] as $index => $message) {
$role = $message['role'] ?? 'unknown';
$content = $message['content'] ?? '';
$timestamp = $message['timestamp'] ?? '';
echo "\n" . ($index + 1) . ". " . strtoupper($role) . ": " . $content . "\n";
if (!empty($timestamp)) {
echo " Time: " . $timestamp . "\n";
}
}
func getChatHistory(chatID string) (*ChatHistoryResponse, error) {
token, err := ensureValidToken()
if err != nil {
return nil, err
}
// Build URL with query parameters
chatURL := fmt.Sprintf("%s?chat_id=%s", chatAPIURL, chatID)
req, err := http.NewRequest("GET", chatURL, nil)
if err != nil {
return nil, err
}
req.Header.Add("Authorization", "Bearer "+token)
req.Header.Add("Content-Type", "application/json")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
return nil, err
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return nil, err
}
if resp.StatusCode != http.StatusOK {
return nil, fmt.Errorf("API call failed: %s - %s", resp.Status, string(body))
}
var response ChatHistoryResponse
if err := json.Unmarshal(body, &response); err != nil {
return nil, err
}
return &response, nil
}
// Example: Get chat history after the follow-up conversation
fmt.Println("\n" + strings.Repeat("=", 50))
fmt.Println("COMPLETE CONVERSATION HISTORY")
fmt.Println(strings.Repeat("=", 50))
chatHistory, err := getChatHistory(chatResponse.QueryID)
if err != nil {
fmt.Printf("Error getting chat history: %v\n", err)
return
}
// Display the conversation history
for i, message := range chatHistory.Messages {
role := message.Role
if role == "" {
role = "unknown"
}
content := message.Content
timestamp := message.Timestamp
fmt.Printf("\n%d. %s: %s\n", i+1, strings.ToUpper(role), content)
if timestamp != "" {
fmt.Printf(" Time: %s\n", timestamp)
}
}
public static ChatHistoryResponse getChatHistory(String chatId) throws IOException, InterruptedException {
String token = AuthManager.ensureValidToken();
String chatUrl = CHAT_API_URL + "?chat_id=" + chatId;
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(chatUrl))
.header("Content-Type", "application/json")
.header("Authorization", "Bearer " + token)
.GET()
.build();
HttpResponse<String> response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
if (response.statusCode() != 200) {
throw new IOException("API call failed: " + response.body());
}
return gson.fromJson(response.body(), ChatHistoryResponse.class);
}
// Example: Get chat history after the follow-up conversation
public static void displayChatHistory(String chatId) throws IOException, InterruptedException {
System.out.println("\n" + "=".repeat(50));
System.out.println("COMPLETE CONVERSATION HISTORY");
System.out.println("=".repeat(50));
ChatHistoryResponse chatHistory = getChatHistory(chatId);
// Display the conversation history
List<ChatMessage> messages = chatHistory.messages != null ? chatHistory.messages : new ArrayList<>();
for (int i = 0; i < messages.size(); i++) {
ChatMessage message = messages.get(i);
String role = message.role != null ? message.role : "unknown";
String content = message.content != null ? message.content : "";
String timestamp = message.timestamp != null ? message.timestamp : "";
System.out.printf("\n%d. %s: %s\n", (i + 1), role.toUpperCase(), content);
if (!timestamp.isEmpty()) {
System.out.printf(" Time: %s\n", timestamp);
}
}
}
Complete Working Examples
Here are complete, runnable examples that demonstrate the full chat flow:#!/usr/bin/env python3
"""
Complete Chat Example - Python
Demonstrates creating a chat session and continuing the conversation.
"""
import requests
import time
import os
from dotenv import load_dotenv
#- Load environment variables
load_dotenv()
#- Configuration
CLIENT_ID = os.getenv("GLOO_CLIENT_ID", "YOUR_CLIENT_ID")
CLIENT_SECRET = os.getenv("GLOO_CLIENT_SECRET", "YOUR_CLIENT_SECRET")
TOKEN_URL = "https://platform.ai.gloo.com/oauth2/token"
MESSAGE_API_URL = "https://platform.ai.gloo.com/ai/v1/message"
CHAT_API_URL = "https://platform.ai.gloo.com/ai/v1/chat"
#- Global token storage
access_token_info = {}
def get_access_token():
"""Retrieve a new access token from the Gloo AI API."""
headers = {"Content-Type": "application/x-www-form-urlencoded"}
data = {"grant_type": "client_credentials", "scope": "api/access"}
response = requests.post(TOKEN_URL, headers=headers, data=data, auth=(CLIENT_ID, CLIENT_SECRET))
response.raise_for_status()
token_data = response.json()
token_data['expires_at'] = int(time.time()) + token_data['expires_in']
return token_data
def is_token_expired(token_info):
"""Check if the token is expired or close to expiring."""
if not token_info or 'expires_at' not in token_info:
return True
return time.time() > (token_info['expires_at'] - 60)
def ensure_valid_token():
"""Ensure we have a valid access token."""
global access_token_info
if is_token_expired(access_token_info):
print("Getting new access token...")
access_token_info = get_access_token()
return access_token_info['access_token']
def send_message(message_text, chat_id=None):
"""Send a message to the chat API."""
token = ensure_valid_token()
headers = {
"Authorization": f"Bearer {token}",
"Content-Type": "application/json"
}
payload = {
"query": message_text,
"character_limit": 1000,
"sources_limit": 5,
"stream": False,
"publishers": []
}
if chat_id:
payload["chat_id"] = chat_id
response = requests.post(MESSAGE_API_URL, headers=headers, json=payload)
response.raise_for_status()
return response.json()
def get_chat_history(chat_id):
"""Retrieve the full chat history for a given chat ID."""
token = ensure_valid_token()
headers = {
"Authorization": f"Bearer {token}",
"Content-Type": "application/json"
}
params = {"chat_id": chat_id}
response = requests.get(CHAT_API_URL, headers=headers, params=params)
response.raise_for_status()
return response.json()
def main():
"""Main function demonstrating the complete chat flow."""
try:
#- Start with a deep, meaningful question
initial_question = "How can I find meaning and purpose when facing life's greatest challenges?"
print("=== Starting New Chat Session ===")
print(f"Question: {initial_question}")
print()
#- Create new chat session
chat_response = send_message(initial_question)
chat_id = chat_response['chat_id']
print("AI Response:")
print(chat_response['message'])
print()
#- Show suggested follow-up questions
if chat_response['suggestions']:
print("Suggested follow-up questions:")
for i, suggestion in enumerate(chat_response['suggestions'], 1):
print(f"{i}. {suggestion}")
print()
#- Use the first suggested question for follow-up, or fallback
if chat_response['suggestions']:
follow_up_question = chat_response['suggestions'][0]
else:
follow_up_question = "Can you give me practical steps I can take today to begin this journey?"
print("=== Continuing the Conversation ===")
print(f"Using suggested question: {follow_up_question}")
print()
#- Send follow-up message
follow_up_response = send_message(follow_up_question, chat_id)
print("AI Response:")
print(follow_up_response.message)
print()
#- Display final chat history
print("=== Complete Chat History ===")
chat_history = get_chat_history(chat_id)
for message in chat_history['messages']:
role = message['role'].upper()
content = message['message']
print(f"{role}: {content}")
print()
print("Chat session completed successfully!")
except requests.exceptions.RequestException as e:
print(f"API Error: {e}")
except Exception as e:
print(f"Error: {e}")
if __name__ == "__main__":
main()
#!/usr/bin/env node
/**
* Complete Chat Example - JavaScript/Node.js
* Demonstrates creating a chat session and continuing the conversation.
*/
const axios = require('axios');
require('dotenv').config();
// Configuration
const CLIENT_ID = process.env.GLOO_CLIENT_ID || 'YOUR_CLIENT_ID';
const CLIENT_SECRET = process.env.GLOO_CLIENT_SECRET || 'YOUR_CLIENT_SECRET';
const TOKEN_URL = 'https://platform.ai.gloo.com/oauth2/token';
const MESSAGE_API_URL = 'https://platform.ai.gloo.com/ai/v1/message';
const CHAT_API_URL = 'https://platform.ai.gloo.com/ai/v1/chat';
// Global token storage
let tokenInfo = {};
async function getAccessToken() {
const body = 'grant_type=client_credentials&scope=api/access';
const response = await axios.post(TOKEN_URL, body, {
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
auth: { username: CLIENT_ID, password: CLIENT_SECRET },
});
const tokenData = response.data;
tokenData.expires_at = Math.floor(Date.now() / 1000) + tokenData.expires_in;
return tokenData;
}
function isTokenExpired(token) {
if (!token || !token.expires_at) return true;
return Date.now() / 1000 > token.expires_at - 60;
}
async function ensureValidToken() {
if (isTokenExpired(tokenInfo)) {
console.log('Getting new access token...');
tokenInfo = await getAccessToken();
}
return tokenInfo.access_token;
}
async function sendMessage(messageText, chatId = null) {
const token = await ensureValidToken();
const payload = {
query: messageText,
character_limit: 1000,
sources_limit: 5,
stream: false,
publishers: [],
enable_suggestions: 1,
};
if (chatId) {
payload.chat_id = chatId;
}
const response = await axios.post(MESSAGE_API_URL, payload, {
headers: {
Authorization: `Bearer ${token}`,
'Content-Type': 'application/json',
},
});
return response.data;
}
async function getChatHistory(chatId) {
const token = await ensureValidToken();
const response = await axios.get(CHAT_API_URL, {
headers: {
Authorization: `Bearer ${token}`,
'Content-Type': 'application/json',
},
params: {
chat_id: chatId,
},
});
return response.data;
}
async function main() {
try {
// Start with a deep, meaningful question
const initialQuestion =
"How can I find meaning and purpose when facing life's greatest challenges?";
console.log('=== Starting New Chat Session ===');
console.log(`Question: ${initialQuestion}`);
console.log();
// Create new chat session
const chatResponse = await sendMessage(initialQuestion);
const chatId = chatResponse.chat_id;
console.log('AI Response:');
console.log(chatResponse.message);
console.log();
// Show suggested follow-up questions
if (chatResponse.suggestions && chatResponse.suggestions.length > 0) {
console.log('Suggested follow-up questions:');
chatResponse.suggestions.forEach((suggestion, index) => {
console.log(`${index + 1}. ${suggestion}`);
});
console.log();
}
// Use the first suggested question for follow-up, or fallback
const followUpQuestion =
chatResponse.suggestions && chatResponse.suggestions.length > 0
? chatResponse.suggestions[0]
: 'Can you give me practical steps I can take today to begin this journey?';
console.log('=== Continuing the Conversation ===');
console.log(`Using suggested question: ${followUpQuestion}`);
console.log();
// Send follow-up message
const followUpResponse = await sendMessage(followUpQuestion, chatId);
console.log('AI Response:');
console.log(followUpResponse.message);
console.log();
// Display final chat history (optional)
console.log('=== Complete Chat History (Optional) ===');
console.log(
'This shows how to retrieve the complete conversation history:',
);
console.log();
const chatHistory = await getChatHistory(chatId);
chatHistory.messages.forEach((message, index) => {
const role = message.role.toUpperCase();
const content = message.message;
console.log(`${index + 1}. ${role}: ${content}`);
console.log();
});
console.log('Chat session completed successfully!');
} catch (error) {
console.error(
'Error:',
error.response ? error.response.data : error.message,
);
}
}
// Run the main function
main();
The
kallm message role is deprecated and no longer supported.#!/usr/bin/env tsx
/**
* Complete Chat Example - TypeScript
* Demonstrates creating a chat session and continuing the conversation.
*/
import axios from 'axios';
import * as dotenv from 'dotenv';
dotenv.config();
// Configuration
const CLIENT_ID = process.env.GLOO_CLIENT_ID || 'YOUR_CLIENT_ID';
const CLIENT_SECRET = process.env.GLOO_CLIENT_SECRET || 'YOUR_CLIENT_SECRET';
const TOKEN_URL = 'https://platform.ai.gloo.com/oauth2/token';
const MESSAGE_API_URL = 'https://platform.ai.gloo.com/ai/v1/message';
const CHAT_API_URL = 'https://platform.ai.gloo.com/ai/v1/chat';
// Type definitions
interface TokenInfo {
access_token: string;
expires_in: number;
expires_at: number;
token_type: string;
}
interface MessageResponse {
chat_id: string;
query_id: string;
message_id: string;
message: string;
timestamp: string;
success: boolean;
suggestions?: string[];
sources?: any[];
}
interface MessageRequest {
query: string;
character_limit?: number;
sources_limit?: number;
stream?: boolean;
publishers?: string[];
chat_id?: string;
enable_suggestions?: number;
}
interface ChatMessage {
query_id: string;
message_id: string;
timestamp: string;
role: 'user' | 'kallm';
message: string;
character_limit?: number;
}
interface ChatHistory {
chat_id: string;
created_at: string;
messages: ChatMessage[];
}
// Global token storage
let tokenInfo: TokenInfo | null = null;
async function getAccessToken(): Promise<TokenInfo> {
const body = 'grant_type=client_credentials&scope=api/access';
const response = await axios.post<TokenInfo>(TOKEN_URL, body, {
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
auth: { username: CLIENT_ID, password: CLIENT_SECRET },
});
const tokenData = response.data;
(tokenData as any).expires_at =
Math.floor(Date.now() / 1000) + tokenData.expires_in;
return tokenData;
}
function isTokenExpired(token: TokenInfo | null): boolean {
if (!token || !(token as any).expires_at) return true;
return Date.now() / 1000 > (token as any).expires_at - 60;
}
async function ensureValidToken(): Promise<string> {
if (isTokenExpired(tokenInfo)) {
console.log('Getting new access token...');
tokenInfo = await getAccessToken();
}
return tokenInfo!.access_token;
}
async function sendMessage(
messageText: string,
chatId?: string,
): Promise<MessageResponse> {
const token = await ensureValidToken();
const payload: MessageRequest = {
query: messageText,
character_limit: 1000,
sources_limit: 5,
stream: false,
publishers: [],
enable_suggestions: 1,
};
if (chatId) {
payload.chat_id = chatId;
}
const response = await axios.post<MessageResponse>(MESSAGE_API_URL, payload, {
headers: {
Authorization: `Bearer ${token}`,
'Content-Type': 'application/json',
},
});
return response.data;
}
async function getChatHistory(chatId: string): Promise<ChatHistory> {
const token = await ensureValidToken();
const response = await axios.get<ChatHistory>(CHAT_API_URL, {
headers: {
Authorization: `Bearer ${token}`,
'Content-Type': 'application/json',
},
params: {
chat_id: chatId,
},
});
return response.data;
}
async function main(): Promise<void> {
try {
// Start with a deep, meaningful question
const initialQuestion =
"How can I find meaning and purpose when facing life's greatest challenges?";
console.log('=== Starting New Chat Session ===');
console.log(`Question: ${initialQuestion}`);
console.log();
// Create new chat session
const chatResponse = await sendMessage(initialQuestion);
const chatId = chatResponse.chat_id;
console.log('AI Response:');
console.log(chatResponse.message);
console.log();
// Show suggested follow-up questions
if (chatResponse.suggestions && chatResponse.suggestions.length > 0) {
console.log('Suggested follow-up questions:');
chatResponse.suggestions.forEach((suggestion, index) => {
console.log(`${index + 1}. ${suggestion}`);
});
console.log();
}
// Use the first suggested question for follow-up, or fallback
const followUpQuestion =
chatResponse.suggestions && chatResponse.suggestions.length > 0
? chatResponse.suggestions[0]
: 'Can you give me practical steps I can take today to begin this journey?';
console.log('=== Continuing the Conversation ===');
console.log(`Using suggested question: ${followUpQuestion}`);
console.log();
// Send follow-up message
const followUpResponse = await sendMessage(followUpQuestion, chatId);
console.log('AI Response:');
console.log(followUpResponse.message);
console.log();
// Display final chat history
console.log('=== Complete Chat History ===');
const chatHistory = await getChatHistory(chatId);
chatHistory.messages.forEach((message) => {
const role = message.role.toUpperCase();
const content = message.message;
console.log(`${role}: ${content}`);
console.log();
});
console.log('Chat session completed successfully!');
} catch (error: any) {
console.error(
'Error:',
error.response ? error.response.data : error.message,
);
}
}
// Run the main function
main();
#!/usr/bin/env php
<?php
/**
* Complete Chat Example - PHP
* Demonstrates creating a chat session and continuing the conversation.
*/
require_once 'vendor/autoload.php';
// Load environment variables
$dotenv = Dotenv\Dotenv::createImmutable(__DIR__);
$dotenv->load();
// Configuration
$CLIENT_ID = getenv('GLOO_CLIENT_ID') ?: 'YOUR_CLIENT_ID';
$CLIENT_SECRET = getenv('GLOO_CLIENT_SECRET') ?: 'YOUR_CLIENT_SECRET';
$TOKEN_URL = 'https://platform.ai.gloo.com/oauth2/token';
$MESSAGE_API_URL = 'https://platform.ai.gloo.com/ai/v1/message';
$CHAT_API_URL = 'https://platform.ai.gloo.com/ai/v1/chat';
// Global token storage
$token_info = [];
function getAccessToken($client_id, $client_secret, $token_url) {
$post_data = 'grant_type=client_credentials&scope=api/access';
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $token_url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);
curl_setopt($ch, CURLOPT_USERPWD, $client_id . ':' . $client_secret);
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/x-www-form-urlencoded']);
$result = curl_exec($ch);
if (curl_errno($ch)) {
throw new Exception(curl_error($ch));
}
curl_close($ch);
$token_data = json_decode($result, true);
$token_data['expires_at'] = time() + $token_data['expires_in'];
return $token_data;
}
function isTokenExpired($token) {
if (empty($token) || !isset($token['expires_at'])) {
return true;
}
return time() > ($token['expires_at'] - 60);
}
function ensureValidToken() {
global $token_info, $CLIENT_ID, $CLIENT_SECRET, $TOKEN_URL;
if (isTokenExpired($tokenInfo)) {
echo "Getting new access token...\n";
$token_info = getAccessToken($CLIENT_ID, $CLIENT_SECRET, $TOKEN_URL);
}
return $token_info['access_token'];
}
function sendMessage($messageText, $chatId = null) {
global $MESSAGE_API_URL;
$token = ensureValidToken();
$payload = [
'query' => $messageText,
'character_limit' => 1000,
'sources_limit' => 5,
'stream' => false,
'publishers' => []
];
if ($chatId) {
$payload['chat_id'] = $chatId;
}
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $MESSAGE_API_URL);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($payload));
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Content-Type: application/json',
'Authorization: Bearer ' . $token
]);
$result = curl_exec($ch);
if (curl_errno($ch)) {
throw new Exception(curl_error($ch));
}
curl_close($ch);
return json_decode($result, true);
}
function getChatHistory($chatId) {
global $CHAT_API_URL;
$token = ensureValidToken();
$url = $CHAT_API_URL . '?' . http_build_query(['chat_id' => $chatId]);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Authorization: Bearer ' . $token,
'Content-Type: application/json'
]);
$result = curl_exec($ch);
if (curl_errno($ch)) {
throw new Exception(curl_error($ch));
}
curl_close($ch);
return json_decode($result, true);
}
function main() {
try {
// Start with a deep, meaningful question about human flourishing
$initial_question = "How can I find meaning and purpose when facing life's greatest challenges?";
echo "=== Starting New Chat Session ===\n";
echo "Question: $initial_question\n\n";
// Create new chat session
$chat_response = sendMessage($initial_question);
$chat_id = $chat_response->chat_id;
echo "AI Response:\n";
echo $chat_response->message . "\n\n";
// Show suggested follow-up questions
if (!empty($chat_response->suggestions)) {
echo "Suggested follow-up questions:\n";
foreach ($chat_response->suggestions as $index => $suggestion) {
echo ($index + 1) . ". " . $suggestion . "\n";
}
echo "\n";
}
// Use the first suggested question for follow-up, or a predefined fallback
$follow_up_question = !empty($chat_response->suggestions)
? $chat_response->suggestions[0]
: "Can you give me practical steps I can take today to begin this journey?";
echo "=== Continuing the Conversation ===\n";
echo "Using suggested question: $follow_up_question\n\n";
// Send the follow-up message
$follow_up_response = sendMessage($follow_up_question, $chat_id);
echo "AI Response:\n";
echo $follow_up_response->message . "\n\n";
// Display final chat history
echo "=== Complete Chat History ===\n";
$chat_history = getChatHistory($chat_id);
foreach ($chat_history->messages as $i => $message) {
displayMessage($message, $i);
}
echo "Chat session completed successfully!\n";
} catch (Exception $e) {
echo "Error: " . $e->getMessage() . "\n";
}
}
// Run the main function
main();
?>
package main
import (
"bytes"
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
"net/url"
"os"
"strings"
"time"
)
// Configuration
var (
clientID = getEnv("GLOO_CLIENT_ID", "YOUR_CLIENT_ID")
clientSecret = getEnv("GLOO_CLIENT_SECRET", "YOUR_CLIENT_SECRET")
tokenURL = "https://platform.ai.gloo.com/oauth2/token"
messageURL = "https://platform.ai.gloo.com/ai/v1/message"
chatURL = "https://platform.ai.gloo.com/ai/v1/chat"
)
// Data structures
type TokenInfo struct {
AccessToken string `json:"access_token"`
ExpiresIn int `json:"expires_in"`
ExpiresAt int64 `json:"expires_at"`
TokenType string `json:"token_type"`
}
type MessageRequest struct {
Query string `json:"query"`
CharacterLimit int `json:"character_limit,omitempty"`
SourcesLimit int `json:"sources_limit,omitempty"`
Stream bool `json:"stream,omitempty"`
Publishers []string `json:"publishers,omitempty"`
ChatID string `json:"chat_id,omitempty"`
}
type MessageResponse struct {
QueryID string `json:"query_id"`
MessageID string `json:"message_id"`
Message string `json:"message"`
Timestamp string `json:"timestamp"`
}
type ChatMessage struct {
QueryID string `json:"query_id"`
MessageID string `json:"message_id"`
Timestamp string `json:"timestamp"`
Role string `json:"role"`
Message string `json:"message"`
CharacterLimit int `json:"character_limit,omitempty"`
}
type ChatHistory struct {
ChatID string `json:"chat_id"`
CreatedAt string `json:"created_at"`
Messages []ChatMessage `json:"messages"`
}
// Global token storage
var tokenInfo *TokenInfo
func getEnv(key, fallback string) string {
if value, ok := os.LookupEnv(key); ok {
return value
}
return fallback
}
func getAccessToken() (*TokenInfo, error) {
data := strings.NewReader("grant_type=client_credentials&scope=api/access")
req, err := http.NewRequest("POST", tokenURL, data)
if err != nil {
return nil, err
}
req.SetBasicAuth(clientID, clientSecret)
req.Header.Add("Content-Type", "application/x-www-form-urlencoded")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
return nil, err
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
bodyBytes, _ := ioutil.ReadAll(resp.Body)
return nil, fmt.Errorf("failed to get token: %s - %s", resp.Status, string(bodyBytes))
}
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return nil, err
}
var token TokenInfo
if err := json.Unmarshal(body, &token); err != nil {
return nil, err
}
token.ExpiresAt = time.Now().Unix() + int64(token.ExpiresIn)
return &token, nil
}
func isTokenExpired(token *TokenInfo) bool {
if token == nil || token.ExpiresAt == 0 {
return true
}
return time.Now().Unix() > (token.ExpiresAt - 60)
}
func ensureValidToken() (string, error) {
if isTokenExpired(tokenInfo) {
fmt.Println("Getting new access token...")
var err error
tokenInfo, err = getAccessToken()
if err != nil {
return "", err
}
}
return tokenInfo.AccessToken, nil
}
func sendMessage(messageText string, chatID string) (*MessageResponse, error) {
token, err := ensureValidToken()
if err != nil {
return nil, err
}
payload := MessageRequest{
Query: messageText,
CharacterLimit: 1000,
SourcesLimit: 5,
Stream: false,
Publishers: []string{},
ChatID: chatID,
}
jsonPayload, err := json.Marshal(payload)
if err != nil {
return nil, err
}
req, err := http.NewRequest("POST", messageURL, bytes.NewBuffer(jsonPayload))
if err != nil {
return nil, err
}
req.Header.Add("Authorization", "Bearer "+token)
req.Header.Add("Content-Type", "application/json")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
return nil, err
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return nil, err
}
if resp.StatusCode != http.StatusOK {
return nil, fmt.Errorf("API call failed: %s - %s", resp.Status, string(body))
}
var response MessageResponse
if err := json.Unmarshal(body, &response); err != nil {
return nil, err
}
return &response, nil
}
func getChatHistory(chatID string) (*ChatHistory, error) {
token, err := ensureValidToken()
if err != nil {
return nil, err
}
params := url.Values{}
params.Add("chat_id", chatID)
requestURL := fmt.Sprintf("%s?%s", chatURL, params.Encode())
req, err := http.NewRequest("GET", requestURL, nil)
if err != nil {
return nil, err
}
req.Header.Add("Authorization", "Bearer "+token)
req.Header.Add("Content-Type", "application/json")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
return nil, err
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return nil, err
}
if resp.StatusCode != http.StatusOK {
return nil, fmt.Errorf("API call failed: %s - %s", resp.Status, string(body))
}
var history ChatHistory
if err := json.Unmarshal(body, &history); err != nil {
return nil, err
}
return &history, nil
}
func main() {
// Start with a deep, meaningful question
initialQuestion := "How can I find meaning and purpose when facing life's greatest challenges?"
fmt.Println("=== Starting New Chat Session ===")
fmt.Printf("Question: %s\n\n", initialQuestion)
// Create new chat session
chatResponse, err := sendMessage(initialQuestion, "")
if err != nil {
fmt.Printf("Error creating chat: %v\n", err)
return
}
chatID := chatResponse.ChatID
fmt.Println("AI Response:")
fmt.Printf("%s\n\n", chatResponse.Message)
// Continue with follow-up questions
followUpQuestions := []string{
"Can you give me practical steps I can take today to begin this journey?",
"How do I maintain hope when circumstances seem overwhelming?",
"What role does community play in finding purpose?",
}
for i, question := range followUpQuestions {
fmt.Printf("=== Follow-up Question %d ===\n", i+1)
fmt.Printf("Question: %s\n\n", question)
// Send follow-up message
followUpResponse, err := sendMessage(question, chatID)
if err != nil {
fmt.Printf("Error sending follow-up: %v\n", err)
continue
}
fmt.Println("AI Response:")
fmt.Printf("%s\n\n", followUpResponse.Message)
}
// Display final chat history
fmt.Println("=== Complete Chat History ===")
chatHistory, err := getChatHistory(chatID)
if err != nil {
fmt.Printf("Error getting chat history: %v\n", err)
return
}
for _, message := range chatHistory.Messages {
role := strings.ToUpper(message.Role)
content := message.Message
fmt.Printf("%s: %s\n\n", role, content)
}
fmt.Println("Chat session completed successfully!")
}
import com.google.gson.Gson;
import java.io.IOException;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.time.Instant;
import java.util.Arrays;
import java.util.Base64;
import java.util.List;
/**
* Complete Chat Example - Java
* Demonstrates creating a chat session and continuing the conversation.
*/
public class ChatExample {
// Configuration
private static final String CLIENT_ID = System.getenv().getOrDefault("GLOO_CLIENT_ID", "YOUR_CLIENT_ID");
private static final String CLIENT_SECRET = System.getenv().getOrDefault("GLOO_CLIENT_SECRET", "YOUR_CLIENT_SECRET");
private static final String TOKEN_URL = "https://platform.ai.gloo.com/oauth2/token";
private static final String MESSAGE_API_URL = "https://platform.ai.gloo.com/ai/v1/message";
private static final String CHAT_API_URL = "https://platform.ai.gloo.com/ai/v1/chat";
// HTTP client and JSON parser
private static final HttpClient httpClient = HttpClient.newHttpClient();
private static final Gson gson = new Gson();
// Global token storage
private static TokenInfo tokenInfo;
// Data classes
public static class TokenInfo {
public String access_token;
public int expires_in;
public long expires_at;
public String token_type;
}
public static class MessageRequest {
public String query;
public Integer character_limit;
public Integer sources_limit;
public Boolean stream;
public List<String> publishers;
public String chat_id;
}
public static class MessageResponse {
public String chat_id;
public String query_id;
public String message_id;
public String message;
public String timestamp;
public Boolean success;
public List<String> suggestions;
public List<Object> sources;
}
public static class ChatMessage {
public String query_id;
public String message_id;
public String timestamp;
public String role;
public String message;
public Integer character_limit;
}
public static class ChatHistory {
public String chat_id;
public String created_at;
public List<ChatMessage> messages;
}
// Authentication methods
private static TokenInfo getAccessToken() throws IOException, InterruptedException {
String auth = CLIENT_ID + ":" + CLIENT_SECRET;
String encodedAuth = Base64.getEncoder().encodeToString(auth.getBytes());
String requestBody = "grant_type=client_credentials&scope=api/access";
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(TOKEN_URL))
.header("Content-Type", "application/x-www-form-urlencoded")
.header("Authorization", "Basic " + encodedAuth)
.POST(HttpRequest.BodyPublishers.ofString(requestBody))
.build();
HttpResponse<String> response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
if (response.statusCode() != 200) {
throw new IOException("Failed to get access token: " + response.body());
}
TokenInfo token = gson.fromJson(response.body(), TokenInfo.class);
token.expires_at = Instant.now().getEpochSecond() + token.expires_in;
return token;
}
private static boolean isTokenExpired(TokenInfo token) {
if (token == null || token.expires_at == 0) {
return true;
}
return Instant.now().getEpochSecond() > (token.expires_at - 60);
}
private static String ensureValidToken() throws IOException, InterruptedException {
if (isTokenExpired(tokenInfo)) {
System.out.println("Getting new access token...");
tokenInfo = getAccessToken();
}
return tokenInfo.access_token;
}
// Chat methods
private static MessageResponse sendMessage(String messageText, String chatId) throws IOException, InterruptedException {
String token = ensureValidToken();
MessageRequest payload = new MessageRequest();
payload.query = messageText;
payload.character_limit = 1000;
payload.sources_limit = 5;
payload.stream = false;
payload.publishers = List.of();
payload.chat_id = chatId;
String jsonPayload = gson.toJson(payload);
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(MESSAGE_API_URL))
.header("Content-Type", "application/json")
.header("Authorization", "Bearer " + token)
.POST(HttpRequest.BodyPublishers.ofString(jsonPayload))
.build();
HttpResponse<String> response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
if (response.statusCode() != 200) {
throw new IOException("API call failed: " + response.body());
}
return gson.fromJson(response.body(), MessageResponse.class);
}
private static ChatHistory getChatHistory(String chatId) throws IOException, InterruptedException {
String token = ensureValidToken();
String url = CHAT_API_URL + "?chat_id=" + chatId;
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(url))
.header("Authorization", "Bearer " + token)
.header("Content-Type", "application/json")
.GET()
.build();
HttpResponse<String> response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
if (response.statusCode() != 200) {
throw new IOException("API call failed: " + response.body());
}
return gson.fromJson(response.body(), ChatHistory.class);
}
// Main method
public static void main(String[] args) {
try {
// Start with a deep, meaningful question
String initialQuestion = "How can I find meaning and purpose when facing life's greatest challenges?";
System.out.println("=== Starting New Chat Session ===");
System.out.println("Question: " + initialQuestion);
System.out.println();
// Create new chat session
MessageResponse chatResponse = sendMessage(initialQuestion, null);
String chatId = chatResponse.chat_id;
System.out.println("AI Response:");
System.out.println(chatResponse.message);
System.out.println();
// Show suggested follow-up questions
List<String> suggestions = chatResponse.getSuggestions();
if (suggestions != null && !suggestions.isEmpty()) {
System.out.println("Suggested follow-up questions:");
for (int i = 0; i < suggestions.size(); i++) {
System.out.println((i + 1) + ". " + suggestions.get(i));
}
System.out.println();
}
// Use the first suggested question for follow-up, or fallback
String followUpQuestion = (suggestions != null && !suggestions.isEmpty())
? suggestions.get(0)
: "Can you give me practical steps I can take today to begin this journey?";
System.out.println("=== Continuing the Conversation ===");
System.out.println("Using suggested question: " + followUpQuestion);
System.out.println();
// Send follow-up message
MessageResponse followUpResponse = sendMessage(followUpQuestion, chatId);
System.out.println("AI Response:");
System.out.println(followUpResponse.getMessage());
System.out.println();
// Display final chat history
System.out.println("=== Complete Chat History ===");
ChatHistory chatHistory = getChatHistory(chatId);
for (ChatMessage message : chatHistory.messages) {
String role = message.role.toUpperCase();
String content = message.message;
System.out.println(role + ": " + content);
System.out.println();
}
System.out.println("Chat session completed successfully!");
} catch (Exception e) {
System.err.println("Error: " + e.getMessage());
e.printStackTrace();
}
}
}
Error Handling Best Practices
When working with the Message API, implement proper error handling for common scenarios:Authentication Errors
- 401 Unauthorized: Token expired or invalid
- 403 Forbidden: Insufficient permissions
Request Errors
- 400 Bad Request: Invalid request parameters
- 422 Unprocessable Entity: Validation errors
Rate Limiting
- 429 Too Many Requests: Implement backoff strategies
Network Issues
- Connection timeouts: Implement retry logic
- Network failures: Handle gracefully with user feedback
Advanced Features
Streaming Responses
Setstream: true in your request for real-time response streaming:
{
"query": "Tell me about hope in difficult times",
"stream": true,
"chat_id": "your-chat-id"
}
Publisher Filtering
Restrict responses to specific content publishers:{
"query": "What does Scripture say about finding purpose?",
"publishers": ["Bible", "Christian Literature"],
"chat_id": "your-chat-id"
}
Response Customization
Control response length and source count:{
"query": "How can I grow spiritually?",
"character_limit": 500,
"sources_limit": 3,
"chat_id": "your-chat-id"
}
Working Code Sample
View Complete Code
Clone or browse the complete working examples for all 6 languages (JavaScript,
TypeScript, Python, PHP, Go, Java) with setup instructions.
Next Steps
Now that you understand the Message API, consider exploring:- Authentication Tutorial - For detailed authentication setup
- Messages API - For additional API information
- Completions Tutorial - For stateless chat interactions
- Tool Use - For enhanced AI capabilities

