API Documentation: Parrot Chat Endpoint

Endpoint URL

https://calvinistparrot.com/api/parrot-chat

Overview

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:

QA Endpoint

For simplicity, I created this other endpoint that focuses on quick QA. Please check the Parrot QA API documentation for more information.


How It Works

  1. Chat Session Initialization
    There are two ways to start a new chat:

    • From Parrot QA: Initialize with both question and answer
    • From Chat Interface: Initialize with just a question
  2. Chat Continuation

    • Uses stored chat history to maintain context
    • Processes messages through multiple agents and tools
    • Streams real-time responses with progress updates
  3. Memory Extraction & Personalization 🧠

    • Automatic Learning: After each conversation, the system extracts and updates user memories in the background
    • Pastoral Context: Builds a profile including spiritual maturity, ministry context, theological preferences, and question history
    • Smart Responses: Future conversations are informed by this context for more personalized, pastorally-appropriate answers
    • Privacy: Memory data is tied to userId and never exposed to other users
    • No Interruption: Memory extraction happens asynchronously and doesn't block responses
  4. Denomination Handling

    • User's denomination preference is stored in their profile and automatically applied
    • Each denomination maps to a specific system prompt
    • Affects how the AI interprets and responds to questions
    • Maintains core doctrinal consistency while respecting denominational distinctives

Why userId is Critical

The userId parameter enables:

Without a userId, the system cannot learn or personalize—each conversation becomes isolated and generic.## API Reference

Request Structure

Send a JSON payload with these possible fields:

Response Stream Format

The API streams different event types as JSON objects:

  1. Progress Updates - Status messages during processing
{"type": "progress", "title": "Looking for articles", "content": "Searching for: predestination"}
  1. Parrot Messages - Main response content (streamed in chunks)
{"type": "parrot", "content": "The doctrine of predestination..."}
  1. Calvin's Review - Theological review feedback
{"type": "calvin", "content": "This explanation aligns with Reformed theology..."}
  1. Reference Materials - Related articles and resources
{"type": "gotQuestions", "content": "* [What is predestination?](https://www.gotquestions.org/predestination.html)"}
  1. Stream Completion
{"type": "done"}

Memory Extraction (Background Process)

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:

  1. After Parrot's response is sent, the conversation history is analyzed
  2. An LLM extracts structured insights using a JSON schema
  3. Memories are stored in a LangGraph MemoryStore (key-value pairs)
  4. User profile counters are updated (question types, Gospel presentations)
  5. Future conversations inject this context into the system prompt for personalized responses

Developer Notes:

Usage Patterns

1. Initialize from Parrot QA

POST /api/parrot-chat
{
  "userId": "user123",
  "initialQuestion": "What is predestination?",
  "initialAnswer": "Predestination refers to...",
  "denomination": "reformed-baptist"
}

2. Initialize from Chat Interface

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 the isAutoTrigger flag to process the initial question.

Complete Flow Example

  1. Start a new chat and get the chatId:
// 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
};
  1. Chat page loads and auto-triggers the initial question:
// 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...
};
  1. API processes the request differently with isAutoTrigger:

3. Continue Conversation

POST /api/parrot-chat
{
  "userId": "user123",
  "chatId": "chat123",
  "message": "How does it relate to free will?"
}

4. Fetch Chat History

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": "gotQuestions",
    "content": "* [Providence and Predestination - Monergism](https://www.monergism.com/reformation-theology/blog/providence-and-predestination)\n* [What is predestination? - GotQuestions.org](https://www.gotquestions.org/predestination.html)\n* [Predestination and the Work of Jesus Considered | Monergism](https://www.monergism.com/predestination-and-work-jesus-considered)\n* [What is Predestination? - Monergism](https://www.monergism.com/what-predestination)\n* [What does the Bible say about predestination vs. free will?](https://www.gotquestions.org/predestination-vs-free-will.html)",
    "timestamp": "2025-02-28T19:48:32.401Z"
   },
   {
    "id": "cm7p6rxq0001kmqp0kdxt3qvt",
    "chatId": "cm7p6rik1001emqp0slgxgu1j",
    "sender": "calvin",
    "content": "Your summary of predestination captures...",
    "timestamp": "2025-02-28T19:48:41.938Z"
   },
   {
    "id": "cm7p6rzqs001mmqp0jrawhfi1",
    "chatId": "cm7p6rik1001emqp0slgxgu1j",
    "sender": "parrot",
    "content": "Predestination is...",
    "timestamp": "2025-02-28T19:48:44.596Z"
   }
  ]
}

Implementation Guide

Front-end Integration Example

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 'calvin':
       showCalvinReview(event.content);
       break;
      case 'gotQuestions':
       showReferences(event.content);
       break;
      case 'done':
       finishStream();
       break;
    }
   }
  }
};

For complete implementation examples, see:


Denominations

The endpoint supports the following denomination:

  1. Reformed Baptist (default)
  2. Presbyterian
  3. Wesleyan
  4. Lutheran
  5. Anglican
  6. Pentecostal/Charismatic
  7. Non-Denominational Evangelical

Each mode tailors its responses according to distinct theological perspectives on secondary issues while sharing a common foundation on core doctrines.

Reformed Baptist


Calvinist Parrot Ministries

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.

Contact

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.

Freely you have received; freely give.

Soli Deo Gloria

Calvinist Parrot