This workflow follows the Documentdefaultdataloader → OpenAI Embeddings recipe pattern — see all workflows that pair these two integrations.
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 →
{
"_comment": "Workflow: NGO.tools KB Ingestion | n8n ID: D74o4IMPY9yNooJl | Webhook: /webhook/ngo-tools-ingest (POST)",
"name": "NGO.tools Knowledge Base Ingestion",
"nodes": [
{
"parameters": {
"httpMethod": "POST",
"path": "ngo-tools-ingest",
"options": {}
},
"id": "webhook-trigger-001",
"name": "Webhook Trigger",
"type": "n8n-nodes-base.webhook",
"typeVersion": 2,
"position": [
-112,
-16
]
},
{
"parameters": {
"mode": "runOnceForAllItems",
"jsCode": "// Extract documents from webhook body and prepare for Document Loader\nconst body = $input.first().json.body || $input.first().json;\nconst docs = body.documents || [];\nconst items = [];\n\nfor (const doc of docs) {\n const source = doc.route_uri || doc.source || doc.file_path || `manual:${doc.title || 'untitled'}`;\n \n items.push({\n json: {\n data: JSON.stringify({\n content: doc.content || '',\n title: doc.title || 'Untitled',\n source: source,\n doc_type: doc.doc_type || 'unknown',\n entity_name: doc.entity_name || ''\n }),\n metadata_title: doc.title || 'Untitled',\n metadata_source: source,\n metadata_doc_type: doc.doc_type || 'unknown',\n metadata_entity_name: doc.entity_name || '',\n metadata_ingested_at: new Date().toISOString()\n }\n });\n}\n\nreturn items;"
},
"id": "code-format-001",
"name": "Format Documents",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
160,
-16
]
},
{
"parameters": {
"operation": "executeQuery",
"query": "DELETE FROM n8n_vectors_ngo_tools WHERE metadata->>'source' = '{{ $json.metadata_source }}'"
},
"id": "delete-existing-001",
"name": "Delete Existing",
"type": "n8n-nodes-base.postgres",
"typeVersion": 2.5,
"position": [
400,
-200
],
"credentials": {
"postgres": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"amount": 1,
"unit": "seconds"
},
"id": "wait-for-delete-001",
"name": "Wait for Delete",
"type": "n8n-nodes-base.wait",
"typeVersion": 1.1,
"position": [
400,
-16
]
},
{
"parameters": {
"mode": "insert",
"tableName": "n8n_vectors_ngo_tools",
"options": {}
},
"id": "vectorstore-insert-001",
"name": "Store in PGVector",
"type": "@n8n/n8n-nodes-langchain.vectorStorePGVector",
"typeVersion": 1,
"position": [
640,
-16
],
"credentials": {
"postgres": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"options": {
"metadata": {
"metadataValues": [
{
"name": "title",
"value": "={{ $json.metadata_title }}"
},
{
"name": "source",
"value": "={{ $json.metadata_source }}"
},
{
"name": "doc_type",
"value": "={{ $json.metadata_doc_type }}"
},
{
"name": "entity_name",
"value": "={{ $json.metadata_entity_name }}"
},
{
"name": "ingested_at",
"value": "={{ $json.metadata_ingested_at }}"
}
]
}
}
},
"id": "doc-loader-001",
"name": "Default Data Loader",
"type": "@n8n/n8n-nodes-langchain.documentDefaultDataLoader",
"typeVersion": 1,
"position": [
440,
200
]
},
{
"parameters": {
"model": "text-embedding-3-small",
"options": {}
},
"id": "embedding-openai-001",
"name": "OpenAI Embeddings",
"type": "@n8n/n8n-nodes-langchain.embeddingsOpenAi",
"typeVersion": 1,
"position": [
640,
272
],
"credentials": {
"openAiApi": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"chunkSize": 1000,
"chunkOverlap": 200,
"options": {}
},
"id": "text-splitter-001",
"name": "Recursive Text Splitter",
"type": "@n8n/n8n-nodes-langchain.textSplitterRecursiveCharacterTextSplitter",
"typeVersion": 1,
"position": [
240,
320
]
}
],
"connections": {
"Webhook Trigger": {
"main": [
[
{
"node": "Format Documents",
"type": "main",
"index": 0
}
]
]
},
"Format Documents": {
"main": [
[
{
"node": "Delete Existing",
"type": "main",
"index": 0
},
{
"node": "Wait for Delete",
"type": "main",
"index": 0
}
]
]
},
"Wait for Delete": {
"main": [
[
{
"node": "Store in PGVector",
"type": "main",
"index": 0
}
]
]
},
"Default Data Loader": {
"ai_document": [
[
{
"node": "Store in PGVector",
"type": "ai_document",
"index": 0
}
]
]
},
"OpenAI Embeddings": {
"ai_embedding": [
[
{
"node": "Store in PGVector",
"type": "ai_embedding",
"index": 0
}
]
]
},
"Recursive Text Splitter": {
"ai_textSplitter": [
[
{
"node": "Default Data Loader",
"type": "ai_textSplitter",
"index": 0
}
]
]
}
},
"settings": {
"executionOrder": "v1"
},
"tags": [
{
"name": "NGO.tools"
},
{
"name": "Ingestion"
}
]
}
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.
openAiApipostgres
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
NGO.tools Knowledge Base Ingestion. Uses postgres, vectorStorePGVector, documentDefaultDataLoader, embeddingsOpenAi. Webhook trigger; 8 nodes.
Source: https://github.com/Zwiener-IT/ngo-tools-chatbot/blob/a05f863077e1313998c891adbe76dc3ba5834ad9/workflows/kb-ingestion.json — original creator credit. Request a take-down →
Related workflows
Workflows that share integrations, category, or trigger type with this one. All free to copy and import.
This workflow implements a complete Retrieval-Augmented Generation (RAG) system for document ingestion and intelligent querying.
Hi! I’m Amanda, a creator of intelligent automations using n8n and Make. I’ve been building AI-powered workflows for over 2 years, always focused on usability and innovation. This one here is very spe
HeyDinastia. Uses executeCommand, httpRequest, youTube, postgres. Webhook trigger; 66 nodes.
RAG AI Agent Template V5. Uses lmChatOpenAi, documentDefaultDataLoader, embeddingsOpenAi, googleDrive. Event-driven trigger; 56 nodes.
AI Multi-Document Analyzer with Smart Recommendations & Reporting