---
updatedAt: 2026-10-23T21:59:00.000Z
---

# Creates a model response for the given chat conversation.

Given a list of messages comprising a conversation, the model will return a response. Compatible with OpenAI. See https://platform.openai.com/docs/api-reference/chat/create

# OpenAPI definition

```json
{
  "openapi": "3.1.0",
  "info": {
    "title": "NVIDIA NIM API for nvidia/nemotron-3.5-bolt-e4b",
    "description": "The NVIDIA NIM REST API. Please see https://docs.api.nvidia.com/nim/reference/ for more details.",
    "version": "1.0.0",
    "termsOfService": "https://www.nvidia.com/en-us/data-center/products/nvidia-ai-enterprise/eula/",
    "contact": {
      "name": "NVIDIA Enterprise Support",
      "url": "https://www.nvidia.com/en-us/support/enterprise/"
    },
    "license": {
      "name": "OpenMDW License Agreement, version 1.1",
      "url": "https://github.com/OpenMDW/OpenMDW/blob/main/1.1/LICENSE.OpenMDW-1.1"
    }
  },
  "servers": [
    {
      "url": "https://integrate.api.nvidia.com/v1/"
    }
  ],
  "paths": {
    "/chat/completions": {
      "post": {
        "operationId": "nvidia-nemotron-3_5-bolt-e4b-infer",
        "tags": [
          "Chat"
        ],
        "summary": "Creates a model response for the given chat conversation.",
        "description": "Given a list of messages comprising a conversation, the model will return a response. Compatible with OpenAI. See https://platform.openai.com/docs/api-reference/chat/create",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ChatRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Invocation is fulfilled",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ChatCompletion"
                }
              },
              "text/event-stream": {
                "schema": {
                  "$ref": "#/components/schemas/ChatCompletionChunk"
                }
              }
            }
          },
          "202": {
            "description": "Result is pending. Client should poll using the requestId.",
            "content": {
              "application/json": {
                "example": {},
                "schema": {}
              }
            },
            "headers": {
              "NVCF-REQID": {
                "description": "requestId required for pooling",
                "schema": {
                  "type": "string",
                  "format": "uuid"
                }
              },
              "NVCF-STATUS": {
                "description": "Invocation status",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "description": "Invalid request parameters, model alias, or messages.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ValidationError"
                },
                "example": {
                  "message": "The 'messages' field cannot be empty.",
                  "type": "Bad Request",
                  "code": 400
                }
              }
            }
          },
          "422": {
            "description": "Validation failed, provided entity could not be processed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Errors"
                },
                "example": {
                  "type": "urn:nvcf-worker-service:problem-details:unprocessable-entity",
                  "title": "Unprocessable Entity",
                  "status": 422,
                  "detail": "string",
                  "instance": "/v2/nvcf/pexec/functions/9fd8dea3-511e-4771-bafb-e6f207d11cc8",
                  "requestId": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
                }
              }
            }
          },
          "500": {
            "description": "The invocation ended with an error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Errors"
                },
                "example": {
                  "type": "urn:nvcf-worker-service:problem-details:internal-server-error",
                  "title": "Internal Server Error",
                  "status": 500,
                  "detail": "string",
                  "instance": "/v2/nvcf/pexec/functions/9fd8dea3-511e-4771-bafb-e6f207d11cc8",
                  "requestId": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
                }
              }
            }
          }
        },
        "x-nvai-meta": {
          "name": "Create chat completion",
          "returns": "Returns a [chat completion](/docs/api-reference/chat/object) object, or a streamed sequence of [chat completion chunk](/docs/api-reference/chat/streaming) objects if the request is streamed.\n",
          "path": "create",
          "examples": [
            {
              "name": "Which number is larger, 9.11 or 9.8?",
              "requestJson": "{\n  \"model\": \"nvidia/nemotron-3.5-bolt-e4b\",\n  \"messages\": [\n    {\n      \"role\": \"user\",\n      \"content\": \"Which number is larger, 9.11 or 9.8?\"\n    }\n  ],\n  \"temperature\": 1.0,\n  \"top_p\": 0.95,\n  \"max_tokens\": 8192,\n  \"seed\": 42,\n  \"stream\": true,\n  \"skip_special_tokens\": false,\n  \"chat_template_kwargs\": {\"enable_thinking\": true}\n}\n",
              "responseJson": "{\n  \"id\": \"id-123\",\n  \"object\": \"chat.completion\",\n  \"created\": 1677652288,\n  \"model\": \"nvidia/nemotron-3.5-bolt-e4b\",\n  \"system_fingerprint\": \"fp_44709d6fcb\",\n  \"choices\": [{\n    \"index\": 0,\n    \"message\": {\n      \"role\": \"assistant\",\n      \"content\": \"The number 9.8 is larger...\"\n    },\n    \"finish_reason\": \"stop\"\n  }],\n  \"usage\": {\n    \"prompt_tokens\": 9,\n    \"completion_tokens\": 12,\n    \"total_tokens\": 21\n  }\n}\n"
            },
            {
              "name": "Summarize why GPU acceleration matters for deep learning in three concise bullet points.",
              "requestJson": "{\n  \"model\": \"nvidia/nemotron-3.5-bolt-e4b\",\n  \"messages\": [\n    {\n      \"role\": \"user\",\n      \"content\": \"Summarize why GPU acceleration matters for deep learning in three concise bullet points.\"\n    }\n  ],\n  \"temperature\": 1.0,\n  \"top_p\": 0.95,\n  \"max_tokens\": 8192,\n  \"seed\": 42,\n  \"stream\": true,\n  \"skip_special_tokens\": false,\n  \"chat_template_kwargs\": {\"enable_thinking\": true}\n}\n",
              "responseJson": "{\n  \"id\": \"id-123\",\n  \"object\": \"chat.completion\",\n  \"created\": 1677652288,\n  \"model\": \"nvidia/nemotron-3.5-bolt-e4b\",\n  \"system_fingerprint\": \"fp_44709d6fcb\",\n  \"choices\": [{\n    \"index\": 0,\n    \"message\": {\n      \"role\": \"assistant\",\n      \"content\": \"- GPUs accelerate matrix operations that dominate deep learning workloads.\\n- Faster training shortens experimentation cycles and improves researcher productivity.\\n- High parallelism makes large-model inference and serving more practical at scale.\"\n    },\n    \"finish_reason\": \"stop\"\n  }],\n  \"usage\": {\n    \"prompt_tokens\": 9,\n    \"completion_tokens\": 12,\n    \"total_tokens\": 21\n  }\n}\n"
            }
          ],
          "templates": [
            {
              "title": "Default",
              "requestEjs": {
                "python": "<%\n  request = { ...request, model: \"stg/nvidia/nemotron-3.5-bolt-e4b\" };\n  // Catalog ejs locals replace JSON with {stringify} only (spread skips non-enumerable parse).\n  const deepClone = (value) => {\n    if (Array.isArray(value)) return value.map(deepClone);\n    if (value && typeof value === \"object\") {\n      const out = {};\n      for (const key of Object.keys(value)) out[key] = deepClone(value[key]);\n      return out;\n    }\n    return value;\n  };\n  const mediaConfig = {\"image\": {\"mimeTypes\": {}}, \"video\": {\"mimeTypes\": {}}, \"audio\": {\"mimeTypes\": {}, \"defaultFormat\": \"wav\"}};\n  const stripNulls = (value) => {\n    if (Array.isArray(value)) return value.map(stripNulls);\n    if (value && typeof value === \"object\") {\n      const out = {};\n      for (const [key, item] of Object.entries(value)) {\n        if (item === null || item === undefined) continue;\n        out[key] = stripNulls(item);\n      }\n      return out;\n    }\n    return value;\n  };\n  const payloadForSnippet = stripNulls(deepClone(request || {}));\n  const hasStream = payloadForSnippet.stream !== undefined && payloadForSnippet.stream !== null;\n  const pyStream = payloadForSnippet.stream ? \"True\" : \"False\";\n  if (hasStream) payloadForSnippet.stream = \"__STREAM__\";\n\n  const hasMediaKind = (kind) => Object.keys(mediaConfig[kind].mimeTypes || {}).length > 0;\n  const isInlineDataUrl = (url, kind) => (\n    typeof url === \"string\" && new RegExp(`^data:${kind}/[^;]+;base64,`, \"i\").test(url)\n  );\n\n  const mediaUrl = (part, key) => {\n    const slot = part?.[key];\n    return typeof slot === \"string\" ? slot : slot?.url;\n  };\n  const setMediaUrl = (part, key, url) => {\n    if (typeof part[key] === \"string\") part[key] = url;\n    else {\n      if (!part[key] || typeof part[key] !== \"object\") part[key] = {};\n      part[key].url = url;\n    }\n  };\n\n  let imageCount = 0;\n  let videoCount = 0;\n  let audioCount = 0;\n\n  (payloadForSnippet.messages || []).forEach((message) => {\n    if (!Array.isArray(message?.content)) return;\n    message.content.forEach((part) => {\n      const imageUrl = mediaUrl(part, \"image_url\");\n      const videoUrl = mediaUrl(part, \"video_url\");\n      const audioUrl = mediaUrl(part, \"audio_url\");\n      // File helpers only for inline base64; http(s) URLs stay as-is in the payload.\n      if (hasMediaKind(\"image\") && part?.type === \"image_url\" && isInlineDataUrl(imageUrl, \"image\")) {\n        setMediaUrl(part, \"image_url\", `__IMAGE_DATA_URL_${imageCount}__`);\n        imageCount += 1;\n      } else if (hasMediaKind(\"video\") && part?.type === \"video_url\" && isInlineDataUrl(videoUrl, \"video\")) {\n        setMediaUrl(part, \"video_url\", `__VIDEO_DATA_URL_${videoCount}__`);\n        videoCount += 1;\n      } else if (hasMediaKind(\"audio\") && part?.type === \"audio_url\" && isInlineDataUrl(audioUrl, \"audio\")) {\n        setMediaUrl(part, \"audio_url\", `__AUDIO_DATA_URL_${audioCount}__`);\n        audioCount += 1;\n      } else if (hasMediaKind(\"audio\") && part?.type === \"input_audio\" && part.input_audio?.data) {\n        part.input_audio.data = `__AUDIO_B64_${audioCount}__`;\n        part.input_audio.format = part.input_audio.format || mediaConfig.audio.defaultFormat;\n        audioCount += 1;\n      }\n    });\n  });\n\n  const pyRepr = (value, level = 0) => {\n    if (value === null) return \"None\";\n    if (typeof value === \"boolean\") return value ? \"True\" : \"False\";\n    if (typeof value === \"number\") return String(value);\n    if (typeof value === \"string\") return JSON.stringify(value);\n    const pad = \" \".repeat(level);\n    const innerPad = \" \".repeat(level + 2);\n    if (Array.isArray(value)) {\n      if (value.length === 0) return \"[]\";\n      return \"[\\n\" + value.map((item) => `${innerPad}${pyRepr(item, level + 2)}`).join(\",\\n\") + \"\\n\" + pad + \"]\";\n    }\n    if (typeof value === \"object\") {\n      const entries = Object.entries(value);\n      if (entries.length === 0) return \"{}\";\n      return \"{\\n\" + entries.map(([key, item]) => `${innerPad}${JSON.stringify(key)}: ${pyRepr(item, level + 2)}`).join(\",\\n\") + \"\\n\" + pad + \"}\";\n    }\n    return \"None\";\n  };\n\n  const replaceAll = (s, a, b) => s.split(a).join(b);\n  let renderedPayload = pyRepr(payloadForSnippet);\n  if (hasStream) renderedPayload = replaceAll(renderedPayload, '\"__STREAM__\"', \"stream\");\n  for (let i = 0; i < imageCount; i++) {\n    renderedPayload = replaceAll(renderedPayload, `\"__IMAGE_DATA_URL_${i}__\"`, `image_data_urls[${i}]`);\n  }\n  for (let i = 0; i < videoCount; i++) {\n    renderedPayload = replaceAll(renderedPayload, `\"__VIDEO_DATA_URL_${i}__\"`, `video_data_urls[${i}]`);\n  }\n  for (let i = 0; i < audioCount; i++) {\n    renderedPayload = replaceAll(renderedPayload, `\"__AUDIO_DATA_URL_${i}__\"`, `audio_data_urls[${i}]`);\n    renderedPayload = replaceAll(renderedPayload, `\"__AUDIO_B64_${i}__\"`, `audio_b64s[${i}]`);\n  }\n\n  // Either file helpers XOR inline base64 - never emit unused helpers.\n  const usesFileHelpers =\n    imageCount + videoCount + audioCount > 0 &&\n    [...Array(imageCount).keys()].every((i) => renderedPayload.includes(`image_data_urls[${i}]`)) &&\n    [...Array(videoCount).keys()].every((i) => renderedPayload.includes(`video_data_urls[${i}]`)) &&\n    [...Array(audioCount).keys()].every(\n      (i) => renderedPayload.includes(`audio_data_urls[${i}]`) || renderedPayload.includes(`audio_b64s[${i}]`)\n    );\n  if (!usesFileHelpers) {\n    imageCount = 0;\n    videoCount = 0;\n    audioCount = 0;\n    const restored = stripNulls(deepClone(request || {}));\n    const restoredStream = restored.stream !== undefined && restored.stream !== null;\n    if (restoredStream) restored.stream = \"__STREAM__\";\n    renderedPayload = pyRepr(restored);\n    if (restoredStream) renderedPayload = replaceAll(renderedPayload, '\"__STREAM__\"', \"stream\");\n  }\n  const hasMedia = usesFileHelpers;\n  const mimePy = (mimes) =>\n    \"{\" + Object.entries(mimes).map(([k, v]) => `${JSON.stringify(k)}: ${JSON.stringify(v)}`).join(\", \") + \"}\";\n%>\n<% if (hasMedia) { %>import base64\nfrom pathlib import Path\n<% } %>import requests\n\ninvoke_url = \"https://integrate.api.nvidia.com/v1/chat/completions\"\nstream = <%- pyStream %>\n<% if (hasMedia) { %>\ndef media_data_url(kind, index, mime_types):\n    for suffix, mime in mime_types.items():\n        path = Path(f\"{kind}_{index}{suffix}\")\n        if path.exists():\n            return f\"data:{mime};base64,{base64.b64encode(path.read_bytes()).decode()}\"\n    raise FileNotFoundError(f\"Expected {kind}_{index} with suffix in {list(mime_types)}\")\n<% if (imageCount > 0) { %>\nimage_data_urls = [media_data_url(\"image\", i, <%- mimePy(mediaConfig.image.mimeTypes) %>) for i in <%- imageCount === 1 ? \"[1]\" : (\"range(1, \" + (imageCount + 1) + \")\") %>]\n<% } %><% if (videoCount > 0) { %>\nvideo_data_urls = [media_data_url(\"video\", i, <%- mimePy(mediaConfig.video.mimeTypes) %>) for i in <%- videoCount === 1 ? \"[1]\" : (\"range(1, \" + (videoCount + 1) + \")\") %>]\n<% } %><% if (audioCount > 0) { %>\naudio_data_urls = [media_data_url(\"audio\", i, <%- mimePy(mediaConfig.audio.mimeTypes) %>) for i in <%- audioCount === 1 ? \"[1]\" : (\"range(1, \" + (audioCount + 1) + \")\") %>]\naudio_b64s = [url.split(\",\", 1)[1] for url in audio_data_urls]\n<% } %><% } %>\nheaders = {\n    \"Authorization\": \"Bearer $NVIDIA_API_KEY\",\n    \"Accept\": \"text/event-stream\" if stream else \"application/json\",\n}\n\npayload = <%- renderedPayload %>\n\nresponse = requests.post(invoke_url, headers=headers, json=payload, stream=stream)\nif stream:\n    for line in response.iter_lines():\n        if line:\n            print(line.decode(\"utf-8\"))\nelse:\n    print(response.json())\n",
                "langChain": "<%\n  request = { ...request, model: \"stg/nvidia/nemotron-3.5-bolt-e4b\" };\n  const deepClone = (value) => {\n    if (Array.isArray(value)) return value.map(deepClone);\n    if (value && typeof value === \"object\") {\n      const out = {};\n      for (const key of Object.keys(value)) out[key] = deepClone(value[key]);\n      return out;\n    }\n    return value;\n  };\n  const mediaConfig = {\"image\": {\"mimeTypes\": {}}, \"video\": {\"mimeTypes\": {}}, \"audio\": {\"mimeTypes\": {}, \"defaultFormat\": \"wav\"}};\n  const payloadForSnippet = deepClone(request || {});\n  const messagesForSnippet = deepClone(payloadForSnippet.messages || []);\n  const hasMediaKind = (kind) => Object.keys(mediaConfig[kind].mimeTypes || {}).length > 0;\n  const isInlineDataUrl = (url, kind) => (\n    typeof url === \"string\" && new RegExp(`^data:${kind}/[^;]+;base64,`, \"i\").test(url)\n  );\n\n  const mediaUrl = (part, key) => {\n    const slot = part?.[key];\n    return typeof slot === \"string\" ? slot : slot?.url;\n  };\n  const setMediaUrl = (part, key, url) => {\n    if (typeof part[key] === \"string\") part[key] = url;\n    else {\n      if (!part[key] || typeof part[key] !== \"object\") part[key] = {};\n      part[key].url = url;\n    }\n  };\n\n  let imageCount = 0;\n  let hasUnsupportedMedia = false;\n  messagesForSnippet.forEach((message) => {\n    if (!Array.isArray(message?.content)) return;\n    message.content.forEach((part) => {\n      const imageUrl = mediaUrl(part, \"image_url\");\n      if (hasMediaKind(\"image\") && part?.type === \"image_url\" && isInlineDataUrl(imageUrl, \"image\")) {\n        setMediaUrl(part, \"image_url\", `__IMAGE_DATA_URL_${imageCount}__`);\n        imageCount += 1;\n      } else if (part?.type === \"video_url\" && isInlineDataUrl(mediaUrl(part, \"video_url\"), \"video\")) {\n        // LangChain cannot ship local file helpers for video; reject inline only.\n        hasUnsupportedMedia = true;\n        setMediaUrl(part, \"video_url\", \"__UNSUPPORTED_MEDIA_DATA__\");\n      } else if (part?.type === \"audio_url\" && isInlineDataUrl(mediaUrl(part, \"audio_url\"), \"audio\")) {\n        hasUnsupportedMedia = true;\n        setMediaUrl(part, \"audio_url\", \"__UNSUPPORTED_MEDIA_DATA__\");\n      } else if (part?.type === \"input_audio\" && part.input_audio?.data) {\n        hasUnsupportedMedia = true;\n        part.input_audio.data = \"__UNSUPPORTED_MEDIA_DATA__\";\n      }\n    });\n  });\n\n  const pyRepr = (value, level = 0) => {\n    if (value === null) return \"None\";\n    if (typeof value === \"boolean\") return value ? \"True\" : \"False\";\n    if (typeof value === \"number\") return String(value);\n    if (typeof value === \"string\") return JSON.stringify(value);\n    const pad = \" \".repeat(level);\n    const innerPad = \" \".repeat(level + 2);\n    if (Array.isArray(value)) {\n      if (value.length === 0) return \"[]\";\n      return \"[\\n\" + value.map((item) => `${innerPad}${pyRepr(item, level + 2)},`).join(\"\\n\") + \"\\n\" + pad + \"]\";\n    }\n    if (typeof value === \"object\") {\n      const entries = Object.entries(value);\n      if (entries.length === 0) return \"{}\";\n      return \"{\\n\" + entries.map(([key, item]) => `${innerPad}${JSON.stringify(key)}: ${pyRepr(item, level + 2)},`).join(\"\\n\") + \"\\n\" + pad + \"}\";\n    }\n    return \"None\";\n  };\n\n  const replaceAll = (s, a, b) => s.split(a).join(b);\n  let renderedMessages = pyRepr(messagesForSnippet);\n  for (let i = 0; i < imageCount; i++) {\n    renderedMessages = replaceAll(renderedMessages, `\"__IMAGE_DATA_URL_${i}__\"`, `image_data_urls[${i}]`);\n  }\n  // Either file helpers XOR inline base64 - never emit unused helpers.\n  const usesFileHelpers =\n    imageCount > 0 &&\n    [...Array(imageCount).keys()].every((i) => renderedMessages.includes(`image_data_urls[${i}]`));\n  if (!usesFileHelpers) {\n    imageCount = 0;\n    renderedMessages = pyRepr(deepClone((request || {}).messages || []));\n  }\n  const invokeOptions = deepClone(request || {});\n  for (const key of [\"model\", \"messages\", \"stream\", \"temperature\", \"top_p\", \"max_tokens\", \"tools\"]) {\n    delete invokeOptions[key];\n  }\n  if (request.tools?.length) delete invokeOptions.tool_choice;\n%>\nfrom langchain_nvidia_ai_endpoints import ChatNVIDIA\n<% if (imageCount > 0) { %>from pathlib import Path\nimport base64\n<% } %>\n\nclient = ChatNVIDIA(\n  model=\"<%- request.model %>\",\n  api_key=\"$NVIDIA_API_KEY\",\n<% if (request.temperature !== undefined && request.temperature !== null) { %>\n  temperature=<%- request.temperature %>,\n<% } %>\n<% if (request.top_p !== undefined && request.top_p !== null) { %>\n  top_p=<%- request.top_p %>,\n<% } %>\n<% if (request.max_tokens !== undefined && request.max_tokens !== null) { %>\n  max_completion_tokens=<%- request.max_tokens %>,\n<% } %>\n)\n<% if (request.tools?.length) { %>\nclient = client.bind_tools(\n  <%- pyRepr(request.tools) %><% if (request.tool_choice !== undefined && request.tool_choice !== null) { %>,\n  tool_choice=<%- pyRepr(request.tool_choice) %><% } %>\n)\n<% } %>\ninvoke_options = <%- pyRepr(invokeOptions) %>\n<% if (imageCount > 0) { %>\ndef find_image_path(index):\n  image_mime_types = <%- pyRepr(mediaConfig.image.mimeTypes) %>\n  for suffix in image_mime_types:\n    path = Path(f\"image_{index}{suffix}\")\n    if path.exists():\n      return path\n  expected = \"/\".join(f\".{suffix.lstrip('.')}\" for suffix in image_mime_types)\n  raise FileNotFoundError(f\"Expected image_{index}{expected}\")\n\ndef read_image_data_url(path):\n  image_mime_types = <%- pyRepr(mediaConfig.image.mimeTypes) %>\n  with open(path, \"rb\") as f:\n    image_b64 = base64.b64encode(f.read()).decode()\n  return f\"data:{image_mime_types[path.suffix.lower()]};base64,{image_b64}\"\n\nimage_data_urls = [read_image_data_url(find_image_path(i)) for i in range(1, <%- imageCount + 1 %>)]\n<% } %><% if (hasUnsupportedMedia) { %>\nraise ValueError(\"LangChain snippet currently supports text and image input. Use Python, Node.js, or Shell for video or audio input.\")\n<% } %>\nlc_messages = <%- renderedMessages %>\n<% if (request.stream) { %>\nfor chunk in client.stream(lc_messages, **invoke_options):\n  if chunk.additional_kwargs and \"reasoning_content\" in chunk.additional_kwargs:\n    print(chunk.additional_kwargs[\"reasoning_content\"], end=\"\")\n  print(chunk.content, end=\"\")\n  if chunk.tool_call_chunks:\n    print(chunk.tool_call_chunks)\n<% } else { %>\nresponse = client.invoke(lc_messages, **invoke_options)\nif response.additional_kwargs and \"reasoning_content\" in response.additional_kwargs:\n  print(response.additional_kwargs[\"reasoning_content\"])\nprint(response.content)\nif response.tool_calls:\n  print(response.tool_calls)\n<% } %>\n",
                "node.js": "<%\n  request = { ...request, model: \"stg/nvidia/nemotron-3.5-bolt-e4b\" };\n  const deepClone = (value) => {\n    if (Array.isArray(value)) return value.map(deepClone);\n    if (value && typeof value === \"object\") {\n      const out = {};\n      for (const key of Object.keys(value)) out[key] = deepClone(value[key]);\n      return out;\n    }\n    return value;\n  };\n  const mediaConfig = {\"image\": {\"mimeTypes\": {}}, \"video\": {\"mimeTypes\": {}}, \"audio\": {\"mimeTypes\": {}, \"defaultFormat\": \"wav\"}};\n  const payloadForSnippet = deepClone(request || {});\n  const hasStream = payloadForSnippet.stream !== undefined && payloadForSnippet.stream !== null;\n  if (hasStream) payloadForSnippet.stream = \"__STREAM__\";\n\n  const hasMediaKind = (kind) => Object.keys(mediaConfig[kind].mimeTypes || {}).length > 0;\n  const isInlineDataUrl = (url, kind) => (\n    typeof url === \"string\" && new RegExp(`^data:${kind}/[^;]+;base64,`, \"i\").test(url)\n  );\n\n  let imageCount = 0;\n  let videoCount = 0;\n  let audioCount = 0;\n  (payloadForSnippet.messages || []).forEach((message) => {\n    if (!Array.isArray(message?.content)) return;\n    message.content.forEach((part) => {\n      if (hasMediaKind(\"image\") && part?.type === \"image_url\" && isInlineDataUrl(part.image_url?.url, \"image\")) {\n        part.image_url.url = `__IMAGE_DATA_URL_${imageCount}__`;\n        imageCount += 1;\n      } else if (hasMediaKind(\"video\") && part?.type === \"video_url\" && isInlineDataUrl(part.video_url?.url, \"video\")) {\n        part.video_url.url = `__VIDEO_DATA_URL_${videoCount}__`;\n        videoCount += 1;\n      } else if (hasMediaKind(\"audio\") && part?.type === \"audio_url\" && isInlineDataUrl(part.audio_url?.url, \"audio\")) {\n        part.audio_url.url = `__AUDIO_DATA_URL_${audioCount}__`;\n        audioCount += 1;\n      } else if (hasMediaKind(\"audio\") && part?.type === \"input_audio\" && part.input_audio?.data) {\n        part.input_audio.data = `__AUDIO_B64_${audioCount}__`;\n        part.input_audio.format = part.input_audio.format || mediaConfig.audio.defaultFormat;\n        audioCount += 1;\n      }\n    });\n  });\n\n  const replaceAll = (s, a, b) => s.split(a).join(b);\n  let renderedPayload = JSON.stringify(payloadForSnippet, null, 2);\n  if (hasStream) renderedPayload = replaceAll(renderedPayload, '\"__STREAM__\"', \"stream\");\n  for (let i = 0; i < imageCount; i++) {\n    renderedPayload = replaceAll(renderedPayload, `\"__IMAGE_DATA_URL_${i}__\"`, `imageDataUrls[${i}]`);\n  }\n  for (let i = 0; i < videoCount; i++) {\n    renderedPayload = replaceAll(renderedPayload, `\"__VIDEO_DATA_URL_${i}__\"`, `videoDataUrls[${i}]`);\n  }\n  for (let i = 0; i < audioCount; i++) {\n    renderedPayload = replaceAll(renderedPayload, `\"__AUDIO_DATA_URL_${i}__\"`, `audioDataUrls[${i}]`);\n    renderedPayload = replaceAll(renderedPayload, `\"__AUDIO_B64_${i}__\"`, `audioB64s[${i}]`);\n  }\n  // Either file helpers XOR inline base64 - never emit unused helpers.\n  const usesFileHelpers =\n    imageCount + videoCount + audioCount > 0 &&\n    [...Array(imageCount).keys()].every((i) => renderedPayload.includes(`imageDataUrls[${i}]`)) &&\n    [...Array(videoCount).keys()].every((i) => renderedPayload.includes(`videoDataUrls[${i}]`)) &&\n    [...Array(audioCount).keys()].every(\n      (i) => renderedPayload.includes(`audioDataUrls[${i}]`) || renderedPayload.includes(`audioB64s[${i}]`)\n    );\n  if (!usesFileHelpers) {\n    imageCount = 0;\n    videoCount = 0;\n    audioCount = 0;\n    const restored = deepClone(request || {});\n    const restoredStream = restored.stream !== undefined && restored.stream !== null;\n    if (restoredStream) restored.stream = \"__STREAM__\";\n    renderedPayload = JSON.stringify(restored, null, 2);\n    if (restoredStream) renderedPayload = replaceAll(renderedPayload, '\"__STREAM__\"', \"stream\");\n  }\n  const hasMedia = usesFileHelpers;\n%>\nimport axios from 'axios';\n<% if (hasMedia) { %>import { existsSync } from 'node:fs';\nimport { readFile } from 'node:fs/promises';\nimport { extname } from 'node:path';\n<% } %>\n\nconst invokeUrl = \"https://integrate.api.nvidia.com/v1/chat/completions\";\nconst stream = <%- Boolean(request.stream) %>;\n\nconst headers = {\n  \"Authorization\": \"Bearer $NVIDIA_API_KEY\",\n  \"Accept\": stream ? \"text/event-stream\" : \"application/json\"\n};\n<% if (hasMedia) { %>\nfunction findMediaPath(kind, index, mimeTypes) {\n  for (const suffix of Object.keys(mimeTypes)) {\n    const path = `${kind}_${index}${suffix}`;\n    if (existsSync(path)) {\n      return path;\n    }\n  }\n  const expected = Object.keys(mimeTypes).join(\"/\");\n  throw new Error(`Expected ${kind}_${index}${expected}`);\n}\n\nasync function readMediaB64(path) {\n  return Buffer.from(await readFile(path)).toString('base64');\n}\n\nfunction mediaDataUrl(path, mediaB64, mimeTypes) {\n  return `data:${mimeTypes[extname(path).toLowerCase()]};base64,${mediaB64}`;\n}\n<% } %>\nasync function main() {\n<% if (imageCount > 0) { %>  const imageMimeTypes = <%- JSON.stringify(mediaConfig.image.mimeTypes, null, 2) %>;\n  const imagePaths = [<% for (let i = 1; i <= imageCount; i++) { %>findMediaPath(\"image\", <%- i %>, imageMimeTypes)<%- i < imageCount ? \", \" : \"\" %><% } %>];\n  const imageB64s = await Promise.all(imagePaths.map(readMediaB64));\n  const imageDataUrls = imagePaths.map((path, index) => mediaDataUrl(path, imageB64s[index], imageMimeTypes));\n<% } %><% if (videoCount > 0) { %>  const videoMimeTypes = <%- JSON.stringify(mediaConfig.video.mimeTypes, null, 2) %>;\n  const videoPaths = [<% for (let i = 1; i <= videoCount; i++) { %>findMediaPath(\"video\", <%- i %>, videoMimeTypes)<%- i < videoCount ? \", \" : \"\" %><% } %>];\n  const videoB64s = await Promise.all(videoPaths.map(readMediaB64));\n  const videoDataUrls = videoPaths.map((path, index) => mediaDataUrl(path, videoB64s[index], videoMimeTypes));\n<% } %><% if (audioCount > 0) { %>  const audioMimeTypes = <%- JSON.stringify(mediaConfig.audio.mimeTypes, null, 2) %>;\n  const audioPaths = [<% for (let i = 1; i <= audioCount; i++) { %>findMediaPath(\"audio\", <%- i %>, audioMimeTypes)<%- i < audioCount ? \", \" : \"\" %><% } %>];\n  const audioB64s = await Promise.all(audioPaths.map(readMediaB64));\n  const audioDataUrls = audioPaths.map((path, index) => mediaDataUrl(path, audioB64s[index], audioMimeTypes));\n<% } %>  const payload = <%- renderedPayload %>;\n\n  const response = await axios.post(invokeUrl, payload, {\n    headers: headers,\n    responseType: stream ? 'stream' : 'json'\n  });\n\n  if (stream) {\n    response.data.on('data', (chunk) => {\n      console.log(chunk.toString());\n    });\n  } else {\n    console.log(JSON.stringify(response.data));\n  }\n}\n\nmain().catch(error => {\n  if (error.response) {\n    console.error(`HTTP ${error.response.status}`);\n    if (error.response.data?.on) {\n      error.response.data.on('data', (chunk) => console.error(chunk.toString()));\n    } else {\n      console.error(error.response.data);\n    }\n  } else {\n    console.error(error);\n  }\n});\n",
                "curl": "<%\n  request = { ...request, model: \"stg/nvidia/nemotron-3.5-bolt-e4b\" };\n  const deepClone = (value) => {\n    if (Array.isArray(value)) return value.map(deepClone);\n    if (value && typeof value === \"object\") {\n      const out = {};\n      for (const key of Object.keys(value)) out[key] = deepClone(value[key]);\n      return out;\n    }\n    return value;\n  };\n  const mediaConfig = {\"image\": {\"mimeTypes\": {}}, \"video\": {\"mimeTypes\": {}}, \"audio\": {\"mimeTypes\": {}, \"defaultFormat\": \"wav\"}};\n  const payloadForSnippet = deepClone(request || {});\n  const hasMediaKind = (kind) => Object.keys(mediaConfig[kind].mimeTypes || {}).length > 0;\n  const isInlineDataUrl = (url, kind) => (\n    typeof url === \"string\" && new RegExp(`^data:${kind}/[^;]+;base64,`, \"i\").test(url)\n  );\n\n  let imageCount = 0;\n  let videoCount = 0;\n  let audioCount = 0;\n  (payloadForSnippet.messages || []).forEach((message) => {\n    if (!Array.isArray(message?.content)) return;\n    message.content.forEach((part) => {\n      if (hasMediaKind(\"image\") && part?.type === \"image_url\" && isInlineDataUrl(part.image_url?.url, \"image\")) {\n        part.image_url.url = `__IMAGE_DATA_URL_${imageCount}__`;\n        imageCount += 1;\n      } else if (hasMediaKind(\"video\") && part?.type === \"video_url\" && isInlineDataUrl(part.video_url?.url, \"video\")) {\n        part.video_url.url = `__VIDEO_DATA_URL_${videoCount}__`;\n        videoCount += 1;\n      } else if (hasMediaKind(\"audio\") && part?.type === \"audio_url\" && isInlineDataUrl(part.audio_url?.url, \"audio\")) {\n        part.audio_url.url = `__AUDIO_DATA_URL_${audioCount}__`;\n        audioCount += 1;\n      } else if (hasMediaKind(\"audio\") && part?.type === \"input_audio\" && part.input_audio?.data) {\n        part.input_audio.data = `__AUDIO_B64_${audioCount}__`;\n        part.input_audio.format = part.input_audio.format || mediaConfig.audio.defaultFormat;\n        audioCount += 1;\n      }\n    });\n  });\n\n  const replaceAll = (s, a, b) => s.split(a).join(b);\n  const escapeHeredoc = (text) => text.replaceAll(\"\\\\\", \"\\\\\\\\\").replaceAll(\"$\", \"\\\\$\").replaceAll(\"`\", \"\\\\`\");\n  let renderedPayload = escapeHeredoc(JSON.stringify(payloadForSnippet, null, 2));\n  for (let i = 0; i < imageCount; i++) {\n    renderedPayload = replaceAll(renderedPayload, `\"__IMAGE_DATA_URL_${i}__\"`, `\"${\"${\"}image_${i + 1}_data_url}\"`);\n  }\n  for (let i = 0; i < videoCount; i++) {\n    renderedPayload = replaceAll(renderedPayload, `\"__VIDEO_DATA_URL_${i}__\"`, `\"${\"${\"}video_${i + 1}_data_url}\"`);\n  }\n  for (let i = 0; i < audioCount; i++) {\n    renderedPayload = replaceAll(renderedPayload, `\"__AUDIO_DATA_URL_${i}__\"`, `\"${\"${\"}audio_${i + 1}_data_url}\"`);\n    renderedPayload = replaceAll(renderedPayload, `\"__AUDIO_B64_${i}__\"`, `\"${\"${\"}audio_${i + 1}_b64}\"`);\n  }\n  // Either file helpers XOR inline base64 - never emit unused helpers.\n  const usesFileHelpers =\n    imageCount + videoCount + audioCount > 0 &&\n    [...Array(imageCount).keys()].every((i) => renderedPayload.includes(`image_${i + 1}_data_url`)) &&\n    [...Array(videoCount).keys()].every((i) => renderedPayload.includes(`video_${i + 1}_data_url`)) &&\n    [...Array(audioCount).keys()].every(\n      (i) => renderedPayload.includes(`audio_${i + 1}_data_url`) || renderedPayload.includes(`audio_${i + 1}_b64`)\n    );\n  if (!usesFileHelpers) {\n    imageCount = 0;\n    videoCount = 0;\n    audioCount = 0;\n    renderedPayload = escapeHeredoc(JSON.stringify(deepClone(request || {}), null, 2));\n  }\n  const hasMedia = usesFileHelpers;\n%>\nstream=<%- request.stream ? \"true\" : \"false\" %>\nif [ \"$stream\" = true ]; then\n    accept_header='Accept: text/event-stream'\nelse\n    accept_header='Accept: application/json'\nfi\n<% if (hasMedia) { %>\nmime_type_for() {\n  case \"$1\" in\n<% for (const [suffix, mimeType] of Object.entries({...mediaConfig.image.mimeTypes, ...mediaConfig.video.mimeTypes, ...mediaConfig.audio.mimeTypes})) { %>    *<%- suffix %>) echo \"<%- mimeType %>\" ;;\n<% } %>    *) echo \"Unsupported media file: $1\" >&2; return 1 ;;\n  esac\n}\n\nfind_media_path() {\n  local kind=\"$1\"\n  local index=\"$2\"\n  shift 2\n  local ext path\n  for ext in \"$@\"; do\n    path=\"${kind}_${index}.${ext}\"\n    if [ -f \"$path\" ]; then\n      echo \"$path\"\n      return 0\n    fi\n  done\n  echo \"Expected ${kind}_${index}.$*\" >&2\n  return 1\n}\n\nmedia_b64() {\n  base64 < \"$1\" | tr -d '\\n'\n}\n\nmedia_data_url() {\n  local path=\"$1\"\n  local mime_type media_base64\n  mime_type=$(mime_type_for \"$path\") || return 1\n  media_base64=$(media_b64 \"$path\") || return 1\n  printf 'data:%s;base64,%s' \"$mime_type\" \"$media_base64\"\n}\n<% for (let i = 1; i <= imageCount; i++) { %>\nimage_<%- i %>_path=$(find_media_path image <%- i %><% for (const suffix of Object.keys(mediaConfig.image.mimeTypes)) { %> <%- suffix.slice(1) %><% } %>)\nimage_<%- i %>_data_url=$(media_data_url \"$image_<%- i %>_path\")\n<% } %><% for (let i = 1; i <= videoCount; i++) { %>\nvideo_<%- i %>_path=$(find_media_path video <%- i %><% for (const suffix of Object.keys(mediaConfig.video.mimeTypes)) { %> <%- suffix.slice(1) %><% } %>)\nvideo_<%- i %>_data_url=$(media_data_url \"$video_<%- i %>_path\")\n<% } %><% for (let i = 1; i <= audioCount; i++) { %>\naudio_<%- i %>_path=$(find_media_path audio <%- i %><% for (const suffix of Object.keys(mediaConfig.audio.mimeTypes)) { %> <%- suffix.slice(1) %><% } %>)\naudio_<%- i %>_b64=$(media_b64 \"$audio_<%- i %>_path\")\naudio_<%- i %>_data_url=$(media_data_url \"$audio_<%- i %>_path\")\n<% } %><% } %>\ncat > payload.json <<JSON\n<%- renderedPayload %>\nJSON\n\ncurl https://integrate.api.nvidia.com/v1/chat/completions \\\n  -H \"Authorization: Bearer $NVIDIA_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -H \"$accept_header\" \\\n  -d @payload.json"
              }
            }
          ]
        }
      }
    }
  },
  "security": [
    {
      "Token": []
    }
  ],
  "components": {
    "securitySchemes": {
      "Token": {
        "type": "http",
        "scheme": "bearer"
      }
    },
    "schemas": {
      "Errors": {
        "properties": {
          "type": {
            "type": "string",
            "description": "Error type"
          },
          "title": {
            "type": "string",
            "description": "Error title"
          },
          "status": {
            "type": "integer",
            "description": "Error status code"
          },
          "detail": {
            "type": "string",
            "description": "Detailed information about the error"
          },
          "instance": {
            "type": "string",
            "description": "Function instance used to invoke the request"
          },
          "requestId": {
            "type": "string",
            "format": "uuid",
            "description": "UUID of the request"
          }
        },
        "type": "object",
        "required": [
          "type",
          "title",
          "status",
          "detail",
          "instance",
          "requestId"
        ],
        "title": "InvokeError"
      },
      "ChatCompletion": {
        "properties": {
          "id": {
            "description": "A unique identifier for the completion.",
            "title": "Id",
            "type": "string"
          },
          "choices": {
            "description": "The list of completion choices the model generated for the input prompt.",
            "items": {
              "$ref": "#/components/schemas/Choice"
            },
            "title": "Choices",
            "type": "array"
          },
          "usage": {
            "allOf": [
              {
                "$ref": "#/components/schemas/Usage"
              }
            ],
            "description": "Usage statistics for the completion request."
          },
          "object": {
            "type": "string"
          },
          "created": {
            "type": "integer"
          },
          "model": {
            "type": "string",
            "description": "The serving function's primary registered model name; this may differ from a requested alias."
          }
        },
        "required": [
          "id",
          "choices",
          "usage"
        ],
        "title": "ChatCompletion",
        "type": "object"
      },
      "ChatCompletionChunk": {
        "properties": {
          "id": {
            "description": "A unique identifier for the completion.",
            "title": "Id",
            "type": "string"
          },
          "choices": {
            "description": "The list of completion choices the model generated for the input prompt.",
            "items": {
              "$ref": "#/components/schemas/ChoiceChunk"
            },
            "title": "Choices",
            "type": "array"
          },
          "object": {
            "type": "string"
          },
          "created": {
            "type": "integer"
          },
          "model": {
            "type": "string",
            "description": "The serving function's primary registered model name; this may differ from a requested alias."
          },
          "usage": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Usage"
              },
              {
                "type": "null"
              }
            ]
          }
        },
        "required": [
          "id",
          "choices"
        ],
        "title": "ChatCompletionChunk",
        "type": "object"
      },
      "ChatRequest": {
        "additionalProperties": false,
        "properties": {
          "model": {
            "type": "string",
            "title": "Model",
            "default": "nvidia/nemotron-3.5-bolt-e4b",
            "description": "The Build playground adds its staging prefix automatically. Standalone gateway requests use stg/nvidia/nemotron-3.5-bolt-e4b."
          },
          "messages": {
            "description": "Conversation messages. System and developer instructions, user messages, assistant responses, and tool results are supported. Include tool_call_id on tool results.",
            "examples": [
              [
                {
                  "content": "I am going to Paris, what should I see?",
                  "role": "user"
                }
              ]
            ],
            "items": {
              "$ref": "#/components/schemas/Message"
            },
            "title": "Messages",
            "type": "array",
            "minItems": 1
          },
          "temperature": {
            "default": 1,
            "description": "The sampling temperature to use for text generation. The higher the temperature value is, the less deterministic the output text will be. It is not recommended to modify both temperature and top_p in the same call.",
            "maximum": 2,
            "title": "Temperature",
            "type": "number",
            "minimum": 0
          },
          "top_p": {
            "default": 0.95,
            "description": "The top-p sampling mass used for text generation. The top-p value determines the probability mass that is sampled at sampling time. For example, if top_p = 0.2, only the most likely tokens (summing to 0.2 cumulative probability) will be sampled. It is not recommended to modify both temperature and top_p in the same call.",
            "maximum": 1,
            "exclusiveMinimum": 0,
            "title": "Top P",
            "type": "number"
          },
          "max_tokens": {
            "default": 1024,
            "description": "The maximum number of tokens to generate in any given call. Note that the model is not aware of this value, and generation will simply stop at the number of tokens specified. The hosted function caps completion budgets at 65536 tokens.",
            "maximum": 65536,
            "minimum": 1,
            "title": "Max Tokens",
            "type": "integer"
          },
          "seed": {
            "anyOf": [
              {
                "maximum": 18446744073709552000,
                "minimum": 0,
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "default": 42,
            "description": "If specified, our system will make a best effort to sample deterministically, such that repeated requests with the same seed and parameters should return the same result.",
            "examples": [
              42
            ],
            "title": "Seed"
          },
          "stream": {
            "default": true,
            "description": "If set, partial message deltas will be sent. Tokens will be sent as data-only server-sent events (SSE) as they become available (JSON responses are prefixed by `data: `), with the stream terminated by a `data: [DONE]` message.",
            "title": "Stream",
            "type": "boolean"
          },
          "stop": {
            "anyOf": [
              {
                "items": {
                  "type": "string"
                },
                "type": "array"
              },
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Stop",
            "description": "A string or a list of strings where the API will stop generating further tokens. The returned text will not contain the stop sequence."
          },
          "tools": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/FunctionTool"
            },
            "description": "Function definitions available for tool calling.",
            "title": "Tools"
          },
          "tool_choice": {
            "title": "Tool Choice",
            "anyOf": [
              {
                "type": "string",
                "enum": [
                  "auto",
                  "none",
                  "required"
                ]
              },
              {
                "type": "object",
                "properties": {
                  "type": {
                    "const": "function"
                  },
                  "function": {
                    "type": "object",
                    "properties": {
                      "name": {
                        "type": "string"
                      }
                    },
                    "required": [
                      "name"
                    ]
                  }
                },
                "required": [
                  "type",
                  "function"
                ]
              }
            ],
            "description": "Automatically select a tool, disable tools, require a tool, or select a named function."
          },
          "parallel_tool_calls": {
            "title": "Parallel Tool Calls",
            "type": "boolean",
            "default": true,
            "description": "Whether multiple tool calls may be generated in one response."
          },
          "response_format": {
            "type": "object",
            "properties": {
              "type": {
                "type": "string",
                "enum": [
                  "text",
                  "json_object",
                  "json_schema"
                ]
              },
              "json_schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string"
                  },
                  "strict": {
                    "type": "boolean"
                  },
                  "schema": {
                    "type": "object"
                  }
                },
                "required": [
                  "name",
                  "schema"
                ]
              }
            },
            "required": [
              "type"
            ],
            "description": "Use json_schema with a JSON schema to constrain structured output.",
            "title": "Response Format"
          },
          "stream_options": {
            "type": "object",
            "properties": {
              "include_usage": {
                "type": "boolean"
              },
              "continuous_usage_stats": {
                "type": "boolean"
              }
            },
            "description": "Include token usage in streamed chunks or emit continuous usage updates.",
            "title": "Stream Options"
          },
          "chat_template_kwargs": {
            "type": "object",
            "title": "Chat Template Arguments",
            "description": "Optional chat-template arguments. Set enable_thinking to true or false to control Bolt reasoning.",
            "properties": {
              "enable_thinking": {
                "type": "boolean",
                "title": "Enable Thinking",
                "default": true,
                "description": "Enable reasoning before the final response."
              }
            },
            "additionalProperties": true,
            "default": {
              "enable_thinking": true
            }
          },
          "skip_special_tokens": {
            "type": "boolean",
            "title": "Skip Special Tokens",
            "description": "Set to false for reasoning and tool parsing so the serving parser retains special-token boundaries.",
            "example": false
          }
        },
        "required": [
          "messages"
        ],
        "title": "ChatRequest",
        "type": "object"
      },
      "Choice": {
        "properties": {
          "index": {
            "description": "The index of the choice in the list of choices (always 0).",
            "title": "Index",
            "type": "integer"
          },
          "message": {
            "allOf": [
              {
                "$ref": "#/components/schemas/Message"
              }
            ],
            "description": "A chat completion message generated by the model.",
            "examples": [
              {
                "content": "Ah, Paris, the City of Light! There are so many amazing things to see and do in this beautiful city ...",
                "role": "assistant"
              }
            ]
          },
          "finish_reason": {
            "anyOf": [
              {
                "enum": [
                  "stop",
                  "length",
                  "tool_calls"
                ],
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "default": null,
            "description": "The reason the model stopped generating tokens. This will be `stop` if the model hit a natural stop point or a provided stop sequence, or `length` if the maximum number of tokens specified in the request was reached.",
            "examples": [
              "stop"
            ],
            "title": "Finish Reason"
          }
        },
        "required": [
          "index",
          "message"
        ],
        "title": "Choice",
        "type": "object"
      },
      "ChoiceChunk": {
        "properties": {
          "index": {
            "description": "The index of the choice in the list of choices (always 0).",
            "title": "Index",
            "type": "integer"
          },
          "delta": {
            "$ref": "#/components/schemas/MessageDelta",
            "description": "Partial assistant content, reasoning, or tool-call updates. Fields may be absent in a chunk."
          },
          "finish_reason": {
            "anyOf": [
              {
                "enum": [
                  "stop",
                  "length",
                  "tool_calls"
                ],
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "default": null,
            "description": "The reason the model stopped generating tokens. This will be `stop` if the model hit a natural stop point or a provided stop sequence, or `length` if the maximum number of tokens specified in the request was reached. Will be `null` if the model has not finished generating.",
            "title": "Finish Reason"
          }
        },
        "required": [
          "index",
          "delta"
        ],
        "title": "ChoiceChunk",
        "type": "object"
      },
      "Message": {
        "additionalProperties": false,
        "properties": {
          "role": {
            "description": "The role of the message author.",
            "enum": [
              "developer",
              "system",
              "user",
              "assistant",
              "tool",
              "function"
            ],
            "title": "Role",
            "type": "string"
          },
          "content": {
            "title": "Content",
            "description": "Text or text content parts, or null for an assistant tool call.",
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/ContentPart"
                }
              },
              {
                "type": "null"
              }
            ]
          },
          "name": {
            "type": "string"
          },
          "tool_call_id": {
            "type": "string"
          },
          "tool_calls": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ToolCall"
            }
          },
          "reasoning_content": {
            "type": [
              "string",
              "null"
            ],
            "description": "Reasoning text returned separately from the final answer."
          },
          "function_call": {
            "type": [
              "object",
              "null"
            ],
            "properties": {
              "name": {
                "type": "string"
              },
              "arguments": {
                "type": "string"
              }
            },
            "description": "Legacy assistant function call. Prefer tool_calls for new integrations."
          }
        },
        "required": [
          "role"
        ],
        "title": "Message",
        "type": "object"
      },
      "Usage": {
        "properties": {
          "completion_tokens": {
            "description": "Number of tokens in the generated completion.",
            "examples": [
              25
            ],
            "title": "Completion Tokens",
            "type": "integer"
          },
          "prompt_tokens": {
            "description": "Number of tokens in the prompt.",
            "examples": [
              9
            ],
            "title": "Prompt Tokens",
            "type": "integer"
          },
          "total_tokens": {
            "description": "Total number of tokens used in the request (prompt + completion).",
            "examples": [
              34
            ],
            "title": "Total Tokens",
            "type": "integer"
          },
          "prompt_tokens_details": {
            "type": [
              "object",
              "null"
            ],
            "properties": {
              "cached_tokens": {
                "type": "integer"
              }
            }
          },
          "completion_tokens_details": {
            "type": [
              "object",
              "null"
            ],
            "properties": {
              "reasoning_tokens": {
                "type": "integer"
              }
            }
          }
        },
        "required": [
          "completion_tokens",
          "prompt_tokens",
          "total_tokens"
        ],
        "title": "Usage",
        "type": "object"
      },
      "ContentPart": {
        "type": "object",
        "properties": {
          "type": {
            "type": "string",
            "enum": [
              "text"
            ]
          },
          "text": {
            "type": "string"
          }
        },
        "required": [
          "type"
        ]
      },
      "FunctionTool": {
        "type": "object",
        "properties": {
          "type": {
            "const": "function"
          },
          "function": {
            "type": "object",
            "properties": {
              "name": {
                "type": "string"
              },
              "description": {
                "type": "string"
              },
              "parameters": {
                "type": "object"
              },
              "strict": {
                "type": "boolean"
              }
            },
            "required": [
              "name"
            ]
          }
        },
        "required": [
          "type",
          "function"
        ]
      },
      "ToolCall": {
        "type": "object",
        "properties": {
          "index": {
            "type": "integer"
          },
          "id": {
            "type": "string"
          },
          "type": {
            "const": "function"
          },
          "function": {
            "type": "object",
            "properties": {
              "name": {
                "type": "string"
              },
              "arguments": {
                "type": "string",
                "description": "JSON-encoded function arguments."
              }
            }
          }
        }
      },
      "ValidationError": {
        "type": "object",
        "properties": {
          "message": {
            "type": "string"
          },
          "type": {
            "type": "string"
          },
          "code": {
            "type": "integer"
          }
        },
        "required": [
          "message",
          "type",
          "code"
        ]
      },
      "MessageDelta": {
        "additionalProperties": false,
        "properties": {
          "role": {
            "description": "The role of the message author.",
            "enum": [
              "developer",
              "system",
              "user",
              "assistant",
              "tool",
              "function"
            ],
            "title": "Role",
            "type": "string"
          },
          "content": {
            "title": "Content",
            "description": "Text or text content parts, or null for an assistant tool call.",
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/ContentPart"
                }
              },
              {
                "type": "null"
              }
            ]
          },
          "name": {
            "type": "string"
          },
          "tool_call_id": {
            "type": "string"
          },
          "tool_calls": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ToolCall"
            }
          },
          "reasoning_content": {
            "type": [
              "string",
              "null"
            ],
            "description": "Reasoning text returned separately from the final answer."
          },
          "function_call": {
            "type": [
              "object",
              "null"
            ],
            "properties": {
              "name": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "arguments": {
                "type": [
                  "string",
                  "null"
                ]
              }
            }
          }
        },
        "title": "MessageDelta",
        "type": "object"
      }
    }
  }
}
```