Chat API
Written By Stanislas
Last updated 18 days ago
Send messages to your AI agent and receive responses. Learn how to send messages with streaming, use synchronous requests, and integrate real-time chat into your application.
Overview
The Chat API allows you to send messages to your Swiftask agent and receive AI-generated responses. You can choose between streaming responses (character by character in real-time) or synchronous requests (wait for the complete response).
This guide covers how to send and receive messages. For real-time event subscriptions, see the Real-time subscriptions guide.
Prerequisites
Before sending messages, ensure you have:
Authenticated with the API β Follow the API Introduction guide to get your
accessTokenandworkspaceIdConfigured your GraphQL client β Set up Apollo Client with proper authentication headers
Created or have a session ID β Use the
starterSessionIdfrom authentication, or create a new session
Quick setup check
// You should have these from authentication
const accessToken = 'your_access_token';
const workspaceId = 'your_workspace_id';
const sessionId = 'your_session_id'; // or starterSessionIdStep-by-step guide
Step 1: Import GraphQL and Apollo Client
import { gql } from '@apollo/client'; Step 2: Send a message with streaming response
Send a message and trigger an AI response that streams back in real-time.
const SEND_MESSAGE = gql`
mutation SendNewMessage($newMessageData: NewMessageInput!) {
sendNewMessage(newMessageData: $newMessageData) {
id
message
createdAt
sessionId
isBotReply
}
}
`;
const sendMessage = async (client, sessionId, messageText) => {
const { data } = await client.mutate({
mutation: SEND_MESSAGE,
variables: {
newMessageData: {
message: messageText,
sessionId,
isForAiReply: true, // This triggers AI response
},
},
});
return data.sendNewMessage;
};
// Usage
const message = await sendMessage(client, 67890, 'What is your pricing?');
console.log('Message sent:', message.id);
Step 3: Listen to the streaming response
To see the AI's response as it streams in real-time, subscribe to message chunks. See the Real-time subscriptions guide for complete subscription setup.
const MESSAGE_STREAM = gql`
subscription OnMessageStream($sessionId: Float!) {
onMessageStream(sessionId: $sessionId) {
messageChunk
botResponseMessageId
isStoppable
}
}
`;
let fullMessage = '';
const subscription = client.subscribe({
query: MESSAGE_STREAM,
variables: { sessionId },
});
subscription.subscribe({
next: ({ data }) => {
fullMessage += data.onMessageStream.messageChunk;
console.log('Response:', fullMessage);
},
error: (error) => console.error(error),
complete: () => console.log('Response complete'),
});
Sending messages
Send a new message
Send a message to the session. Set isForAiReply: true to trigger an AI response.
GraphQL Mutation:
mutation SendNewMessage($newMessageData: NewMessageInput!) {
sendNewMessage(newMessageData: $newMessageData) {
id
message
createdAt
sessionId
isBotReply
}
}
Input parameters:
Example: Simple message without AI response
const message1 = await client.mutate({
mutation: SEND_MESSAGE,
variables: {
newMessageData: {
message: 'Just saving this note',
sessionId: 67890,
},
},
});
Example: Message that triggers AI response
const message2 = await client.mutate({
mutation: SEND_MESSAGE,
variables: {
newMessageData: {
message: 'What can you help me with?',
sessionId: 67890,
isForAiReply: true,
},
},
});
Synchronous requests
Send message and wait for complete response
For simple Q&A without streaming, use the synchronous endpoint. The API returns the complete response immediately instead of streaming it.
GraphQL Mutation:
mutation SyncBotRequest($newMessageData: NewMessageInput!) {
syncBotRequest(newMessageData: $newMessageData) {
text
botId
botSlug
isBotError
sessionId
sources
}
}
Example:
const SYNC_BOT_REQUEST = gql`
mutation SyncBotRequest($newMessageData: NewMessageInput!) {
syncBotRequest(newMessageData: $newMessageData) {
text
isBotError
sessionId
sources
}
}
`;
const syncMessage = async (client, sessionId, message) => {
const { data } = await client.mutate({
mutation: SYNC_BOT_REQUEST,
variables: {
newMessageData: {
message,
sessionId,
},
},
});
return data.syncBotRequest;
};
// Usage
const response = await syncMessage(client, 67890, 'What is 2 + 2?');
console.log('Bot response:', response.text);
console.log('Sources used:', response.sources);
When to use:
Simple Q&A without streaming needed
Batch processing of messages
When you need the complete response before proceeding
Practical use cases
Real-time chat UI
Build a chat interface where users see responses appear character by character.
const handleSendMessage = async (userInput) => {
// 1. Display user message immediately
displayMessage(userInput, 'user');
// 2. Send message to trigger AI response
await sendMessage(client, sessionId, userInput);
// 3. Subscribe to streaming (see Real-time subscriptions guide)
let fullResponse = '';
const subscription = client.subscribe({
query: MESSAGE_STREAM,
variables: { sessionId },
});
subscription.subscribe({
next: ({ data }) => {
fullResponse += data.onMessageStream.messageChunk;
displayMessage(fullResponse, 'bot', true); // isStreaming = true
},
complete: () => {
displayMessage(fullResponse, 'bot', false); // Mark as complete
},
});
};
Quick answers (no streaming)
Get instant answers for simple questions without waiting for streaming.
const handleQuickQuestion = async (question) => {
const response = await syncMessage(client, sessionId, question);
if (response.isBotError) {
showError('The bot encountered an error');
} else {
displayAnswer(response.text);
}
};
Multi-turn conversation
Send multiple messages in sequence and display all responses.
const conversation = [
'What is machine learning?',
'Can you explain it in simpler terms?',
'Give me a real-world example',
];
for (const message of conversation) {
const response = await syncMessage(client, sessionId, message);
displayMessage(message, 'user');
displayMessage(response.text, 'bot');
}
Tips & best practices
Always set isForAiReply: true when you want an AI response. Without it, the message is stored but no response is generated.
Use streaming for better UX. Streaming shows responses character by character, giving users immediate feedback. Use synchronous only for simple cases where you need the complete response before proceeding.
Validate input before sending. Check message length (max 5000 characters) and trim whitespace to avoid unnecessary API calls.
const validateMessage = (message) => {
if (!message || message.trim().length === 0) {
throw new Error('Message cannot be empty');
}
if (message.length > 5000) {
throw new Error('Message exceeds maximum length of 5000 characters');
}
return message.trim();
};
Handle errors gracefully. Always wrap mutations in try-catch blocks and show user-friendly error messages.
try {
const message = await sendMessage(client, sessionId, userInput);
displayMessage(message.message, 'user');
} catch (error) {
console.error('Error sending message:', error);
showErrorToUser('Failed to send message. Please try again.');
}
Keep session IDs organized. If your app supports multiple conversations, track session IDs clearly so users can switch between them.
Ready to send your first message? Use the step-by-step guide above to send a message and receive a response from your Swiftask agent.