Skip to main content

Overview

Retrieves the message history for a specific chat session. Returns paginated results with message content, timestamps, and token counts. Authentication: Authorization: Bearer {session_token} Use Cases:
  • Page refresh (restore chat state)
  • Resuming abandoned sessions
  • Exporting conversation history
  • Displaying chat history in UI

Request

Path Parameters:
ParameterTypeRequiredDescription
conversation_idstringSession ID from create session response
Headers:
Authorization: Bearer {session_token}
Query Parameters:
ParameterTypeRequiredDefaultDescription
limitnumber50Max messages to return (max: 100)
offsetnumber0Skip this many messages
Example:
GET /v1/chat/sessions/chat_abc123_user_1705312800000/messages?limit=20&offset=0

Response

Status: 200 OK
{
  "messages": [
    {
      "role": "assistant",
      "content": "Hello! How can I help you today?",
      "timestamp": "2024-01-15T10:00:00+00:00",
      "token_count": null
    },
    {
      "role": "user",
      "content": "What services do you offer?",
      "timestamp": "2024-01-15T10:00:05+00:00",
      "token_count": null
    },
    {
      "role": "assistant",
      "content": "We offer a wide range of services including...",
      "timestamp": "2024-01-15T10:00:06+00:00",
      "token_count": 45
    },
    {
      "role": "user",
      "content": "What are your pricing plans?",
      "timestamp": "2024-01-15T10:00:15+00:00",
      "token_count": null
    },
    {
      "role": "assistant",
      "content": "Our pricing plans are as follows...",
      "timestamp": "2024-01-15T10:00:16+00:00",
      "token_count": 120
    }
  ],
  "count": 5
}

Response Fields

FieldTypeDescription
messagesarrayList of message objects
messages[].rolestringuser or assistant
messages[].contentstringMessage text content
messages[].timestampstringISO 8601 datetime
messages[].token_countnumberToken count (assistant messages only)
countnumberTotal messages returned

Pagination

Default Behavior

  • Limit: 50 messages (default)
  • Offset: 0 (start from beginning)
  • Maximum: 100 messages per request

Paginating Large Histories

// Get first page
const page1 = await fetch(
  `/v1/chat/sessions/${conversationId}/messages?limit=50&offset=0`,
  { headers: { Authorization: `Bearer ${token}` } }
);

// Get second page
const page2 = await fetch(
  `/v1/chat/sessions/${conversationId}/messages?limit=50&offset=50`,
  { headers: { Authorization: `Bearer ${token}` } }
);

Getting Last N Messages

// Get last 20 messages (reverse order in UI)
const response = await fetch(
  `/v1/chat/sessions/${conversationId}/messages?limit=20&offset=9999`,
  { headers: { Authorization: `Bearer ${token}` } }
);

Error Responses

401 Unauthorized

{
  "detail": "Invalid token"
}

403 Forbidden

{
  "detail": "Conversation ID does not match session token"
}

404 Not Found

{
  "detail": "Session not found or expired"
}

Examples

cURL

curl -X GET "https://api.talkifai.dev/v1/chat/sessions/chat_abc123/messages?limit=20" \
  -H "Authorization: Bearer eyJhbGc..."

JavaScript (Fetch)

async function getMessageHistory(conversationId, token, limit = 50, offset = 0) {
  const url = new URL(
    `https://api.talkifai.dev/v1/chat/sessions/${conversationId}/messages`
  );
  url.searchParams.set('limit', limit);
  url.searchParams.set('offset', offset);

  const response = await fetch(url, {
    headers: {
      'Authorization': `Bearer ${token}`
    }
  });

  if (!response.ok) {
    const error = await response.json();
    throw new Error(error.detail || 'Failed to fetch history');
  }

  return response.json();
}

// Usage
const history = await getMessageHistory(conversationId, sessionToken);
console.log(`${history.count} messages loaded`);

React (Load on Mount)

function ChatWindow({ conversationId, sessionToken }) {
  const [messages, setMessages] = useState([]);
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    async function loadHistory() {
      try {
        const response = await fetch(
          `/v1/chat/sessions/${conversationId}/messages?limit=50`,
          {
            headers: {
              'Authorization': `Bearer ${sessionToken}`
            }
          }
        );

        const data = await response.json();
        setMessages(data.messages);
      } catch (error) {
        console.error('Failed to load history:', error);
      } finally {
        setLoading(false);
      }
    }

    loadHistory();
  }, [conversationId, sessionToken]);

  if (loading) return <div>Loading chat history...</div>;

  return (
    <div>
      {messages.map((msg, i) => (
        <div key={i} className={`message ${msg.role}`}>
          {msg.content}
        </div>
      ))}
    </div>
  );
}

Next.js (Server Component)

async function ChatHistory({ conversationId, sessionToken }) {
  const response = await fetch(
    `${process.env.TALKIFAI_API_URL}/v1/chat/sessions/${conversationId}/messages?limit=50`,
    {
      headers: {
        'Authorization': `Bearer ${sessionToken}`
      },
      cache: 'no-store'
    }
  );

  const data = await response.json();

  return (
    <div className="chat-history">
      {data.messages.map((msg, i) => (
        <Message key={i} role={msg.role} content={msg.content} />
      ))}
    </div>
  );
}

Use Cases

1. Restore Chat After Page Refresh

// On page load
useEffect(() => {
  const savedConversationId = sessionStorage.getItem('conversation_id');
  const savedToken = sessionStorage.getItem('session_token');

  if (savedConversationId && savedToken) {
    loadHistory(savedConversationId, savedToken);
  }
}, []);

2. Export Conversation

async function exportConversation(conversationId, token) {
  const history = await getMessageHistory(conversationId, token, 1000);
  
  const text = history.messages.map(msg => 
    `${msg.role.toUpperCase()}: ${msg.content}`
  ).join('\n\n');
  
  // Download as text file
  const blob = new Blob([text], { type: 'text/plain' });
  const url = URL.createObjectURL(blob);
  const a = document.createElement('a');
  a.href = url;
  a.download = `chat-${conversationId}.txt`;
  a.click();
}

3. Infinite Scroll History

function ChatWithScroll({ conversationId, token }) {
  const [messages, setMessages] = useState([]);
  const [offset, setOffset] = useState(0);
  const [hasMore, setHasMore] = useState(true);

  const loadMore = async () => {
    const data = await getMessageHistory(conversationId, token, 50, offset);
    
    if (data.count < 50) {
      setHasMore(false);
    }
    
    setMessages(prev => [...data.messages, ...prev]);
    setOffset(prev => prev + 50);
  };

  return (
    <div onScroll={handleScroll}>
      {hasMore && <button onClick={loadMore}>Load Earlier</button>}
      {messages.map(msg => <Message {...msg} />)}
    </div>
  );
}

Best Practices

1. Cache History Locally

// Store in localStorage for offline viewing
localStorage.setItem(`chat_${conversationId}`, JSON.stringify(messages));

// Load from cache first
const cached = localStorage.getItem(`chat_${conversationId}`);
if (cached) {
  setMessages(JSON.parse(cached));
}

2. Limit Initial Load

// Load only last 20 messages initially
const response = await fetch(
  `/v1/chat/sessions/${conversationId}/messages?limit=20&offset=9999`
);

// Load full history on demand

3. Handle Session Expiry

try {
  const history = await getMessageHistory(conversationId, token);
} catch (error) {
  if (error.message.includes('expired') || error.message.includes('not found')) {
    // Session expired - create new session
    await startNewSession();
  }
}

4. Preserve Scroll Position

const messageListRef = useRef(null);

useEffect(() => {
  if (messageListRef.current) {
    // Scroll to bottom after loading
    messageListRef.current.scrollTop = messageListRef.current.scrollHeight;
  }
}, [messages]);


Next Steps

Send Message

Continue the conversation with SSE streaming.

End Session

Properly end session to trigger cleanup.