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:

  1. Authenticated with the API β€” Follow the API Introduction guide to get your accessToken and workspaceId

  2. Configured your GraphQL client β€” Set up Apollo Client with proper authentication headers

  3. Created or have a session ID β€” Use the starterSessionId from 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 starterSessionId

Step-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:

Parameter

Type

Required

Description

message

string

Yes

The message text (max 5000 characters)

sessionId

number

Yes

The session ID

isForAiReply

boolean

No

Set to true to get an AI response (default: false)

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.