This workflow follows the OpenAI Embeddings → HTTP Request 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 →
{
"name": "03 \u2014 Query naive (baseline)",
"settings": {
"executionOrder": "v1"
},
"nodes": [
{
"parameters": {
"httpMethod": "POST",
"path": "query-naive",
"responseMode": "lastNode",
"options": {}
},
"id": "a3000000-0000-4000-8000-000000000001",
"name": "Webhook",
"type": "n8n-nodes-base.webhook",
"typeVersion": 2,
"position": [
-620,
0
],
"notes": "POST { \"question\": \"...\" }. Baseline: no hybrid search, no rerank."
},
{
"parameters": {
"mode": "load",
"tableName": "documents",
"prompt": "={{ $json.body.question }}",
"topK": 5,
"options": {
"queryName": "match_documents"
}
},
"id": "a3000000-0000-4000-8000-000000000002",
"name": "Retrieve \u2014 pure vector",
"type": "@n8n/n8n-nodes-langchain.vectorStoreSupabase",
"typeVersion": 1.1,
"position": [
-380,
0
],
"credentials": {
"supabaseApi": {
"name": "<your credential>"
}
},
"notes": "match_documents orders by cosine distance only \u2014 this is the naive baseline the other strategies are measured against."
},
{
"parameters": {
"model": "text-embedding-3-small",
"options": {}
},
"id": "a3000000-0000-4000-8000-000000000003",
"name": "Embeddings OpenAI",
"type": "@n8n/n8n-nodes-langchain.embeddingsOpenAi",
"typeVersion": 1.2,
"position": [
-380,
220
],
"credentials": {
"openAiApi": {
"name": "<your credential>"
}
},
"notes": "Must be the same model used at ingestion: query and chunk vectors have to live in the same space."
},
{
"parameters": {
"jsCode": "const question = $('Webhook').first().json.body.question;\nconst hits = $input.all().map((item, i) => {\n const doc = item.json.document ?? item.json;\n return {\n rank: i + 1,\n similarity: item.json.score ?? null,\n source: doc.metadata?.source ?? null,\n lines: doc.metadata?.loc?.lines ?? null,\n content: doc.pageContent ?? doc.content ?? '',\n };\n});\n\nconst context = hits\n .map((h) => `[${h.rank}] (${h.source}${h.lines ? `, lines ${h.lines.from}-${h.lines.to}` : ''})\\n${h.content}`)\n .join('\\n\\n');\n\nconst system = 'You answer strictly from the provided excerpts of the NIST Cybersecurity Framework 2.0. Cite the excerpt you used as [n] after each claim. If the excerpts do not contain the answer, say so plainly instead of guessing.';\nconst user = `Question: ${question}\\n\\nExcerpts:\\n${context}`;\n\nreturn [{ json: { question, hits, system, user, contextChars: context.length } }];"
},
"id": "a3000000-0000-4000-8000-000000000004",
"name": "Build Prompt",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
-140,
0
],
"notes": "No executeOnce: it would clamp the node to the first retrieved chunk."
},
{
"parameters": {
"method": "POST",
"url": "https://api.openai.com/v1/chat/completions",
"authentication": "predefinedCredentialType",
"nodeCredentialType": "openAiApi",
"sendBody": true,
"specifyBody": "json",
"jsonBody": "={{ JSON.stringify({ model: 'gpt-4o-mini', temperature: 0, messages: [ { role: 'system', content: $json.system }, { role: 'user', content: $json.user } ] }) }}",
"options": {}
},
"id": "a3000000-0000-4000-8000-000000000005",
"name": "Generate \u2014 gpt-4o-mini",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
100,
0
],
"credentials": {
"openAiApi": {
"name": "<your credential>"
}
},
"notes": "Raw HTTP rather than the chat node so the response carries `usage` \u2014 token counts are the cost evidence for this block."
},
{
"parameters": {
"jsCode": "const res = $input.first().json;\nconst usage = res.usage ?? {};\n// gpt-4o-mini, USD per 1M tokens.\nconst IN = 0.15, OUT = 0.60;\nconst cost = ((usage.prompt_tokens ?? 0) / 1e6) * IN + ((usage.completion_tokens ?? 0) / 1e6) * OUT;\nconst prep = $('Build Prompt').first().json;\n\nreturn [{ json: {\n strategy: 'naive',\n question: prep.question,\n answer: res.choices?.[0]?.message?.content ?? null,\n retrieved: prep.hits.map((h) => ({\n rank: h.rank,\n similarity: h.similarity,\n source: h.source,\n lines: h.lines,\n preview: h.content.slice(0, 220),\n })),\n usage,\n costUsd: Number(cost.toFixed(6)),\n} }];"
},
"id": "a3000000-0000-4000-8000-000000000006",
"name": "Format Answer",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
340,
0
],
"notes": "Cost is computed here, not estimated afterwards: prompt/completion tokens come back with every generation."
}
],
"connections": {
"Webhook": {
"main": [
[
{
"node": "Retrieve \u2014 pure vector",
"type": "main",
"index": 0
}
]
]
},
"Retrieve \u2014 pure vector": {
"main": [
[
{
"node": "Build Prompt",
"type": "main",
"index": 0
}
]
]
},
"Embeddings OpenAI": {
"ai_embedding": [
[
{
"node": "Retrieve \u2014 pure vector",
"type": "ai_embedding",
"index": 0
}
]
]
},
"Build Prompt": {
"main": [
[
{
"node": "Generate \u2014 gpt-4o-mini",
"type": "main",
"index": 0
}
]
]
},
"Generate \u2014 gpt-4o-mini": {
"main": [
[
{
"node": "Format Answer",
"type": "main",
"index": 0
}
]
]
}
}
}
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.
openAiApisupabaseApi
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
03 — Query naive (baseline). Uses vectorStoreSupabase, embeddingsOpenAi, httpRequest. Webhook trigger; 6 nodes.
Source: https://github.com/BhrayanM/rag-engine/blob/main/workflows/03-query-naive.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.
Bread-Meat-Delivery. Uses lmChatOpenAi, agent, httpRequest, redis. Webhook trigger; 91 nodes.
My workflow 14. Uses supabase, redis, openAi, googleCalendarTool. Webhook trigger; 91 nodes.
HeyDinastia. Uses executeCommand, httpRequest, youTube, postgres. Webhook trigger; 66 nodes.
This workflow automates multi-channel AI-driven sales engagement for lead qualification, service information delivery, and consultation booking. It integrates WhatsApp, Facebook Messenger, Instagram D
YouTube Agent. Uses supabase, agent, lmChatAnthropic, outputParserStructured. Webhook trigger; 56 nodes.