Chat Completions (Embed)
Use the OpenAI-compatible embed endpoint for text, managed or self-hosted generative UI, and function tools.
The Embed Chat Completions API is a drop-in endpoint for applications that already use chat.completions.create(). It preserves the standard message format and supports text or OpenUI Lang responses.
Endpoint: POST https://api.thesys.dev/v1/embed/chat/completions
Use the embedClient from the API overview, which covers authentication, base URLs, models, and shared configuration.
Make a managed UI request
Use the server helper to have OpenUI Cloud assemble the system prompt for its built-in component library.
import { generateSystemPrompt } from "@openuidev/thesys-server";
const completion = await embedClient.chat.completions.create({
model: "openai/gpt-5",
messages: [
{ role: "system", content: generateSystemPrompt() },
{ role: "user", content: "Compare quarterly revenue by region." },
],
});
console.log(completion.choices[0].message.content);The returned message content is an OpenUI Lang program. See Component Library for the built-in client library and custom component workflow.
Stream and render responses
Set stream: true on the server. In the browser, pair the Chat Completions stream adapter with the OpenAI message format:
"use client";
import { AgentInterface, fetchLLM, openAIAdapter, openAIMessageFormat } from "@openuidev/react-ui";
import { chatLibrary } from "@openuidev/thesys";
import "@openuidev/thesys/styles.css";
const llm = fetchLLM({
url: "/api/chat",
streamAdapter: openAIAdapter(),
messageFormat: openAIMessageFormat,
});
export function Chat() {
return <AgentInterface llm={llm} componentLibrary={chatLibrary} />;
}Use openAIAdapter() when your route preserves the raw data: SSE response. If it returns the OpenAI SDK stream through .toReadableStream() instead, use openAIReadableStreamAdapter(). See Adapters and message formats for the exact pairings.
Manage conversation history
Chat Completions is message-based. Keep the conversation in your application and include the system message plus the relevant user, assistant, and tool messages on every turn.
The Conversations API integrates with Responses, not Embed Chat Completions. Choose Responses when you want Cloud-managed persistent history.
Use function tools
Embed Chat Completions accepts function tools only and does not execute them. Run the standard loop in your application:
- Send the messages and function declarations.
- Read
tool_callsfrom the assistant message. - Execute each function in your application.
- Append the assistant tool-call message and each
role: "tool"result. - Repeat until the model returns a final response.
Hosted web_search, image_search, remote MCP, and artifacts-as-tool are available on the Responses API. For standalone slides or reports, use Chat Completions for artifacts.
Use other generation modes
Plain text passthrough
Use a {provider}/{model} model ID without the managed generateSystemPrompt() sentinel. OpenUI Cloud forwards your messages and system prompt without injecting a generative UI prompt or component schema.
const completion = await embedClient.chat.completions.create({
model: "openai/gpt-5",
messages: [
{ role: "system", content: "You are a concise product analyst." },
{ role: "user", content: "Summarize the risks in this launch plan." },
],
});
console.log(completion.choices[0].message.content);OpenAI, Anthropic, and Google model IDs route to those providers. Unknown providers route through OpenRouter.
Self-hosted generative UI
Compile the complete system prompt in your application from a generated OpenUI library spec. The endpoint forwards that prompt verbatim; the model returns OpenUI Lang for your client-side renderer.
import { generateSystemPrompt } from "@openuidev/lang-core";
import library from "./generated/library.spec.json";
const completion = await embedClient.chat.completions.create({
model: "openai/gpt-5",
messages: [
{
role: "system",
content: generateSystemPrompt({
library,
promptOptions,
}),
},
...messages,
],
stream: true,
});In this mode, prompt assembly, output validation, and rendering are owned by your application.
Request-level provider key
For a request-level self-hosted key flow, encrypt the provider key with POST /encryption/encrypt, then include this object in the request body:
byok: {
provider,
encryptedApiKey,
}