AutomationFlowsAI & RAG › Generate and Deploy Notion Chat Assistants with Openai and N8n API

Generate and Deploy Notion Chat Assistants with Openai and N8n API

ByDr. Firas @drfiras on n8n.io

This workflow takes a Notion database URL via n8n Chat, uses Notion and OpenAI to generate a tailored Notion-search chat assistant workflow, validates the generated n8n JSON, and then deploys the new workflow to your n8n instance via the n8n REST API (or returns JSON if…

Chat trigger trigger★★★★☆ complexityAI-powered29 nodesChat TriggerNotionAgentOpenAI ChatOutput Parser StructuredText ClassifierHTTP Request
AI & RAG Trigger: Chat trigger Nodes: 29 Complexity: ★★★★☆ AI nodes: yes Added:

This workflow corresponds to n8n.io template #17483 — we link there as the canonical source.

This workflow follows the Agent → Chat Trigger 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 →

Download .json
{
  "id": "tprSHYIIivToUEIR",
  "meta": {
    "builderVariant": "mcp",
    "aiBuilderAssisted": true
  },
  "name": "Generate and deploy an AI chat assistant for any Notion database",
  "tags": [],
  "nodes": [
    {
      "id": "7e2adc6d-5762-45d3-85f4-5a5ff672b4d6",
      "name": "Chat: Request Notion Database URL",
      "type": "@n8n/n8n-nodes-langchain.chatTrigger",
      "position": [
        736,
        480
      ],
      "parameters": {
        "public": true,
        "options": {
          "title": "\ud83e\udd16 Notion Database Assistant Generator",
          "subtitle": "Paste a Notion database URL and I will build + deploy a custom AI chat assistant for it.",
          "responseMode": "lastNode",
          "inputPlaceholder": "e.g. https://www.notion.so/myworkspace/34f67a14195344fda645691c63dc3901"
        },
        "initialMessages": "Hi! I can build you an AI chat assistant tailored to any Notion database.\n\nPaste a Notion database URL below. Generation + deployment takes 1-3 minutes."
      },
      "typeVersion": 1.4
    },
    {
      "id": "60104cc6-abb5-4f36-bc01-c4c8f59139f2",
      "name": "Configuration",
      "type": "n8n-nodes-base.set",
      "position": [
        912,
        480
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "cfg-1",
              "name": "notion_database_input",
              "type": "string",
              "value": "={{ $json.chatInput }}"
            },
            {
              "id": "cfg-2",
              "name": "openai_model",
              "type": "string",
              "value": "gpt-5.4"
            },
            {
              "id": "cfg-3",
              "name": "fixer_model",
              "type": "string",
              "value": "gpt-5.4-mini"
            },
            {
              "id": "cfg-4",
              "name": "temperature",
              "type": "number",
              "value": 0.3
            },
            {
              "id": "cfg-5",
              "name": "max_retries",
              "type": "number",
              "value": 2
            },
            {
              "id": "cfg-6",
              "name": "n8n_instance_url",
              "type": "string",
              "value": "<__PLACEHOLDER_VALUE__Your n8n instance base URL, e.g. https://n8n.yourdomain.com (no trailing slash)__>"
            }
          ]
        },
        "includeOtherFields": true
      },
      "typeVersion": 3.4
    },
    {
      "id": "68be92a8-106f-4a7f-b1e6-851630964ace",
      "name": "Get Notion Database Schema",
      "type": "n8n-nodes-base.notion",
      "onError": "continueErrorOutput",
      "position": [
        1088,
        480
      ],
      "parameters": {
        "simple": false,
        "resource": "database",
        "databaseId": {
          "__rl": true,
          "mode": "url",
          "value": "={{ $('Configuration').item.json.notion_database_input.match(/https?:\\/\\/[^\\s\\/$.?#].[^\\s]*/g)?.[0] ?? '' }}"
        }
      },
      "credentials": {
        "notionApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "c41242f4-2225-4a8a-8c81-fc95e1b0f1d8",
      "name": "Reply: Invalid Notion URL",
      "type": "n8n-nodes-base.set",
      "position": [
        1424,
        688
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "err-1",
              "name": "output",
              "type": "string",
              "value": "Sorry, that doesn't look like a valid Notion database URL, or I don't have access to it yet. Make sure you've shared the database with the connected integration, then paste the URL again."
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "558218a5-94bc-410b-9a8f-62d5375afdfb",
      "name": "Standardize Database Schema",
      "type": "n8n-nodes-base.set",
      "position": [
        1296,
        464
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "std-1",
              "name": "inputDatabase.id",
              "type": "string",
              "value": "={{ $json.id }}"
            },
            {
              "id": "std-2",
              "name": "inputDatabase.url",
              "type": "string",
              "value": "={{ $json.url }}"
            },
            {
              "id": "std-3",
              "name": "inputDatabase.public_url",
              "type": "string",
              "value": "={{ $json.public_url }}"
            },
            {
              "id": "std-4",
              "name": "inputDatabase.name",
              "type": "string",
              "value": "={{ $json.title?.[0]?.text?.content ?? $json.name ?? 'Untitled database' }}"
            },
            {
              "id": "std-5",
              "name": "inputDatabase.properties",
              "type": "object",
              "value": "={{ $json.properties }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "901adab6-fcfd-4649-836d-3a0d6dac1527",
      "name": "Simplify Schema Properties",
      "type": "n8n-nodes-base.code",
      "position": [
        1456,
        464
      ],
      "parameters": {
        "jsCode": "// Reduce the raw Notion properties object to a compact schema:\n// keeps only id/name/type (+ select/multi_select options), to save tokens in the generation prompt.\nreturn items.map(item => {\n  const inputDatabase = item.json.inputDatabase;\n  const simplifiedProperties = Object.fromEntries(Object.entries(inputDatabase.properties || {}).map(([key, value]) => {\n    const simplifiedValue = { id: value.id, name: value.name, type: value.type };\n    if (value.type === 'multi_select' || value.type === 'select') {\n      simplifiedValue.options = (value.multi_select?.options || value.select?.options || []).map(option => option.name);\n    }\n    return [key, simplifiedValue];\n  }));\n  item.json.inputDatabase.properties = simplifiedProperties;\n  return item;\n});"
      },
      "typeVersion": 2
    },
    {
      "id": "624a8965-9e72-4e60-8f12-c424906c9f37",
      "name": "Prepare Agent Input",
      "type": "n8n-nodes-base.code",
      "notes": "Allows both the first pass and the retry branch to feed the same shape into the Generate Assistant Workflow agent.",
      "position": [
        1664,
        464
      ],
      "parameters": {
        "jsCode": "const first = $input.first().json;\nreturn [{\n  json: {\n    inputDatabase: first.inputDatabase,\n    feedbackPrompt: first.feedbackPrompt || '',\n    retryCount: (typeof first.retryCount !== 'undefined') ? first.retryCount : 0,\n    workflowTemplate: JSON.parse(\"{\\\"nodes\\\":[{\\\"parameters\\\":{\\\"public\\\":true,\\\"initialMessages\\\":\\\"Hi! Ask me anything about this knowledge base.\\\",\\\"options\\\":{\\\"title\\\":\\\"Notion Knowledge Base Assistant\\\",\\\"appendAttribution\\\":false}},\\\"id\\\":\\\"trigger-1\\\",\\\"name\\\":\\\"When chat message received\\\",\\\"type\\\":\\\"@n8n/n8n-nodes-langchain.chatTrigger\\\",\\\"typeVersion\\\":1.4,\\\"position\\\":[380,460]},{\\\"parameters\\\":{\\\"promptType\\\":\\\"auto\\\",\\\"options\\\":{\\\"systemMessage\\\":\\\"You are a helpful agent. Query the DATABASE_NAME_PLACEHOLDER Notion database to find relevant records or provide insights based on multiple records. Be concise and accurate, never hallucinate, and always list the Notion page URLs you used at the end under Relevant pages.\\\"}},\\\"id\\\":\\\"agent-1\\\",\\\"name\\\":\\\"AI Agent\\\",\\\"type\\\":\\\"@n8n/n8n-nodes-langchain.agent\\\",\\\"typeVersion\\\":3.1,\\\"position\\\":[660,460]},{\\\"parameters\\\":{\\\"model\\\":{\\\"__rl\\\":true,\\\"mode\\\":\\\"list\\\",\\\"value\\\":\\\"gpt-5.4-mini\\\"},\\\"responsesApiEnabled\\\":true,\\\"options\\\":{\\\"temperature\\\":0.4}},\\\"id\\\":\\\"model-1\\\",\\\"name\\\":\\\"OpenAI Chat Model\\\",\\\"type\\\":\\\"@n8n/n8n-nodes-langchain.lmChatOpenAi\\\",\\\"typeVersion\\\":1.3,\\\"position\\\":[560,680],\\\"credentials\\\":{\\\"openAiApi\\\":{\\\"id\\\":\\\"\\\",\\\"name\\\":\\\"OpenAi account\\\"}}},{\\\"parameters\\\":{\\\"contextWindowLength\\\":10},\\\"id\\\":\\\"memory-1\\\",\\\"name\\\":\\\"Simple Memory\\\",\\\"type\\\":\\\"@n8n/n8n-nodes-langchain.memoryBufferWindow\\\",\\\"typeVersion\\\":1.4,\\\"position\\\":[760,680]},{\\\"parameters\\\":{\\\"descriptionType\\\":\\\"manual\\\",\\\"toolDescription\\\":\\\"Search the DATABASE_NAME_PLACEHOLDER Notion database. Filter by keyword (matches the title/text property) and/or tag. keyword and tag use an OR relationship.\\\",\\\"method\\\":\\\"POST\\\",\\\"url\\\":\\\"https://api.notion.com/v1/databases/DATABASE_ID_PLACEHOLDER/query\\\",\\\"authentication\\\":\\\"predefinedCredentialType\\\",\\\"nodeCredentialType\\\":\\\"notionApi\\\",\\\"sendBody\\\":true,\\\"specifyBody\\\":\\\"json\\\",\\\"jsonBody\\\":\\\"={{ { \\\\\\\"filter\\\\\\\": { \\\\\\\"or\\\\\\\": [ { \\\\\\\"property\\\\\\\": \\\\\\\"PRIMARY_TEXT_PROPERTY_PLACEHOLDER\\\\\\\", \\\\\\\"rich_text\\\\\\\": { \\\\\\\"contains\\\\\\\": $fromAI('keyword', 'Search keyword to match against the primary text property', 'string') } }, { \\\\\\\"property\\\\\\\": \\\\\\\"TAG_PROPERTY_PLACEHOLDER\\\\\\\", \\\\\\\"multi_select\\\\\\\": { \\\\\\\"contains\\\\\\\": $fromAI('tag', 'Tag to filter by, one of the known tag options', 'string') } } ] }, \\\\\\\"sorts\\\\\\\": [ { \\\\\\\"timestamp\\\\\\\": \\\\\\\"last_edited_time\\\\\\\", \\\\\\\"direction\\\\\\\": \\\\\\\"descending\\\\\\\" } ] } }}\\\"},\\\"id\\\":\\\"tool-1\\\",\\\"name\\\":\\\"Search Notion Database\\\",\\\"type\\\":\\\"n8n-nodes-base.httpRequestTool\\\",\\\"typeVersion\\\":4.4,\\\"position\\\":[960,680],\\\"credentials\\\":{\\\"notionApi\\\":{\\\"id\\\":\\\"\\\",\\\"name\\\":\\\"Notion account\\\"}}},{\\\"parameters\\\":{\\\"descriptionType\\\":\\\"manual\\\",\\\"toolDescription\\\":\\\"Retrieve the full block content of a specific Notion page by its page_id (obtained from Search Notion Database results).\\\",\\\"method\\\":\\\"GET\\\",\\\"url\\\":\\\"=https://api.notion.com/v1/blocks/{{ $fromAI('page_id', 'Notion page ID from a previous search result') }}/children\\\",\\\"authentication\\\":\\\"predefinedCredentialType\\\",\\\"nodeCredentialType\\\":\\\"notionApi\\\"},\\\"id\\\":\\\"tool-2\\\",\\\"name\\\":\\\"Read Notion Page Content\\\",\\\"type\\\":\\\"n8n-nodes-base.httpRequestTool\\\",\\\"typeVersion\\\":4.4,\\\"position\\\":[1160,680],\\\"credentials\\\":{\\\"notionApi\\\":{\\\"id\\\":\\\"\\\",\\\"name\\\":\\\"Notion account\\\"}}}],\\\"connections\\\":{\\\"OpenAI Chat Model\\\":{\\\"ai_languageModel\\\":[[{\\\"node\\\":\\\"AI Agent\\\",\\\"type\\\":\\\"ai_languageModel\\\",\\\"index\\\":0}]]},\\\"Simple Memory\\\":{\\\"ai_memory\\\":[[{\\\"node\\\":\\\"AI Agent\\\",\\\"type\\\":\\\"ai_memory\\\",\\\"index\\\":0}]]},\\\"Search Notion Database\\\":{\\\"ai_tool\\\":[[{\\\"node\\\":\\\"AI Agent\\\",\\\"type\\\":\\\"ai_tool\\\",\\\"index\\\":0}]]},\\\"Read Notion Page Content\\\":{\\\"ai_tool\\\":[[{\\\"node\\\":\\\"AI Agent\\\",\\\"type\\\":\\\"ai_tool\\\",\\\"index\\\":0}]]},\\\"When chat message received\\\":{\\\"main\\\":[[{\\\"node\\\":\\\"AI Agent\\\",\\\"type\\\":\\\"main\\\",\\\"index\\\":0}]]}}}\")\n  }\n}];"
      },
      "typeVersion": 2
    },
    {
      "id": "eb919a86-b3a2-4804-95d8-176ff1a13897",
      "name": "Generate Assistant Workflow",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        1904,
        464
      ],
      "parameters": {
        "text": "=# New Notion database details\n{{ $json.inputDatabase.toJsonString() }}\n\n# n8n workflow template to use as reference\n{{ $json.workflowTemplate.toJsonString() }}\n\n{{ $json.feedbackPrompt }}\n\nYour task: adapt the reference template above so it works with the new Notion database. Replace DATABASE_NAME_PLACEHOLDER with the real database name, DATABASE_ID_PLACEHOLDER with the real database id, PRIMARY_TEXT_PROPERTY_PLACEHOLDER with the most relevant title/rich_text property name from the schema, and TAG_PROPERTY_PLACEHOLDER with the most relevant select/multi_select property name (omit that filter branch entirely if none exists).\n\nJSON output rules:\n- Return valid JSON only: properly quoted keys/values, no trailing commas, correctly nested braces and brackets.\n- Any \"jsonBody\" field on an httpRequestTool node MUST keep using the native $fromAI(...) expression syntax exactly as shown in the template. NEVER replace it with a literal placeholder string like \"{keyword}\" \u2014 that breaks the tool at runtime.\n- Preserve the exact node type/typeVersion values from the template unless a field genuinely needs to change for this schema.\n- Output with real line breaks so the JSON stays human-readable.",
        "options": {
          "maxIterations": 5,
          "systemMessage": "You are an n8n expert who understands n8n workflow JSON structure precisely. You adapt n8n workflow templates to new data schemas. Do not hallucinate fields that are not in the provided schema. Only output n8n workflow JSON via the structured output tool."
        },
        "promptType": "define",
        "hasOutputParser": true
      },
      "typeVersion": 3.1
    },
    {
      "id": "232d7b29-dce5-4704-a092-d4b037ff9c80",
      "name": "OpenAI Model (Generator)",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
      "position": [
        1904,
        688
      ],
      "parameters": {
        "model": {
          "__rl": true,
          "mode": "id",
          "value": "={{ $('Configuration').item.json.openai_model }}"
        },
        "options": {
          "timeout": 120000,
          "maxTokens": 8192,
          "temperature": "={{ $('Configuration').item.json.temperature }}"
        },
        "builtInTools": {}
      },
      "credentials": {
        "openAiApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.3
    },
    {
      "id": "2c7bcf6d-a3e7-46fa-bdb3-da946faa769f",
      "name": "Structured Output Parser",
      "type": "@n8n/n8n-nodes-langchain.outputParserStructured",
      "position": [
        2160,
        688
      ],
      "parameters": {
        "autoFix": true,
        "schemaType": "manual",
        "inputSchema": "{\"type\":\"object\",\"properties\":{\"workflowJson\":{\"type\":\"string\",\"description\":\"The complete generated n8n workflow, as a single valid, escaped JSON string (not a JSON object).\"}},\"required\":[\"workflowJson\"]}"
      },
      "typeVersion": 1.3
    },
    {
      "id": "e2b80829-9f41-408e-8e5a-8785293d2079",
      "name": "OpenAI Model (Fixer / Classifier)",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
      "position": [
        2160,
        912
      ],
      "parameters": {
        "model": {
          "__rl": true,
          "mode": "id",
          "value": "={{ $('Configuration').item.json.fixer_model }}"
        },
        "options": {
          "maxTokens": 4096,
          "temperature": 0
        },
        "builtInTools": {}
      },
      "credentials": {
        "openAiApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.3
    },
    {
      "id": "d4b0d174-62e1-45ed-b867-502289e3bbef",
      "name": "Extract Generated Workflow",
      "type": "n8n-nodes-base.set",
      "position": [
        2400,
        464
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "eval-1",
              "name": "generatedWorkflow",
              "type": "string",
              "value": "={{ $json.output.output.workflowJson }}"
            },
            {
              "id": "eval-2",
              "name": "searchNotionDBJsonBody",
              "type": "string",
              "value": "={{ $json.output.output.workflowJson.parseJson().nodes.find(n => n.name === \"Search Notion Database\")?.parameters?.jsonBody ?? \"\" }}"
            },
            {
              "id": "eval-3",
              "name": "inputDatabase",
              "type": "object",
              "value": "={{ $('Prepare Agent Input').item.json.inputDatabase }}"
            },
            {
              "id": "eval-4",
              "name": "retryCount",
              "type": "number",
              "value": "={{ $('Prepare Agent Input').item.json.retryCount }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "13f663b8-a2bf-4294-a9c1-5080b42c0676",
      "name": "Check for Placeholder Bug",
      "type": "n8n-nodes-base.switch",
      "position": [
        2656,
        464
      ],
      "parameters": {
        "rules": {
          "values": [
            {
              "outputKey": "placeholderBug",
              "conditions": {
                "options": {
                  "version": 1,
                  "leftValue": "",
                  "caseSensitive": false,
                  "typeValidation": "strict"
                },
                "combinator": "or",
                "conditions": [
                  {
                    "operator": {
                      "type": "string",
                      "operation": "contains"
                    },
                    "leftValue": "={{ $json.searchNotionDBJsonBody }}",
                    "rightValue": "object Object"
                  },
                  {
                    "operator": {
                      "type": "string",
                      "operation": "contains"
                    },
                    "leftValue": "={{ $json.searchNotionDBJsonBody }}",
                    "rightValue": "{keyword}"
                  }
                ]
              },
              "renameOutput": true
            }
          ]
        },
        "options": {
          "fallbackOutput": "extra",
          "renameFallbackOutput": "ok"
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "92b89487-9e43-4b7c-87f3-daebf730bed4",
      "name": "Merge Failed Attempts",
      "type": "n8n-nodes-base.merge",
      "position": [
        3152,
        704
      ],
      "parameters": {},
      "typeVersion": 3.2
    },
    {
      "id": "b9e9823e-f2f9-4298-9bd1-4517e643b7b6",
      "name": "Valid n8n Workflow JSON?",
      "type": "@n8n/n8n-nodes-langchain.textClassifier",
      "position": [
        2912,
        464
      ],
      "parameters": {
        "options": {
          "enableAutoFixing": true,
          "systemPromptTemplate": "You are an expert in the n8n workflow automation tool. Classify the JSON provided by the user into one of: {categories}. Don't explain, only output the classification."
        },
        "inputText": "={{ $json.generatedWorkflow }}",
        "categories": {
          "categories": [
            {
              "category": "validJSON",
              "description": "A syntactically valid, complete n8n workflow JSON object with nodes and connections."
            },
            {
              "category": "invalidJSON",
              "description": "Malformed JSON, truncated JSON, or anything that is not a complete n8n workflow."
            }
          ]
        }
      },
      "typeVersion": 1.1
    },
    {
      "id": "ee24ce59-2b82-4e07-ad8e-bdbe4a1aa06e",
      "name": "OpenAI Model (Fixer / Classifier) copy",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
      "position": [
        2912,
        704
      ],
      "parameters": {
        "model": {
          "__rl": true,
          "mode": "id",
          "value": "={{ $('Configuration').item.json.fixer_model }}"
        },
        "options": {
          "maxTokens": 1024,
          "temperature": 0
        },
        "builtInTools": {}
      },
      "credentials": {
        "openAiApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.3
    },
    {
      "id": "3b869b12-4450-4e29-a8c0-8513a50662f5",
      "name": "Build Deployment Payload",
      "type": "n8n-nodes-base.code",
      "position": [
        3152,
        304
      ],
      "parameters": {
        "jsCode": "const generated = JSON.parse($input.first().json.generatedWorkflow);\nconst dbName = $input.first().json.inputDatabase?.name || 'Notion';\nreturn [{\n  json: {\n    deployName: dbName + ' - AI Assistant',\n    deployNodes: generated.nodes,\n    deployConnections: generated.connections\n  }\n}];"
      },
      "typeVersion": 2
    },
    {
      "id": "c96b70eb-ae34-45e7-9eaa-f129a91cb291",
      "name": "Deploy Workflow via n8n API",
      "type": "n8n-nodes-base.httpRequest",
      "onError": "continueErrorOutput",
      "position": [
        3408,
        304
      ],
      "parameters": {
        "url": "={{ $('Configuration').item.json.n8n_instance_url }}/api/v1/workflows",
        "method": "POST",
        "options": {
          "timeout": 30000
        },
        "jsonBody": "={{ { \"name\": $json.deployName, \"nodes\": $json.deployNodes, \"connections\": $json.deployConnections, \"settings\": { \"executionOrder\": \"v1\" } } }}",
        "sendBody": true,
        "sendHeaders": true,
        "specifyBody": "json",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth",
        "headerParameters": {
          "parameters": [
            {
              "name": "Content-Type",
              "value": "application/json"
            }
          ]
        }
      },
      "typeVersion": 4.4
    },
    {
      "id": "f6229f56-2ff3-481b-9627-2fcde1d02406",
      "name": "Reply: Deployment Success",
      "type": "n8n-nodes-base.set",
      "position": [
        3664,
        208
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "ok-1",
              "name": "output",
              "type": "string",
              "value": "=\u2705 Your custom Notion AI assistant is ready!\n\n\ud83d\udd17 Open it here: {{ $('Configuration').item.json.n8n_instance_url }}/workflow/{{ $json.id }}\n\nBefore you use it:\n1. Open the workflow and select your OpenAI + Notion credentials on the model and tool nodes (they are not auto-bound for security).\n2. Send a test message in the chat trigger.\n3. Activate the workflow if you want it always-on."
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "7996741a-77cb-4ec7-b9a9-2329d4265053",
      "name": "Reply: Deploy Failed (Fallback JSON)",
      "type": "n8n-nodes-base.set",
      "position": [
        3664,
        400
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "fail-1",
              "name": "output",
              "type": "string",
              "value": "=\u26a0\ufe0f I generated the assistant but couldn't deploy it automatically \u2014 check the \"n8n API Key\" credential and the n8n_instance_url in Configuration.\n\nHere is the workflow JSON \u2014 copy it and paste into a new n8n canvas (Ctrl+V / Cmd+V):\n\n```\n{{ $('Extract Generated Workflow').item.json.generatedWorkflow }}\n```"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "bfd9f65d-b360-43c9-a81c-048ab581999d",
      "name": "Retry Limit Reached?",
      "type": "n8n-nodes-base.if",
      "position": [
        3408,
        704
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 1,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "operator": {
                "type": "number",
                "operation": "gte"
              },
              "leftValue": "={{ $json.retryCount }}",
              "rightValue": "={{ $('Configuration').item.json.max_retries }}"
            }
          ]
        }
      },
      "typeVersion": 2.3
    },
    {
      "id": "64c23422-c060-487c-918b-ae467b84e4e9",
      "name": "Reply: Generation Failed",
      "type": "n8n-nodes-base.set",
      "position": [
        3664,
        560
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "gf-1",
              "name": "output",
              "type": "string",
              "value": "I tried a few times but couldn't generate a fully valid workflow for this database schema. This can happen with very unusual property types. Try again in a moment, or simplify the database (fewer exotic property types) and resend the URL."
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "cc2a81aa-755b-4741-a6df-88875dbeb6f8",
      "name": "Add Feedback Prompt",
      "type": "n8n-nodes-base.set",
      "position": [
        3664,
        832
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "fb-1",
              "name": "feedbackPrompt",
              "type": "string",
              "value": "# Previous attempt was rejected\nYour previous output failed validation (invalid JSON, or a jsonBody field used a literal placeholder instead of $fromAI(...)). Below was your task and the rejected output \u2014 fix the specific issue and try again, keeping everything else the same.\n\n# Rejected output\n"
            }
          ]
        },
        "includeOtherFields": true
      },
      "typeVersion": 3.4
    },
    {
      "id": "f1cab848-963f-483d-baba-197188bc57b7",
      "name": "Prepare Retry",
      "type": "n8n-nodes-base.set",
      "position": [
        3904,
        832
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "rr-1",
              "name": "inputDatabase",
              "type": "object",
              "value": "={{ $json.inputDatabase }}"
            },
            {
              "id": "rr-2",
              "name": "feedbackPrompt",
              "type": "string",
              "value": "={{ $json.feedbackPrompt }}{{ $json.generatedWorkflow }}"
            },
            {
              "id": "rr-3",
              "name": "retryCount",
              "type": "number",
              "value": "={{ $json.retryCount + 1 }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "ac36a6bc-d583-437a-9ce9-7c476ee1d75f",
      "name": "Main Documentation",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -528,
        -176
      ],
      "parameters": {
        "color": 4,
        "width": 1120,
        "height": 1928,
        "content": "# Generate and deploy an AI chat assistant for any Notion database\n# \ud83d\udce5  [Open full documentation on Notion](https://app.notion.com/p/automatisation/Course-Generate-and-deploy-an-AI-chat-assistant-for-any-Notion-database-39e3d6550fd98123817cec0b54ce6aa0)\n\n## How it works\nPaste any Notion database URL into the chat. The workflow fetches its schema, an AI agent adapts a proven Notion-assistant template to that exact schema (right property names, right database ID), self-checks the generated JSON (including a known \"jsonBody placeholder\" bug), retries up to a configurable limit, and then **deploys the finished assistant directly into your n8n account via the n8n REST API** \u2014 no manual copy-paste. You get a clickable link back in the chat.\n\n## Setup\n1. Connect your **OpenAi account** and **Notion account** credentials on the relevant nodes (they are pre-selected if you import into the same account this was generated in).\n2. Share the Notion databases you want to turn into assistants with your Notion integration.\n3. Create an **n8n API Key** credential (httpHeaderAuth) \u2014 n8n UI: Settings \u2192 n8n API \u2192 Create an API key \u2192 copy it. Create a new credential of type \"Header Auth\", Name: `X-N8N-API-KEY`, Value: your key. Select it on the \"Deploy Workflow via n8n API\" node.\n4. Open the **Configuration** node and set `n8n_instance_url` to your instance base URL (e.g. `https://n8n.yourdomain.com`, no trailing slash).\n\n## Requirements\n- An OpenAI API key with GPT-5.4 family access (OpenAi account credential).\n- A Notion integration connected to your workspace (Notion account credential) with access to the target databases.\n- Your own n8n REST API key (self-hosted or Cloud) for the auto-deploy step. Without it, the workflow still works \u2014 it just returns the JSON in chat as a fallback instead of deploying automatically.\n\n## Customization\n- Edit the **Configuration** node to change the generator model, the fixer/classifier model, generation temperature, or the max retry count.\n- Edit the reference template embedded in **Prepare Agent Input** if you want generated assistants to use a different memory window, different tools, or a different system prompt style.\n- The deploy step creates workflows inactive and unpublished by default \u2014 review each one before activating.\n\nNeed help customizing?\nContact me for consulting and support : [Linkedin](https://www.linkedin.com/in/doctor-firass/)\n\n# MY NEW YOUTUBE CHANNEL\n\ud83d\udc49 [Subscribe to my new YouTube channel](https://www.youtube.com/@DrFiras_AI). Here I'll share videos and Shorts with practical tutorials and FREE templates for n8n.\n\n[![The AI Doctor](https://www.dr-firas.com/the-ai-doctor.png)](https://www.youtube.com/@DrFiras_AI)"
      },
      "typeVersion": 1
    },
    {
      "id": "36f48c1f-416d-4c03-907f-7606ffa18852",
      "name": "Section 1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        848,
        112
      ],
      "parameters": {
        "color": 7,
        "width": 1050,
        "content": "## 1. Capture input & fetch schema\nChat trigger centralizes config, extracts the Notion database URL, and pulls + simplifies its schema."
      },
      "typeVersion": 1
    },
    {
      "id": "ac24044e-0e20-453f-afd1-9023466dfcd8",
      "name": "Section 2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2000,
        1136
      ],
      "parameters": {
        "color": 7,
        "width": 800,
        "content": "## 2. AI generation\nAn agent adapts a proven Notion-assistant template to the new schema and returns strict JSON via a structured output parser (with auto-fix)."
      },
      "typeVersion": 1
    },
    {
      "id": "b7c1dd2a-b34f-44e6-9937-de0e7d11f0f8",
      "name": "Section 3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        3056,
        1104
      ],
      "parameters": {
        "color": 7,
        "width": 904,
        "height": 200,
        "content": "## 3. Self-validation + retry loop\nChecks for the known jsonBody placeholder bug and for malformed JSON, retries with feedback up to Configuration.max_retries, then gives up gracefully."
      },
      "typeVersion": 1
    },
    {
      "id": "165e30b3-d2d5-4589-bb6d-34da63af03cf",
      "name": "Section 4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2240,
        96
      ],
      "parameters": {
        "color": 7,
        "width": 750,
        "content": "## 4. Auto-deploy\nBuilds the n8n API payload and creates the workflow directly in your account via POST /api/v1/workflows, replying with a clickable link. Falls back to copy-paste JSON if deploy fails."
      },
      "typeVersion": 1
    }
  ],
  "active": false,
  "settings": {
    "binaryMode": "separate",
    "availableInMCP": true,
    "executionOrder": "v1"
  },
  "versionId": "8df02d46-b72b-4203-8332-20b40b16d7dd",
  "nodeGroups": [],
  "connections": {
    "Configuration": {
      "main": [
        [
          {
            "node": "Get Notion Database Schema",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Prepare Retry": {
      "main": [
        [
          {
            "node": "Prepare Agent Input",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Add Feedback Prompt": {
      "main": [
        [
          {
            "node": "Prepare Retry",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Prepare Agent Input": {
      "main": [
        [
          {
            "node": "Generate Assistant Workflow",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Retry Limit Reached?": {
      "main": [
        [
          {
            "node": "Reply: Generation Failed",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Add Feedback Prompt",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Merge Failed Attempts": {
      "main": [
        [
          {
            "node": "Retry Limit Reached?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Build Deployment Payload": {
      "main": [
        [
          {
            "node": "Deploy Workflow via n8n API",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "OpenAI Model (Generator)": {
      "ai_languageModel": [
        [
          {
            "node": "Generate Assistant Workflow",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Structured Output Parser": {
      "ai_outputParser": [
        [
          {
            "node": "Generate Assistant Workflow",
            "type": "ai_outputParser",
            "index": 0
          }
        ]
      ]
    },
    "Valid n8n Workflow JSON?": {
      "main": [
        [
          {
            "node": "Build Deployment Payload",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Merge Failed Attempts",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "Check for Placeholder Bug": {
      "main": [
        [
          {
            "node": "Merge Failed Attempts",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Valid n8n Workflow JSON?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Extract Generated Workflow": {
      "main": [
        [
          {
            "node": "Check for Placeholder Bug",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get Notion Database Schema": {
      "main": [
        [
          {
            "node": "Standardize Database Schema",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Reply: Invalid Notion URL",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Simplify Schema Properties": {
      "main": [
        [
          {
            "node": "Prepare Agent Input",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Deploy Workflow via n8n API": {
      "main": [
        [
          {
            "node": "Reply: Deployment Success",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Reply: Deploy Failed (Fallback JSON)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Generate Assistant Workflow": {
      "main": [
        [
          {
            "node": "Extract Generated Workflow",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Standardize Database Schema": {
      "main": [
        [
          {
            "node": "Simplify Schema Properties",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Chat: Request Notion Database URL": {
      "main": [
        [
          {
            "node": "Configuration",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "OpenAI Model (Fixer / Classifier)": {
      "ai_languageModel": [
        [
          {
            "node": "Structured Output Parser",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "OpenAI Model (Fixer / Classifier) copy": {
      "ai_languageModel": [
        [
          {
            "node": "Valid n8n Workflow JSON?",
            "type": "ai_languageModel",
            "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.

Pro

For the full experience including quality scoring and batch install features for each workflow upgrade to Pro

About this workflow

This workflow takes a Notion database URL via n8n Chat, uses Notion and OpenAI to generate a tailored Notion-search chat assistant workflow, validates the generated n8n JSON, and then deploys the new workflow to your n8n instance via the n8n REST API (or returns JSON if…

Source: https://n8n.io/workflows/17483/ — original creator credit. Request a take-down →

More AI & RAG workflows → · Browse all categories →

Related workflows

Workflows that share integrations, category, or trigger type with this one. All free to copy and import.

AI & RAG

💰 Beginner Investor – Learn the market faster with AI-powered insights guiding your decisions. 📈 Retail Trader – Optimize your trading strategy with in-depth analysis typically reserved for profession

HTTP Request, Output Parser Structured, OpenAI Chat +4
AI & RAG

This template attempts to create an AI-powered content assistant for WordPress sites using Mistral AI, enabling article recommendations, content summarization, and contextual Q&A capabilities.

Chat Trigger, Output Parser Structured, Agent +10
AI & RAG

by Varritech Technologies

Chat Trigger, Agent, OpenAI Chat +8
AI & RAG

Who’s it for Creators who want to create faceless videos automatically, while keeping human oversight and quality control.

Read Write File, Agent, OpenAI Chat +7
AI & RAG

The Best Linkedin Posting System. Uses httpRequest, lmChatOpenAi, agent, chatTrigger. Chat trigger; 49 nodes.

HTTP Request, OpenAI Chat, Agent +8