Skip to Content

Chat Completions

POST https://api.fenno.ai/v1/chat/completions Authorization: Bearer <FENNO_API_KEY> Content-Type: application/json

Request fields

FieldTypeMeaning
modelstring, requiredExact available Chat Completions model ID
messagesarray, requiredConversation history; use model-supported roles and content items
streambooleanReturn SSE chunks instead of one completion
temperature, top_pnumber, optionalSampling controls, only where supported
max_completion_tokens or max_tokensinteger, optionalModel-dependent output limit; do not assume both are accepted
tools, tool_choicearray / string or objectFunction definitions and selection policy
response_formatobject, optionalJSON mode or supported JSON Schema configuration
reasoning_effortstring, optionalModel-specific reasoning control; not Responses’ reasoning object

Python example

Install openai; set FENNO_API_KEY and FENNO_MODEL:

import os from openai import OpenAI client = OpenAI( base_url="https://api.fenno.ai/v1", api_key=os.environ["FENNO_API_KEY"], timeout=60.0, max_retries=0, ) response = client.chat.completions.create( model=os.environ["FENNO_MODEL"], messages=[ {"role": "system", "content": "Answer concisely."}, {"role": "user", "content": "What is an API gateway?"}, ], ) print(response.choices[0].message.content)

Send the relevant history on each request. A chat completion ID is not a server-side conversation handle.

Response fields

FieldMeaning
id, model, objectResponse identification and model information
choices[].messageAssistant text and/or tool_calls
choices[].finish_reasonCommon values include stop, length, tool_calls and safety-related stops
usageInput/output token information when provided

Do not treat every assistant message as plain text: content may be absent during tool calling. An output-limit stop is not a complete structured answer.

Streaming

Set stream=True in the SDK or "stream": true in JSON. Read choices[].delta, not choices[].message. Some chunks contain roles or tool arguments rather than text, and some may have empty choices. The SSE transport ends with [DONE]; inspect finish reasons as well.

stream_options.include_usage is optional and model-dependent. Do not require a usage chunk to render an answer, and do not interpret its absence as zero cost.

See function calling, structured output, streaming and error formats.