# Create a chat completion

> OpenAI Chat Completions-compatible endpoint. Mirrors OpenAI's `POST /v1/chat/completions` path so an OpenAI SDK can target it by base URL alone.

<Heading
  as={"h1"}
  className={"openapi__heading"}
  children={"Create a chat completion"}
>
</Heading>

<MethodEndpoint
  method={"post"}
  path={"/api/v1/chat/completions"}
  context={"endpoint"}
>
  
</MethodEndpoint>

OpenAI Chat Completions-compatible endpoint. Mirrors OpenAI's `POST /v1/chat/completions` path so an OpenAI SDK can target it by base URL alone.

Names exactly one target. With `ai_provider_id` the completion is stateless: the provider's secret is decrypted and the appropriate Vercel AI SDK provider is called, with no server-side model fallback. With `chat_id` the stored chat supplies the provider (or the project's `default_model_route_id`), model and instructions.

System content travels only in `instructions` — a `role: "system"` entry in `messages` is refused with `400 SYSTEM_MESSAGE_NOT_ALLOWED`. With `chat_id`, a request `instructions` replaces the chat's stored one for this call only; the stored value applies when the request carries none, and the two are never merged.

Messages may use `document_id` instead of `content` with either target. Chats hold no message history — send the full `messages` array every time.

<Heading
  id={"request"}
  as={"h2"}
  className={"openapi-tabs__heading"}
>
  <Translate id="theme.openapi.request.title">Request</Translate>
</Heading>

<ParamsDetails>
  
</ParamsDetails>

<RequestSchema
  {...require("./create-chat-completion.RequestSchema.json")}
>
  
</RequestSchema>

<StatusCodes
  {...require("./create-chat-completion.StatusCodes.json")}
>
  
</StatusCodes>
