The workflow JSON
Copy or download the full n8n JSON below. Paste it into a new n8n workflow, add your credentials, activate. Full import guide →
{
"name": "ZEP Memory",
"nodes": [
{
"parameters": {
"promptType": "define",
"text": "={{ $json.message.text }}",
"options": {}
},
"type": "@n8n/n8n-nodes-langchain.agent",
"typeVersion": 2,
"position": [
220,
-560
],
"id": "541507eb-abde-478e-9960-567439f41475",
"name": "AI Agent"
},
{
"parameters": {
"updates": [
"message"
],
"additionalFields": {}
},
"type": "n8n-nodes-base.telegramTrigger",
"typeVersion": 1.2,
"position": [
0,
-560
],
"id": "210ce106-4b4e-40e6-9aff-abd151a33dd6",
"name": "Telegram Trigger",
"credentials": {
"telegramApi": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"chatId": "={{ $('Telegram Trigger').item.json.message.chat.id }}",
"text": "={{ $json.output }}",
"additionalFields": {
"appendAttribution": false
}
},
"type": "n8n-nodes-base.telegram",
"typeVersion": 1.2,
"position": [
580,
-560
],
"id": "03069cee-447d-41d3-95b1-d98f0445ad3c",
"name": "Send a text message",
"credentials": {
"telegramApi": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"updates": [
"message"
],
"additionalFields": {}
},
"type": "n8n-nodes-base.telegramTrigger",
"typeVersion": 1.2,
"position": [
-20,
0
],
"id": "58415b2c-bed0-447a-9009-c825668bfd94",
"name": "Telegram Trigger1",
"credentials": {
"telegramApi": {
"name": "<your credential>"
}
},
"disabled": true
},
{
"parameters": {
"chatId": "={{ $('Telegram Trigger1').item.json.message.chat.id }}",
"text": "={{ $('AI Agent 2').item.json.output }}",
"additionalFields": {
"appendAttribution": false
}
},
"type": "n8n-nodes-base.telegram",
"typeVersion": 1.2,
"position": [
1140,
0
],
"id": "6c1bc09a-f627-4719-9304-8c28fef7c264",
"name": "Send a text message1",
"credentials": {
"telegramApi": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"jsCode": "// n8n Code Node\n// This code extracts all facts from the JSON structure\n\n// Get the input data\nconst items = $input.all();\nconst facts = [];\n\n// Process each item\nfor (const item of items) {\n try {\n // Parse the data string if it exists\n if (item.json.data) {\n const parsedData = JSON.parse(item.json.data);\n \n // Check if edges array exists\n if (parsedData.edges && Array.isArray(parsedData.edges)) {\n // Extract facts from each edge\n parsedData.edges.forEach(edge => {\n if (edge.fact) {\n facts.push(edge.fact);\n }\n });\n }\n }\n } catch (error) {\n // Handle parsing errors\n console.error('Error parsing data:', error);\n }\n}\n\n// Return all facts as an array in a single item\nreturn [{\n json: {\n facts: facts\n }\n}];"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
300,
80
],
"id": "5ef7ad9d-9fc9-49a9-b716-6abd508e67cc",
"name": "Code"
},
{
"parameters": {
"promptType": "define",
"text": "={{ $('Telegram Trigger1').item.json.message.text }}",
"options": {
"systemMessage": "=You are a helpful assistant.\n\nHere is some additional information about Nate:\n{{ $json.facts.join(\"\\n\") }}\n\n5 most recent interactions with Nate:\n{{ $json.conversations.join(\"\\n\\n\")}}"
}
},
"type": "@n8n/n8n-nodes-langchain.agent",
"typeVersion": 2,
"position": [
620,
0
],
"id": "4ce5948e-9f07-4ff4-82bc-f0a722ce7f51",
"name": "AI Agent 2"
},
{
"parameters": {
"url": "=https://api.getzep.com/api/v2/sessions/{{ $json.message.chat.id }}/messages",
"authentication": "predefinedCredentialType",
"nodeCredentialType": "zepApi",
"sendQuery": true,
"queryParameters": {
"parameters": [
{
"name": "limit",
"value": "10"
}
]
},
"options": {}
},
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
160,
-80
],
"id": "6e2c0c5e-304d-45b2-b946-83855db03a57",
"name": "Context Window",
"credentials": {
"zepApi": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"method": "POST",
"url": "https://api.getzep.com/api/v2/graph/search",
"authentication": "predefinedCredentialType",
"nodeCredentialType": "zepApi",
"sendBody": true,
"specifyBody": "json",
"jsonBody": "={\n \"user_id\": \"zep_c6b8b1f0611f69464c860b3ae885639e022d1c54b59ffe82d16faf9c08cc24b0\",\n \"query\": \"{{ $json.message.text }}\",\n \"scope\": \"edges\",\n \"limit\": 3,\n \"search_filters\": {\n \"min_relevance\": 0.7\n }\n}",
"options": {}
},
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
160,
80
],
"id": "4508f733-d001-499b-8828-11a191282a1b",
"name": "User Graph",
"credentials": {
"zepApi": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"jsCode": "// Loop through each item\nfor (const item of $input.all()) {\n // Parse the JSON data\n const jsonData = JSON.parse(item.json.data);\n const messages = jsonData.messages;\n \n // Array to store formatted message pairs\n const messagePairs = [];\n \n // Process messages in pairs (Human followed by AI)\n for (let i = 0; i < messages.length; i++) {\n const message = messages[i];\n \n // Look for Human messages\n if (message.role === \"Human\" && message.role_type === \"user\") {\n // Check if there's a corresponding AI response\n if (i + 1 < messages.length && messages[i + 1].role === \"AI\" && messages[i + 1].role_type === \"assistant\") {\n // Format the pair\n const pair = `Human: ${message.content}\\nAI: ${messages[i + 1].content}`;\n messagePairs.push(pair);\n \n // Skip the AI message in the next iteration since we've already processed it\n i++;\n } else {\n // If no AI response, just add the human message\n messagePairs.push(`Human: ${message.content}`);\n }\n } else if (message.role === \"AI\" && message.role_type === \"assistant\") {\n // Handle standalone AI messages (shouldn't happen in normal conversation flow)\n messagePairs.push(`AI: ${message.content}`);\n }\n }\n \n // Return all pairs as a single array\n return [{\n json: {\n conversations: messagePairs\n }\n }];\n}"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
300,
-80
],
"id": "8b7169e3-e930-49e4-8969-158a52247a81",
"name": "Code1"
},
{
"parameters": {
"mode": "combine",
"combineBy": "combineByPosition",
"options": {}
},
"type": "n8n-nodes-base.merge",
"typeVersion": 3.2,
"position": [
460,
0
],
"id": "ca50e57e-f1a8-447c-99e7-8db833bd7d9d",
"name": "Merge"
},
{
"parameters": {
"method": "POST",
"url": "=https://api.getzep.com/api/v2/sessions/{{ $('Telegram Trigger1').item.json.message.chat.id }}/memory",
"authentication": "predefinedCredentialType",
"nodeCredentialType": "zepApi",
"sendBody": true,
"specifyBody": "json",
"jsonBody": "={\n \"user_id\": \"zep_c6b8b1f0611f69464c860b3ae885639e022d1c54b59ffe82d16faf9c08cc24b0\",\n \"session_id\": \"{{ $('Telegram Trigger1').item.json.message.chat.id }}\",\n \"messages\": [\n {\n \"role_type\": \"user\",\n \"content\": \"{{ $('Telegram Trigger1').item.json.message.text }}\"\n },\n {\n \"role_type\": \"assistant\",\n \"content\": \"{{ $json.output.replace(/\\n/g, '').replace(/\"/g, '') }}\"\n }\n ]\n}",
"options": {}
},
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
940,
0
],
"id": "6aa1334a-b036-4c8f-943b-1bdb8293e5ec",
"name": "Add Memory",
"credentials": {
"zepApi": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"updates": [
"message"
],
"additionalFields": {}
},
"type": "n8n-nodes-base.telegramTrigger",
"typeVersion": 1.2,
"position": [
-20,
480
],
"id": "16f6bd19-c4b9-4480-89bb-e58583f5e78d",
"name": "Telegram Trigger2",
"credentials": {
"telegramApi": {
"name": "<your credential>"
}
},
"disabled": true
},
{
"parameters": {
"chatId": "={{ $('Telegram Trigger2').item.json.message.chat.id }}",
"text": "={{ $('AI Agent 3').item.json.output }}",
"additionalFields": {
"appendAttribution": false
}
},
"type": "n8n-nodes-base.telegram",
"typeVersion": 1.2,
"position": [
1000,
480
],
"id": "dd14c87f-9583-472f-86d3-5ff12ba4ec19",
"name": "Send a text message2",
"credentials": {
"telegramApi": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"jsCode": "// n8n Code Node\n// This code extracts all facts from the JSON structure\n\n// Get the input data\nconst items = $input.all();\nconst facts = [];\n\n// Process each item\nfor (const item of items) {\n try {\n // Parse the data string if it exists\n if (item.json.data) {\n const parsedData = JSON.parse(item.json.data);\n \n // Check if edges array exists\n if (parsedData.edges && Array.isArray(parsedData.edges)) {\n // Extract facts from each edge\n parsedData.edges.forEach(edge => {\n if (edge.fact) {\n facts.push(edge.fact);\n }\n });\n }\n }\n } catch (error) {\n // Handle parsing errors\n console.error('Error parsing data:', error);\n }\n}\n\n// Return all facts as an array in a single item\nreturn [{\n json: {\n facts: facts\n }\n}];"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
300,
480
],
"id": "609694f0-51d1-4e18-8a9c-b6283695136a",
"name": "Code2"
},
{
"parameters": {
"method": "POST",
"url": "https://api.getzep.com/api/v2/graph/search",
"authentication": "predefinedCredentialType",
"nodeCredentialType": "zepApi",
"sendBody": true,
"specifyBody": "json",
"jsonBody": "={\n \"user_id\": \"zep_c6b8b1f0611f69464c860b3ae885639e022d1c54b59ffe82d16faf9c08cc24b0\",\n \"query\": \"{{ $json.message.text }}\",\n \"scope\": \"edges\",\n \"limit\": 3,\n \"search_filters\": {\n \"min_relevance\": 0.7\n }\n}",
"options": {}
},
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
140,
480
],
"id": "53375e1f-a339-4da1-8afd-afead4487874",
"name": "User Graph1",
"credentials": {
"zepApi": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"sessionIdType": "customKey",
"sessionKey": "={{ $('Telegram Trigger2').item.json.message.chat.id }}"
},
"type": "@n8n/n8n-nodes-langchain.memoryPostgresChat",
"typeVersion": 1.3,
"position": [
580,
680
],
"id": "13e2b02b-7e35-4573-99e4-552cb939a82d",
"name": "Postgres Chat Memory",
"credentials": {
"postgres": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"content": "# Zep Memory\nContext & User Graph\n",
"height": 500,
"width": 940,
"color": 2
},
"type": "n8n-nodes-base.stickyNote",
"typeVersion": 1,
"position": [
-120,
-700
],
"id": "3c56fef7-8976-4268-a7c0-f36fd02928ce",
"name": "Sticky Note"
},
{
"parameters": {
"options": {}
},
"type": "@n8n/n8n-nodes-langchain.lmChatOpenRouter",
"typeVersion": 1,
"position": [
200,
-380
],
"id": "87aa689c-ce1e-4d94-8ecf-4beaaa742f08",
"name": "GPT 4.1 mini",
"credentials": {
"openRouterApi": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"options": {}
},
"type": "@n8n/n8n-nodes-langchain.lmChatOpenRouter",
"typeVersion": 1,
"position": [
600,
180
],
"id": "be8992db-c837-453a-b4b7-0a1830fc950e",
"name": "GPT 4.1 mini1",
"credentials": {
"openRouterApi": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"options": {}
},
"type": "@n8n/n8n-nodes-langchain.lmChatOpenRouter",
"typeVersion": 1,
"position": [
440,
680
],
"id": "06dc2089-155d-48f0-8188-a518c562a251",
"name": "GPT 4.1 mini2",
"credentials": {
"openRouterApi": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"promptType": "define",
"text": "={{ $('Telegram Trigger2').item.json.message.text }}",
"options": {
"systemMessage": "=You are a helpful assistant.\n\nHere is some additional information about Nate:\n{{ $json.facts.join(\"\\n\") }}"
}
},
"type": "@n8n/n8n-nodes-langchain.agent",
"typeVersion": 2,
"position": [
500,
480
],
"id": "04dc87f1-4a5d-41b4-ba84-6a09961094eb",
"name": "AI Agent 3"
},
{
"parameters": {
"content": "# Zep Memory (HTTP)\nContext & User Graph\n",
"height": 500,
"width": 1480,
"color": 5
},
"type": "n8n-nodes-base.stickyNote",
"typeVersion": 1,
"position": [
-120,
-180
],
"id": "bfcf0335-be1a-4f3a-ade8-2a07fe78c7cc",
"name": "Sticky Note1"
},
{
"parameters": {
"content": "# Zep & Postgres Hybrid\nContext & User Graph\n",
"height": 500,
"width": 1360,
"color": 4
},
"type": "n8n-nodes-base.stickyNote",
"typeVersion": 1,
"position": [
-120,
340
],
"id": "e73b68c0-ae8c-41d4-95e3-5ba58360fcca",
"name": "Sticky Note2"
},
{
"parameters": {
"sessionIdType": "customKey",
"sessionKey": "=1"
},
"type": "@n8n/n8n-nodes-langchain.memoryZep",
"typeVersion": 1.3,
"position": [
400,
-380
],
"id": "f8b87230-812e-421c-8bb4-3a3c12896964",
"name": "Zep",
"credentials": {
"zepApi": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"sessionIdType": "customKey",
"sessionKey": "={{ $('Telegram Trigger').item.json.message.chat.id }}"
},
"type": "@n8n/n8n-nodes-langchain.memoryBufferWindow",
"typeVersion": 1.3,
"position": [
940,
-380
],
"id": "fcdcdeba-4193-454f-8cef-38d5dba2e984",
"name": "Simple Memory"
},
{
"parameters": {
"method": "POST",
"url": "=https://api.getzep.com/api/v2/sessions/{{ $('Telegram Trigger2').item.json.message.chat.id }}/memory",
"authentication": "predefinedCredentialType",
"nodeCredentialType": "zepApi",
"sendBody": true,
"specifyBody": "json",
"jsonBody": "={\n \"user_id\": \"zep_c6b8b1f0611f69464c860b3ae885639e022d1c54b59ffe82d16faf9c08cc24b0\",\n \"session_id\": \"{{ $('Telegram Trigger2').item.json.message.chat.id }}\",\n \"messages\": [\n {\n \"role_type\": \"user\",\n \"content\": \"{{ $('Telegram Trigger2').item.json.message.text }}\"\n },\n {\n \"role_type\": \"assistant\",\n \"content\": \"{{ $json.output.replace(/\\n/g, '').replace(/\"/g, '') }}\"\n }\n ]\n}",
"options": {}
},
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
820,
480
],
"id": "7b0547f0-4f8d-4b93-9250-be3f39ec5b52",
"name": "Add Memory1",
"credentials": {
"zepApi": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"content": "# \ud83d\udee0\ufe0f Setup Guide \n**Author:** [Nate Herk](https://www.youtube.com/@nateherk)\n\nFollow the steps below to get this workflow up and running:\n\n### \u2705 Step 1: Set Up Your [ZEP](https://www.getzep.com/) Account \nHead to [ZEP](https://www.getzep.com/) and create a free account. This gives you access to your API key. \nOnce you have your key: \n- Plug it into the ZEP Memory Module in n8n. \n- You can also reuse this credential in HTTP Request nodes that call ZEP\u2019s API.\n\n### \u2705 Step 2: Connect a Chat Model \nHook up a chat model to your AI agents to power conversations. \nOptions include: \n- [OpenRouter](https://openrouter.ai/) \u2013 connect your OpenRouter API key. \n- Or use any other model provider of your choice.\n\n### \u2705 Step 3: Connect Telegram (Optional) \nWant to chat with your agents via Telegram? \n- Add your Telegram credentials in n8n so your agents can send/receive messages there.\n\n### \u2705 Step 4: Add Your Postgres Credential \nIn hybrid workflows that combine ZEP + Postgres, plug in your Postgres credentials. \n- This helps maintain a solid context window across memory systems.\n\n### \ud83d\udca1 Final Step: Start Testing & Exploring \n- Check token usage. \n- Explore your user graph in ZEP. \n- Fine-tune your agents. \n- Happy automating!\n",
"height": 780,
"width": 780
},
"type": "n8n-nodes-base.stickyNote",
"typeVersion": 1,
"position": [
-920,
-700
],
"id": "e46332bd-ddda-4c73-b0e6-d8a5faedda22",
"name": "Sticky Note3"
},
{
"parameters": {
"content": "## Ew... simple memory",
"height": 300,
"width": 300,
"color": 7
},
"type": "n8n-nodes-base.stickyNote",
"typeVersion": 1,
"position": [
840,
-500
],
"id": "1b8398c5-f2bd-476e-8cb7-2eac3f7285a3",
"name": "Sticky Note4"
}
],
"connections": {
"Telegram Trigger": {
"main": [
[
{
"node": "AI Agent",
"type": "main",
"index": 0
}
]
]
},
"AI Agent": {
"main": [
[
{
"node": "Send a text message",
"type": "main",
"index": 0
}
]
]
},
"Telegram Trigger1": {
"main": [
[
{
"node": "Context Window",
"type": "main",
"index": 0
},
{
"node": "User Graph",
"type": "main",
"index": 0
}
]
]
},
"Code": {
"main": [
[
{
"node": "Merge",
"type": "main",
"index": 1
}
]
]
},
"User Graph": {
"main": [
[
{
"node": "Code",
"type": "main",
"index": 0
}
]
]
},
"Context Window": {
"main": [
[
{
"node": "Code1",
"type": "main",
"index": 0
}
]
]
},
"Code1": {
"main": [
[
{
"node": "Merge",
"type": "main",
"index": 0
}
]
]
},
"Merge": {
"main": [
[
{
"node": "AI Agent 2",
"type": "main",
"index": 0
}
]
]
},
"AI Agent 2": {
"main": [
[
{
"node": "Add Memory",
"type": "main",
"index": 0
}
]
]
},
"Add Memory": {
"main": [
[
{
"node": "Send a text message1",
"type": "main",
"index": 0
}
]
]
},
"Telegram Trigger2": {
"main": [
[
{
"node": "User Graph1",
"type": "main",
"index": 0
}
]
]
},
"Code2": {
"main": [
[
{
"node": "AI Agent 3",
"type": "main",
"index": 0
}
]
]
},
"User Graph1": {
"main": [
[
{
"node": "Code2",
"type": "main",
"index": 0
}
]
]
},
"Postgres Chat Memory": {
"ai_memory": [
[
{
"node": "AI Agent 3",
"type": "ai_memory",
"index": 0
}
]
]
},
"GPT 4.1 mini": {
"ai_languageModel": [
[
{
"node": "AI Agent",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"GPT 4.1 mini1": {
"ai_languageModel": [
[
{
"node": "AI Agent 2",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"GPT 4.1 mini2": {
"ai_languageModel": [
[
{
"node": "AI Agent 3",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"AI Agent 3": {
"main": [
[
{
"node": "Add Memory1",
"type": "main",
"index": 0
}
]
]
},
"Zep": {
"ai_memory": [
[
{
"node": "AI Agent",
"type": "ai_memory",
"index": 0
}
]
]
},
"Simple Memory": {
"ai_memory": [
[]
]
},
"Add Memory1": {
"main": [
[
{
"node": "Send a text message2",
"type": "main",
"index": 0
}
]
]
}
},
"active": false,
"settings": {
"executionOrder": "v1"
},
"versionId": "e8c7f5bb-22d9-4b81-90d6-e18e413c4092",
"meta": {
"templateCredsSetupCompleted": true
},
"id": "GxMydqOT8W74wJW7",
"tags": []
}
Credentials you'll need
Each integration node will prompt for credentials when you import. We strip credential IDs before publishing — you'll add your own.
openRouterApipostgrestelegramApizepApi
About this workflow
ZEP Memory. Uses agent, telegramTrigger, telegram, httpRequest. Event-driven trigger; 29 nodes.
Source: https://github.com/Zie619/n8n-workflows — original creator credit. Request a take-down →