AutomationFlowsAI & RAG › Openai Responses API Adapter for LLM and AI Agent Workflows

Openai Responses API Adapter for LLM and AI Agent Workflows

ByJimleuk @jimleuk on n8n.io

Though I would recommend just waiting for official support, if you're impatient and would like a round-about way to integrate OpenAI's responses API into your existing AI workflows then this template is sure to satisfy!

Chat trigger trigger★★★★☆ complexityAI-powered19 nodesChat TriggerAgentHTTP RequestOpenAI Chat
AI & RAG Trigger: Chat trigger Nodes: 19 Complexity: ★★★★☆ AI nodes: yes Added:

This workflow corresponds to n8n.io template #4218 — 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
{
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "nodes": [
    {
      "id": "8531ff8a-b247-4baa-a85b-11512fc2bb60",
      "name": "When chat message received",
      "type": "@n8n/n8n-nodes-langchain.chatTrigger",
      "position": [
        -320,
        -500
      ],
      "parameters": {
        "public": true,
        "options": {
          "allowFileUploads": true
        }
      },
      "typeVersion": 1.1
    },
    {
      "id": "a039b516-a74a-4ea6-8583-abec9bf2a1f8",
      "name": "AI Agent",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        -120,
        -500
      ],
      "parameters": {
        "options": {
          "passthroughBinaryImages": true,
          "returnIntermediateSteps": true
        }
      },
      "typeVersion": 1.9
    },
    {
      "id": "454a16ea-9bcf-4cb8-a62d-95a1aedea974",
      "name": "Webhook",
      "type": "n8n-nodes-base.webhook",
      "position": [
        -320,
        160
      ],
      "parameters": {
        "path": "n8n-responses-api/models",
        "options": {},
        "responseMode": "responseNode"
      },
      "typeVersion": 2
    },
    {
      "id": "3fca113b-f259-4495-a52c-89f3c09748c0",
      "name": "OpenAI Models",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        -100,
        160
      ],
      "parameters": {
        "url": "https://api.openai.com/v1/models",
        "options": {},
        "authentication": "predefinedCredentialType",
        "nodeCredentialType": "openAiApi"
      },
      "credentials": {
        "openAiApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "bee5a8d3-e18a-4756-99ea-7d14fa08e2f5",
      "name": "POST ChatCompletions",
      "type": "n8n-nodes-base.webhook",
      "position": [
        460,
        240
      ],
      "parameters": {
        "path": "n8n-responses-api/chat/completions",
        "options": {},
        "httpMethod": "POST",
        "responseMode": "responseNode"
      },
      "typeVersion": 2
    },
    {
      "id": "974fd565-c1cf-468a-827f-391bd013e145",
      "name": "Models Response",
      "type": "n8n-nodes-base.respondToWebhook",
      "position": [
        120,
        160
      ],
      "parameters": {
        "options": {
          "responseCode": 200,
          "responseHeaders": {
            "entries": [
              {
                "name": "Content-Type",
                "value": "application/json"
              }
            ]
          }
        },
        "respondWith": "json",
        "responseBody": "={{ $json }}"
      },
      "typeVersion": 1.2
    },
    {
      "id": "6a4bfb20-5562-4500-9ee2-521f848d3825",
      "name": "Remap to Response API Schema",
      "type": "n8n-nodes-base.code",
      "position": [
        680,
        240
      ],
      "parameters": {
        "mode": "runOnceForEachItem",
        "jsCode": "function tranformContent(content) {\n  return [].concat(content).map(content => {\n    if (typeof content === 'string') {\n      return { type: \"input_text\", text: content };\n    }\n    return {\n      type: getInputType(content.type),\n      [content.type]: content[content.type].url\n    }\n  })\n};\n\nfunction getInputType(type) {\n  if (type === 'image_url') return 'input_image';\n  if (type === 'file_url') return 'input_file';\n  return 'input_text';\n}\n\nconst input = $input.item.json.body.messages.map(message => ({\n  role: message.role,\n  content: tranformContent(message.content)\n}));\n\nreturn { input };"
      },
      "typeVersion": 2
    },
    {
      "id": "5f4f22c9-f333-469c-a915-8f5da6443e53",
      "name": "OpenAI Responses API",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        900,
        240
      ],
      "parameters": {
        "url": "https://api.openai.com/v1/responses",
        "method": "POST",
        "options": {},
        "jsonBody": "={{\n{\n  model: $('POST ChatCompletions').first().json.body.model,\n  stream: $('POST ChatCompletions').first().json.body.stream,\n  input: $json.input,\n}\n}}",
        "sendBody": true,
        "specifyBody": "json",
        "authentication": "predefinedCredentialType",
        "nodeCredentialType": "openAiApi"
      },
      "credentials": {
        "openAiApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "5242a76d-9649-469b-ba91-e33d0f42850e",
      "name": "Is Agent?",
      "type": "n8n-nodes-base.if",
      "position": [
        1100,
        240
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "213702bf-d5c2-4a8a-b5c8-e55f804e4496",
              "operator": {
                "type": "boolean",
                "operation": "true",
                "singleValue": true
              },
              "leftValue": "={{ $('POST ChatCompletions').first().json.body.stream }}",
              "rightValue": ""
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "4ecc0ec2-4637-48d9-9157-0a6dc39bab9e",
      "name": "n8n Webhook",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
      "position": [
        -140,
        -320
      ],
      "parameters": {
        "model": {
          "__rl": true,
          "mode": "list",
          "value": "gpt-4o-mini"
        },
        "options": {}
      },
      "credentials": {
        "openAiApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "d050bfc1-ce7a-4ae2-b4b1-763be76b8061",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -400,
        -740
      ],
      "parameters": {
        "color": 7,
        "width": 700,
        "height": 580,
        "content": "## 1. Create a New Custom OpenAI Credential\n[Learn more about OpenAI Credentials](https://docs.n8n.io/integrations/builtin/credentials/openai/)\n\nTo use Github Models with our existing n8n nodes, one approach is to mimic an openAI compatible API connected through the OpenAI model subnode. Sounds complicated but don't worry, this template shows you how! The first step is to setup a new OpenAI credential so that we can change the Base URL."
      },
      "typeVersion": 1
    },
    {
      "id": "7703f756-652b-44e4-81b3-021323b08e18",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        180,
        -380
      ],
      "parameters": {
        "color": 5,
        "width": 540,
        "height": 240,
        "content": "### LLM Models via N8N Webhooks\n1. Create a new OpenAI Credential and call it \"n8n-responses-api\"\n2. Enter API key as anything you like eg. \"12345\"\n3. Enter Base URL as \"https://<your_n8n_url>/webhook/n8n-reponses-api\"\n4. Activate your workflow! This only really works with the production webhook URL.\n\n\nFeel free to change the names to whatever you want, just make sure the LLM node is able to reach it!"
      },
      "typeVersion": 1
    },
    {
      "id": "a6bc3bcc-d1e9-4d7a-947b-faeddda59507",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -400,
        -40
      ],
      "parameters": {
        "color": 7,
        "width": 740,
        "height": 420,
        "content": "## 2. Listing All Available Models \n[Read more about the Webhook Trigger node](https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.webhook/)\n\nOur first endpoint is for listing all models. The Github Models API how we can do this but the response requires some re-mapping to make it compatible with our LLM node."
      },
      "typeVersion": 1
    },
    {
      "id": "54e0b20a-1a3d-4068-b76a-9b6d10fa0fc2",
      "name": "Format Completion Response",
      "type": "n8n-nodes-base.code",
      "position": [
        1320,
        340
      ],
      "parameters": {
        "mode": "runOnceForEachItem",
        "jsCode": "return {\n  \"id\": $json.id,\n  \"object\": \"chat.completion\",\n  \"created\": $json.created_at,\n  \"model\": $json.model,\n  \"choices\": $json.output.flatMap((item,idx) => (\n    item.content.map((content) => ({\n      index: idx,\n      finish_reason: \"stop\",\n      \"message\": {\n        \"annotations\": content.annotations,\n        \"content\": content.text,\n        \"refusal\": null,\n        \"role\": item.role\n      }\n    }))\n  )),\n  \"usage\": {\n    \"completion_tokens\": $json.usage.output_tokens,\n    \"completion_tokens_details\": $json.usage.output_tokens_details,\n    \"prompt_tokens\": $json.usage.input_tokens_details,\n    \"prompt_tokens_details\": $json.usage.input_tokens_details,\n    \"total_tokens\": $json.usage.total_tokens\n  },\n  \"service_tier\": $json.service_tier,\n  \"system_fingerprint\": $json.id\n}"
      },
      "typeVersion": 2
    },
    {
      "id": "a7f2daa8-b4be-4571-b210-3d7ffd7481a3",
      "name": "JSON Response",
      "type": "n8n-nodes-base.respondToWebhook",
      "position": [
        1520,
        340
      ],
      "parameters": {
        "options": {},
        "respondWith": "json",
        "responseBody": "={{ $json }}"
      },
      "typeVersion": 1.2
    },
    {
      "id": "4d64850a-3125-47eb-a892-1beddbb371fb",
      "name": "Text Response",
      "type": "n8n-nodes-base.respondToWebhook",
      "position": [
        1520,
        140
      ],
      "parameters": {
        "options": {},
        "respondWith": "text",
        "responseBody": "={{ $json.data }}"
      },
      "typeVersion": 1.2
    },
    {
      "id": "a9352379-8001-4ff2-a76a-cd927e9f47a2",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        380,
        -40
      ],
      "parameters": {
        "color": 7,
        "width": 1360,
        "height": 580,
        "content": "## 3. Remap OpenAI Responses API for Langchain Compatibility\n[Learn more about the HTTP request node](https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.httprequest)\n\nOpenAI's Responses API is a massive upgrade in terms of capability and support for multimodal use-cases. Unfortunately, this means\nthe API responses are now so fundamentally different, it's not that quite straightforward to use them with Langchain.\nHere, we show it's possible to map the output for compatibility but does so loses out on newer features of the API."
      },
      "typeVersion": 1
    },
    {
      "id": "cd8859ef-9d74-4272-a580-d0db59ce1a43",
      "name": "Format Stream Response",
      "type": "n8n-nodes-base.code",
      "position": [
        1320,
        140
      ],
      "parameters": {
        "mode": "runOnceForEachItem",
        "jsCode": "const items = $input.item.json.data.split(/^\\n/mg);\nconst events = items.map(item => {\n  const [event, data] = item.split('\\n');\n  return {\n    event: event?.split(':')[1]?.trim() ?? null,\n    data: data?.substring(data.indexOf(':')+1,data.length)?.trim() ?? null\n  }\n});\n\nconst done = events.find(item => item.event === 'response.completed');\nconst res = JSON.parse(done.data).response;\n\nconst chunk = {\n  id: res.id,\n  object:\"chat.completion.chunk\",\n  created: res.created_at,\n  model: res.model,\n  service_tier: res.service_tier,\n  system_fingerprint: res.id,\n  choices: [{\n    index: 0,\n     delta: { content: res.output[0].content[0].text }\n  }],\n  \"usage\": {\n    \"completion_tokens\": res.usage.output_tokens,\n    \"completion_tokens_details\": res.usage.output_tokens_details,\n    \"prompt_tokens\": res.usage.input_tokens_details,\n    \"prompt_tokens_details\": res.usage.input_tokens_details,\n    \"total_tokens\": res.usage.total_tokens\n  }\n};\n\nconst data = [\n  `data: ${JSON.stringify(chunk)}`,\n  `data: [DONE]`\n].join('\\n\\n');\n\nreturn { data };"
      },
      "typeVersion": 2
    },
    {
      "id": "e1cb299d-3301-41d9-aa99-9b740105f377",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -880,
        -740
      ],
      "parameters": {
        "width": 420,
        "height": 1180,
        "content": "## Try It Out!\n### This n8n template demonstrates how to use OpenAI's Responses API with existing LLM and AI Agent nodes.\n\nThough I would recommend just waiting for official support, if you're impatient and would like a round-about way to integrate OpenAI's responses API into your existing AI workflows then this template is sure to satisfy!\n\nThis approach implements a simple API wrapper for the Responses API using n8n's builtin webhooks. When the base url is pointed to these webhooks using a custom OpenAI credential, it's possible to intercept the request and remap for compatibility.\n\n### How it works\n* An OpenAI subnode is attached to our agent but has a special custom credential where the base_url is changed to point at this template's webhooks.\n* When executing a query, the agent's request is forwarded to our mini chat completion workflow.\n* Here, we take the default request and remap the values to use with a HTTP node which is set to query the Responses API.\n* Once a response is received, we'll need to remap the output for Langchain compatibility. This just means the LLM or Agent node can parse it and respond to the user.\n* There are two response formats, one for streaming and one for non-streaming responses.\n\n### How to use\n* You must activate this workflow to be able to use the webhooks.\n* Create the custom OpenAI credential as instructed.\n* Go to your existing AI workflows and replace the LLM node with the custom OpenAI credential. You do not need to copy anything else over to the existing template.\n\n### Requirements\n* OpenAI account for Responses API\n\n### Customising this workflow\n* Feel free to experiment with other LLMs using this same technique!\n* Keep up to date with the Responses API announcements and make modifications as required.\n\n### Need Help?\nJoin the [Discord](https://discord.com/invite/XPKeKXeB7d) or ask in the [Forum](https://community.n8n.io/)!\n\nHappy Hacking!"
      },
      "typeVersion": 1
    }
  ],
  "connections": {
    "Webhook": {
      "main": [
        [
          {
            "node": "OpenAI Models",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Is Agent?": {
      "main": [
        [
          {
            "node": "Format Stream Response",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Format Completion Response",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "n8n Webhook": {
      "ai_languageModel": [
        [
          {
            "node": "AI Agent",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "OpenAI Models": {
      "main": [
        [
          {
            "node": "Models Response",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "OpenAI Responses API": {
      "main": [
        [
          {
            "node": "Is Agent?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "POST ChatCompletions": {
      "main": [
        [
          {
            "node": "Remap to Response API Schema",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Format Stream Response": {
      "main": [
        [
          {
            "node": "Text Response",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Format Completion Response": {
      "main": [
        [
          {
            "node": "JSON Response",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "When chat message received": {
      "main": [
        [
          {
            "node": "AI Agent",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Remap to Response API Schema": {
      "main": [
        [
          {
            "node": "OpenAI Responses API",
            "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.

Pro

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

About this workflow

Though I would recommend just waiting for official support, if you're impatient and would like a round-about way to integrate OpenAI's responses API into your existing AI workflows then this template is sure to satisfy!

Source: https://n8n.io/workflows/4218/ — 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

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
AI & RAG

Who is this workflow for? This workflow is designed for SEO analysts, content creators, marketing agencies, and developers who need to index a website and then interact with its content as if it were

Agent, OpenAI Chat, Memory Buffer Window +10