{"componentChunkName":"component---src-gatsby-theme-chronoblog-templates-note-js","path":"/notes/llm-integration-openai-responses-api/","result":{"data":{"mdx":{"parent":{"__typename":"File","fields":{"gitLogLatestDate":"2026-05-31 15:47:24 +0200"}},"id":"f1614aaa-0ca4-5ea5-ad92-0a046902285a","excerpt":"Large language models (LLMs) understand and generate text from prompts. OpenAI exposes models through the  Responses API . The official…","frontmatter":{"title":"LLM integration with OpenAI Responses API","date":"2026-05-31 12:00:00 UTC","job_ad":null,"job_ad_id":null,"job_ad_url":null,"tags":["openai","llm","api","node"],"cover":null},"fields":{"slug":"/notes/llm-integration-openai-responses-api/","readingTime":{"text":"3 min read"}},"body":"function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }\n\nfunction _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }\n\n/* @jsxRuntime classic */\n\n/* @jsx mdx */\nvar _frontmatter = {\n  \"title\": \"LLM integration with OpenAI Responses API\",\n  \"date\": \"2026-05-31 12:00:00 UTC\",\n  \"tags\": [\"openai\", \"llm\", \"api\", \"node\"],\n  \"canonical_url\": \"https://sevic.dev/notes/llm-integration-openai-responses-api/\"\n};\nvar layoutProps = {\n  _frontmatter: _frontmatter\n};\nvar MDXLayout = \"wrapper\";\nreturn function MDXContent(_ref) {\n  var components = _ref.components,\n      props = _objectWithoutProperties(_ref, [\"components\"]);\n\n  return mdx(MDXLayout, _extends({}, layoutProps, props, {\n    components: components,\n    mdxType: \"MDXLayout\"\n  }), mdx(\"p\", null, \"Large language models (LLMs) understand and generate text from prompts. OpenAI exposes models through the \", mdx(\"a\", _extends({\n    parentName: \"p\"\n  }, {\n    \"href\": \"https://platform.openai.com/docs/api-reference/responses\"\n  }), \"Responses API\"), \". The official \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"openai\"), \" npm package is the practical way to call it from Node.js. This post covers common patterns beyond a single prompt string.\"), mdx(\"h3\", {\n    \"id\": \"prerequisites\"\n  }, \"Prerequisites\"), mdx(\"ul\", null, mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"OpenAI account\"), mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"Generated API key\"), mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"Enabled billing\"), mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"Node.js version 26\"), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"inlineCode\", {\n    parentName: \"li\"\n  }, \"openai\"), \" package installed (\", mdx(\"inlineCode\", {\n    parentName: \"li\"\n  }, \"npm i openai\"), \")\")), mdx(\"h3\", {\n    \"id\": \"client-setup\"\n  }, \"Client setup\"), mdx(\"p\", null, \"Create a client with your API key (read from the environment in production).\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-js\"\n  }), \"import OpenAI from 'openai';\\n\\nconst client = new OpenAI({ apiKey: process.env.OPENAI_API_KEY });\\n\")), mdx(\"p\", null, \"The same SDK can target other hosts that implement a compatible API by setting \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"baseURL\"), \" and \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"apiKey\"), \":\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-js\"\n  }), \"const client = new OpenAI({\\n  apiKey: process.env.LLM_API_KEY,\\n  baseURL: 'https://your-gateway.example/v1',\\n});\\n\")), mdx(\"p\", null, mdx(\"a\", _extends({\n    parentName: \"p\"\n  }, {\n    \"href\": \"https://github.com/openai/openai-node/blob/master/azure.md\"\n  }), \"Azure OpenAI\"), \" uses \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"AzureOpenAI\"), \" instead. Many third-party gateways support Chat Completions only; the examples below use \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"client.responses.*\"), \", so confirm your provider supports the Responses API (especially for tools like web search).\"), mdx(\"h3\", {\n    \"id\": \"basic-integration\"\n  }, \"Basic integration\"), mdx(\"p\", null, \"Pass a string as \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"input\"), \" and read \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"output_text\"), \" from the response.\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-js\"\n  }), \"const response = await client.responses.create({\\n  model: 'gpt-5.5',\\n  input: 'Write a one-sentence bedtime story about a unicorn.',\\n});\\n\\nconsole.log(response.output_text);\\n\")), mdx(\"h3\", {\n    \"id\": \"system-prompt\"\n  }, \"System prompt\"), mdx(\"p\", null, \"Use top-level \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"instructions\"), \" for stable behavior (tone, format, role). They take precedence over casual wording in the user message.\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-js\"\n  }), \"const response = await client.responses.create({\\n  model: 'gpt-5.5',\\n  instructions: 'Reply in one short sentence. Use plain language.',\\n  input: 'Explain what an LLM is.',\\n});\\n\\nconsole.log(response.output_text);\\n\")), mdx(\"h3\", {\n    \"id\": \"few-shot-prompting\"\n  }, \"Few-shot prompting\"), mdx(\"p\", null, \"Pass prior turns as an \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"input\"), \" array with \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"user\"), \" and \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"assistant\"), \" roles, then the new user message. Keep task rules in \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"instructions\"), \".\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-js\"\n  }), \"const response = await client.responses.create({\\n  model: 'gpt-5.5',\\n  instructions:\\n    'Classify sentiment as exactly one word: positive, negative, or neutral.',\\n  input: [\\n    { role: 'user', content: 'I love this!' },\\n    { role: 'assistant', content: 'positive' },\\n    { role: 'user', content: 'This is awful.' },\\n    { role: 'assistant', content: 'negative' },\\n    { role: 'user', content: 'It is fine I guess.' },\\n  ],\\n});\\n\\nconsole.log(response.output_text);\\n\")), mdx(\"h3\", {\n    \"id\": \"streaming\"\n  }, \"Streaming\"), mdx(\"p\", null, \"Set \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"stream: true\"), \" and handle \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"response.output_text.delta\"), \" events for incremental text.\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-js\"\n  }), \"const stream = await client.responses.create({\\n  model: 'gpt-5.5',\\n  input: 'List three colors.',\\n  stream: true,\\n});\\n\\nfor await (const event of stream) {\\n  if (event.type === 'response.output_text.delta') {\\n    process.stdout.write(event.delta);\\n  }\\n}\\n\")), mdx(\"h3\", {\n    \"id\": \"structured-output-with-json-schema\"\n  }, \"Structured output with JSON schema\"), mdx(\"p\", null, \"Constrain the model to JSON matching your schema via \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"text.format\"), \". With \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"strict: true\"), \", the output should match the schema.\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-js\"\n  }), \"const response = await client.responses.create({\\n  model: 'gpt-5.5',\\n  input: 'The film Inception was directed by Christopher Nolan.',\\n  text: {\\n    format: {\\n      type: 'json_schema',\\n      name: 'movie_summary',\\n      strict: true,\\n      schema: {\\n        type: 'object',\\n        properties: {\\n          title: { type: 'string' },\\n          director: { type: 'string' },\\n        },\\n        required: ['title', 'director'],\\n        additionalProperties: false,\\n      },\\n    },\\n  },\\n});\\n\\nconst data = JSON.parse(response.output_text);\\nconsole.log(data.title, data.director);\\n\")), mdx(\"p\", null, \"For typed parsing with Zod, you can use \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"client.responses.parse()\"), \" instead of \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"JSON.parse\"), \".\"), mdx(\"h3\", {\n    \"id\": \"web-search-tool\"\n  }, \"Web search tool\"), mdx(\"p\", null, \"Enable the built-in web search tool when the answer should use current information from the web.\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-js\"\n  }), \"const response = await client.responses.create({\\n  model: 'gpt-5.5',\\n  tools: [{ type: 'web_search' }],\\n  include: ['web_search_call.action.sources'],\\n  input: 'What was a major tech headline this week? Cite sources briefly.',\\n});\\n\\nconsole.log(response.output_text);\\n\")), mdx(\"p\", null, \"Web search adds latency and tool usage cost. Use a model that supports tools.\"));\n}\n;\nMDXContent.isMDXComponent = true;"}},"pageContext":{"id":"f1614aaa-0ca4-5ea5-ad92-0a046902285a"}},"staticQueryHashes":["1961101537","2542493696"]}