Chat Completions
Chat Completions generates a model reply from a list of messages. Glexir supports it for
compatibility with existing code. For new work, use the Responses API: it is
required for -pro models and for tool calling on gpt-6-astra and gpt-6.1-sol.
The endpoint is OpenAI-compatible: POST https://api.glexir.com/v1/chat/completions.
Create a completion
glexir.chat.completions.create(body, options?) returns APIPromise<ChatCompletion>. With
stream: true it returns APIPromise<Stream<ChatCompletionChunk>>.
Operations
| SDK method | HTTP | Returns |
|---|---|---|
chat.completions.create(body, options?) | POST /v1/chat/completions | ChatCompletion, or Stream<ChatCompletionChunk> with stream: true |
chat.completions.stream(body, options?) | POST /v1/chat/completions with stream: true | ChatCompletionStream |
chat.completions.parse(body, options?) | POST /v1/chat/completions | Promise<ParsedChatCompletion<T>> |
chat.completions.retrieve(id, options?) | GET /v1/chat/completions/{id} | ChatCompletion |
chat.completions.update(id, body, options?) | POST /v1/chat/completions/{id} | ChatCompletion |
chat.completions.list(query?, options?) | GET /v1/chat/completions | PagePromise<ChatCompletion> |
chat.completions.delete(id, options?) | DELETE /v1/chat/completions/{id} | ChatCompletionDeleted |
chat.completions.messages.list(id, query?, options?) | GET /v1/chat/completions/{id}/messages | PagePromise<ChatCompletionStoreMessage> |
Every method takes request options as its last argument:
{ signal, timeout, maxRetries, headers, idempotencyKey }.
Create parameters
ChatCompletionCreateParams is ChatCompletionCreateParamsNonStreaming | ChatCompletionCreateParamsStreaming.
Both extend ChatCompletionCreateParamsBase. Unknown fields are sent unchanged.
modelChatModelrequired- A text model ID, such as
gpt-5.4-mini.-promodels return 400: they are only available through/v1/responses. messagesChatCompletionMessageParam[]required- A non-empty list of messages with role
developer,system,user,assistantortool. See Messages. streamboolean | nulloptional- Stream the reply as server-sent events. With
true,create()returns aStream. stream_options{ include_usage?: boolean; include_obfuscation?: boolean } | nulloptional- Streaming only.
include_usage: trueadds a final chunk with token usage. See Streaming. toolsChatCompletionTool[]optional- Function and custom tools only. See Tools.
tool_choiceChatCompletionToolChoiceOptionoptionalnone,auto,required,{ type: "function", function: { name } },{ type: "custom", custom: { name } }or{ type: "allowed_tools", allowed_tools: { mode, tools } }.parallel_tool_callsbooleanoptional- Allow several tool calls in one reply.
response_formatResponseFormatText | ResponseFormatJSONSchema | ResponseFormatJSONObjectoptional{ type: "text" },{ type: "json_object" }, or{ type: "json_schema", json_schema: { name, schema?, description?, strict? } }.reasoning_effortReasoningEffort | nulloptionalnone,minimal,low,medium,high,xhighormax.verbosity"low" | "medium" | "high" | nulloptional- How long the reply should be.
max_completion_tokensnumber | nulloptional- Upper bound on generated tokens, including reasoning tokens.
max_tokensnumber | nulloptional- Deprecated. Use
max_completion_tokens. Reasoning models reject it. nnumber | nulloptional- How many choices to generate.
stopstring | string[] | nulloptional- Stop sequences.
temperaturenumber | nulloptional- Sampling temperature.
top_pnumber | nulloptional- Nucleus sampling.
frequency_penaltynumber | nulloptional- Penalise repeated tokens by frequency.
presence_penaltynumber | nulloptional- Penalise tokens that already appeared.
logit_biasRecord<string, number> | nulloptional- Token ID to bias.
logprobsboolean | nulloptional- Return log probabilities of output tokens.
top_logprobsnumber | nulloptional- Most likely tokens to return at each position. Needs
logprobs: true. prediction{ type: "content"; content: string | ChatCompletionContentPartText[] } | nulloptional- Predicted output, to speed up replies that are mostly known in advance.
storeboolean | nulloptional- Store the completion so you can retrieve, update, list and delete it. The gateway forwards your value unchanged. See Stored completions.
metadataRecord<string, string> | nulloptional- Up to 16 key/value pairs. With
store: true, at most 15: Glexir uses one key. service_tierServiceTier | nulloptionalauto,default,flex,scale,priority,fastorultrafast. Billing and access work as in Responses.moderationModerationConfig | nulloptional- Inline moderation:
{ model: "omni-moderation-latest", policy?: { input?: { mode }, output?: { mode } } }. prompt_cache_keystring | nulloptional- Groups requests that share a prompt prefix. Scoped to your organization by the gateway.
prompt_cache_optionsPromptCacheOptions | nulloptionalmode(implicitorexplicit) andttl(for example30m).prompt_cache_retention"in_memory" | "24h" | nulloptional- Deprecated. Use
prompt_cache_options.ttl. safety_identifierstring | nulloptional- A stable ID for your end user. The gateway replaces it with a hashed value derived from your organization and this value.
seednumber | nulloptional- Deprecated.
userstringoptional- Deprecated. Used as the end-user ID when
safety_identifieris missing, then removed by the gateway. web_search_optionsRecord<string, unknown>optional- Rejected with 400 unsupported_on_glexir. Web search is a hosted tool.
The gateway also rejects audio and modalities that include "audio" (audio output is not
supported).
Messages
| Role | Type | content |
|---|---|---|
developer | ChatCompletionDeveloperMessageParam | string | ChatCompletionContentPartText[] |
system | ChatCompletionSystemMessageParam | string | ChatCompletionContentPartText[] |
user | ChatCompletionUserMessageParam | string | ChatCompletionContentPart[] (text, image, file) |
assistant | ChatCompletionAssistantMessageParam | string, text and refusal parts, or null; plus refusal? and tool_calls? |
tool | ChatCompletionToolMessageParam | string | ChatCompletionContentPartText[], plus tool_call_id |
Every role except tool takes an optional name. User content parts:
{ type: "text", text }{ type: "image_url", image_url: { url, detail? } }, whereurlis an http(s) URL or adata:URL anddetailisauto,low,highororiginal.{ type: "file", file: { file_data?, file_id?, filename? } }for PDFs and other files.file_idmust be a file you uploaded through Glexir; any other ID returns 404.
Text, image and file parts accept prompt_cache_breakpoint: { mode: "explicit" }.
The gateway returns 400 unsupported_on_glexir for messages with an audio field and for
input_audio content parts. An empty messages array returns 400.
The ChatCompletion object
idstringoptional- The completion ID, for example
chatcmpl-.... object"chat.completion"optional- Always chat.completion.
creatednumberoptional- Unix timestamp in seconds.
modelstringoptional- The model that served the request.
choicesChatCompletionChoice[]optional- Each has
index,finish_reason(stop,length,tool_calls,content_filter,function_call),logprobsandmessage. choices[].messageChatCompletionMessageoptionalrole: "assistant",content,refusal,tool_calls?andannotations?.usageCompletionUsageoptionalprompt_tokens,completion_tokens,total_tokens, plusprompt_tokens_details(cached_tokens,cache_write_tokens, ...) andcompletion_tokens_details(reasoning_tokens, prediction tokens, ...). Glexir bills from these numbers.service_tierServiceTier | nulloptional- The tier that actually served the request. Glexir bills at this tier.
metadataRecord<string, string> | nulloptional- Your metadata. Glexir's own key is removed.
moderationobject | nulloptional- Moderation results when you set
moderation. system_fingerprintstringoptional- Deprecated.
_request_idstring | nulloptional- Added by the SDK: the
x-request-idheader.
Streaming
Set stream: true on create() for a raw Stream<ChatCompletionChunk>, or use
chat.completions.stream() for a helper that assembles the final completion. Both are covered in
Streaming.
include_usage
With stream_options: { include_usage: true }, the last chunk before [DONE] has an empty choices
array and a usage object. Guard chunk.choices[0] as above.
Glexir always turns include_usage on when it talks to OpenAI, because it bills streams from that
chunk. If you didn't ask for it, the gateway removes the usage chunk before it reaches you. If a
stream ends without usage (for example, the upstream fails), Glexir bills an estimate of the input
tokens only.
ChatCompletionChunk has id, object: "chat.completion.chunk", created, model, choices (each
with index, delta, finish_reason and logprobs?), and usage?, service_tier?,
obfuscation? and error?. A delta has role?, content?, refusal? and tool_calls?
fragments.
Tools
Chat Completions accepts function and custom tools:
ChatCompletionFunctionTool:{ type: "function", function: { name, description?, parameters?, strict? } }. Chat Completions is non-strict unless you setstrict: true.ChatCompletionCustomTool:{ type: "custom", custom: { name, description?, format? } }.formatis{ type: "text" }or{ type: "grammar", grammar: { definition, syntax: "lark" | "regex" } }. The grammar is nested undergrammar, unlike the Responses API.
Any other tool type, and any tool_choice type other than function, custom or allowed_tools,
returns 400 unsupported_on_glexir. That includes OpenAI-hosted tools such as web search.
Tool calling on newer models
On GPT-5.4 and later, Chat Completions supports tools only with reasoning_effort: "none".
gpt-6-astra and gpt-6.1-sol need the Responses API for tool calling.
Structured output
chat.completions.parse(body, options?) creates a completion and parses each choice's
message.content when response_format.type is json_schema or json_object. It also parses the
arguments of function tools that have strict: true.
It returns ParsedChatCompletion<T>:
- Each
choices[].messageis aParsedChatCompletionMessage<T>withparsed: T | null.parsedisnullwhen the model refused or the format is not JSON. - Function tool calls are
ParsedFunctionToolCall:{ id, type: "function", function: { name, arguments, parsed_arguments } }.parsed_argumentsis the parsed JSON for strict tools andnullotherwise. - It throws
LengthFinishReasonErrorif any choice hasfinish_reason: "length", andContentFilterFinishReasonErrorfor"content_filter". optionsisParseOptions<T>: request options plusvalidate?: (value: unknown) => T.
Stored completions
Create a completion with store: true to keep it. You can then retrieve, update, list and delete
it, and list its messages. These endpoints only see completions created through your Glexir
organization; any other ID returns 404 (No chat completion found with id '...').
Glexir tags each stored completion with one metadata key, glexir_customer, to keep your list
separate from other organizations. It removes that key from every response, and it counts toward the
16-key limit: a stored completion can have at most 15 of your own keys, or the request returns 400.
| Method | Notes |
|---|---|
retrieve(completionId, options?) | Returns the ChatCompletion. |
update(completionId, body, options?) | ChatCompletionUpdateParams is { metadata: Record<string, string> | null }. Metadata is the only field you can change, and it is required (400 without it). |
list(query?, options?) | ChatCompletionListParams: after?, limit?, metadata? (filter by key/value), model?, order? (asc by default). Returns PagePromise<ChatCompletion>; iterate with for await. |
delete(completionId, options?) | Returns ChatCompletionDeleted: { id, deleted, object: "chat.completion.deleted" }. |
messages.list(completionId, query?, options?) | MessageListParams: after?, limit?, order?. Returns PagePromise<ChatCompletionStoreMessage>, a message with id and optional content_parts. |
Errors
| Status | code | Cause |
|---|---|---|
| 400 | unsupported_on_glexir | Hosted tool, unsupported tool_choice, audio input or output, or web_search_options. |
| 400 | model_not_found | model missing, not a text model, not enabled, or Responses-only (-pro). |
| 400 | null | Empty messages, missing metadata on update, or more than 15 metadata keys with store: true. |
| 402 | credit_balance_exhausted, spend_limit_exceeded | Not enough credit, or a spend limit reached. |
| 403 | model_not_priced, tier_not_allowed | Model not in the price book, or tier not available to you. |
| 404 | null | The stored completion or a referenced file is not yours. |
| 429 | rate_limit_exceeded, concurrency_limit_exceeded | Too many requests. |
See HTTP error codes and Errors & retries.