https://calvinistparrot.com/api/parrot-chat
The Parrot Chat endpoint provides real-time conversational interactions by streaming responses. It handles creating chat sessions, processing user messages, maintaining context, and integrating multiple theological agents including a final review stage ("Calvin's Review").
Important: The API now includes an intelligent memory extraction system that learns from conversations to provide personalized pastoral care. The userId is required for this feature to work properly—it enables the system to build a profile of each user's spiritual journey, theological questions, and ministry context over time.
As with the Parrot QA API, the Parrot Chat endpoint supports multiple denominational modes to cater to various theological traditions. However, we will not compromise on the following essential doctrines:
For simplicity, I created this other endpoint that focuses on quick QA. Please check the Parrot QA API documentation for more information.
Chat Session Initialization
Chat Continuation
Memory Extraction & Personalization
userId and never exposed to other usersDenomination Handling
The userId parameter enables:
Without a userId, the system cannot learn or personalize—each conversation becomes isolated and generic.## API Reference
Send a JSON payload with these possible fields:
The API streams different event types as JSON objects:
{"type": "progress", "title": "Looking for articles", "content": "Searching for: predestination"}
{"type": "parrot", "content": "The doctrine of predestination..."}
{"type": "tool_progress", "toolName": "supplementalArticleSearch", "message": "Searching for articles on predestination..."}
{"type": "tool_summary", "toolName": "supplementalArticleSearch", "content": "Found 3 relevant articles..."}
{"type": "gotQuestions", "content": "- [What is predestination?](https://www.gotquestions.org/predestination.html) _(GotQuestions)_"}
{"type": "CCEL", "content": "- [Calvin's Institutes, Book III](https://ccel.org/...)"}
{"type": "conversationNameUpdated", "chatId": "chat123", "name": "Understanding Predestination"}
{"type": "done"}
After the response stream completes, the system automatically extracts and updates user memories in a background process (non-blocking). This includes:
Extracted Information:
How it Works:
Developer Notes:
userId onlyPOST /api/parrot-chat { "userId": "user123", "initialQuestion": "What is predestination?", "initialAnswer": "Predestination refers to...", "denomination": "reformed-baptist" }
POST /api/parrot-chat { "userId": "user123", "initialQuestion": "What is predestination?" }
Response:
{ "chatId": "chat123" }
Note: This endpoint only returns the chatId. The client should navigate to a new URL with this chatId (e.g.,
/chat123). When the chat page loads, it will automatically trigger the streaming process using theisAutoTriggerflag to process the initial question.
// In /page.tsx const handleStartNewChat = async () => { const response = await fetch('/api/parrot-chat', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ userId: "user123", initialQuestion: "What is predestination?" }), }); const { chatId } = await response.json(); router.push(`/${chatId}`); // Navigate to chat page };
// In /[chatId]/page.tsx useEffect(() => { // When we detect only a user message with no response yet if (messages.length === 1 && messages[0].sender === "user" && !autoSentRef.current) { autoSentRef.current = true; // Auto-trigger the API call with the isAutoTrigger flag handleSendMessage({ message: messages[0].content, isAutoTrigger: true }); } }, [messages, handleSendMessage]); // Actual API call with isAutoTrigger flag const handleSendMessage = async ({ message, isAutoTrigger }) => { const response = await fetch("/api/parrot-chat", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ chatId: "chat123", // From URL params message: "What is predestination?", // Initial question isAutoTrigger: true // This tells the API not to store the message again }), }); // Handle streaming response... };
isAutoTrigger: true, the API doesn't save the message again (it's already stored)POST /api/parrot-chat { "userId": "user123", "chatId": "chat123", "message": "How does it relate to free will?" }
GET /api/parrot-chat?chatId=chat123
Response:
{ "chat": { "id": "cm7p6rik1001emqp0slgxgu1j", "userId": "6754db6b00119ba9e0da", "conversationName": "Understanding Predestination", "denomination": "reformed-baptist", "createdAt": "2025-02-28T19:48:22.321Z", "modifiedAt": "2025-02-28T19:48:45.855Z" }, "messages": [ { "id": "cm7p6rimi001gmqp0liuisq27", "chatId": "cm7p6rik1001emqp0slgxgu1j", "sender": "user", "content": "What is predestination?", "timestamp": "2025-02-28T19:48:22.410Z" }, { "id": "cm7p6rqc0001imqp0h9gywt2x", "chatId": "cm7p6rik1001emqp0slgxgu1j", "sender": "tool_summary", "toolName": "supplementalArticleSearch", "content": "Found 3 relevant theological articles on predestination from trusted sources.", "timestamp": "2025-02-28T19:48:30.401Z" }, { "id": "cm7p6rqd0001jmqp0abc12345", "chatId": "cm7p6rik1001emqp0slgxgu1j", "sender": "gotQuestions", "content": "- [Providence and Predestination - Monergism](https://www.monergism.com/reformation-theology/blog/providence-and-predestination) _(Monergism)_\n- [What is predestination? - GotQuestions.org](https://www.gotquestions.org/predestination.html) _(GotQuestions)_\n- [What is Predestination? - Monergism](https://www.monergism.com/what-predestination) _(Monergism)_", "timestamp": "2025-02-28T19:48:32.401Z" }, { "id": "cm7p6rxq0001kmqp0kdxt3qvt", "chatId": "cm7p6rik1001emqp0slgxgu1j", "sender": "CCEL", "content": "- [Calvin's Institutes, Book III, Chapter 21](https://ccel.org/ccel/calvin/institutes/institutes.v.xxii.html) - On Eternal Election", "timestamp": "2025-02-28T19:48:41.938Z" }, { "id": "cm7p6rzqs001mmqp0jrawhfi1", "chatId": "cm7p6rik1001emqp0slgxgu1j", "sender": "parrot", "content": "Predestination is...", "timestamp": "2025-02-28T19:48:44.596Z" } ] }
Note: The
tool_summarymessages include atoolNamefield that is parsed from the stored JSON content. This allows the frontend to display tool-specific UI components.
const handleStream = async (chatId: string, message: string) => { const response = await fetch('/api/parrot-chat', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ chatId, message }) }); const reader = response.body.getReader(); const decoder = new TextDecoder(); while (true) { const { value, done } = await reader.read(); if (done) break; const lines = decoder.decode(value).split('\n'); for (const line of lines) { if (!line.trim()) continue; const event = JSON.parse(line); switch (event.type) { case 'progress': updateProgress(event.title, event.content); break; case 'parrot': appendParrotMessage(event.content); break; case 'tool_progress': // Ephemeral - show but don't persist showToolProgress(event.toolName, event.message); break; case 'tool_summary': // Persistent - show and will be in chat history showToolSummary(event.toolName, event.content); break; case 'gotQuestions': showReferences(event.content); break; case 'CCEL': showCCELReferences(event.content); break; case 'conversationNameUpdated': // Update sidebar with new conversation name updateSidebarChatName(event.chatId, event.name); break; case 'done': finishStream(); break; } } } };
For complete implementation examples, see:
The endpoint supports the following denomination:
Each mode tailors its responses according to distinct theological perspectives on secondary issues while sharing a common foundation on core doctrines.
This work is part of the Calvinist Parrot Ministries, we exist to glorify God by creating and freely distributing AI tools that proclaim the Gospel, strengthen the Church, and equip believers across the globe.
For further questions or support, please reach out!
This is open source, so if you're interested in helping me development this, check out the GitHub repo.
