Chat Completions
POST /v1/chat/completions is the main OpenAI-compatible text endpoint. It supports multi-turn conversations, streaming, vision (image inputs), tool/function calling, and various parameters for controlling output.
Use it when
- Your app already uses the OpenAI Chat Completions format
- You want easy migration from another OpenAI-compatible provider
- You want streaming deltas and broad provider coverage
Code examples
1curl -X POST https://api.navy/v1/chat/completions \
2 -H "Authorization: Bearer sk-navy-YOUR_KEY" \
3 -H "Content-Type: application/json" \
4 -d '{
5 "model": "gpt-5",
6 "messages": [
7 {"role": "system", "content": "You are a concise release assistant."},
8 {"role": "user", "content": "Write three product taglines."}
9 ],
10 "stream": false
11 }'Parameters
model(string, required) — Model ID such asgpt-5,claude-sonnet-4, orgemini-2.5-promessages(array, required) — Chat history withroleandcontent. Content can be a string or an array of parts (text, image_url) for vision modelsmax_tokens(integer, optional) — Maximum tokens to generatetemperature(number, optional) — Sampling temperature (0.0–2.0)top_p(number, optional) — Nucleus sampling threshold (0.0–1.0)top_k(integer, optional) — Top-K sampling parameter (supported by some providers)stream(boolean, optional) — Enable streaming responses via SSEstop(string or array, optional) — Stop sequence(s) to end generationseed(integer, optional) — Random seed for reproducible outputsfrequency_penalty(number, optional) — Penalize repeated tokens (−2.0 to 2.0)presence_penalty(number, optional) — Penalize tokens based on presence (−2.0 to 2.0)reasoning_effort(string, optional) —"none","minimal","low","medium","high","xhigh"for thinking modelsresponse_format(object, optional) —{ type: "json_object" },{ type: "json_schema", json_schema: {...} }, or{ type: "text" }tools(array, optional) — Tool/function definitions for function callingtool_choice(string or object, optional) —"auto","none","required", or{ type: "function", function: { name: "..." } }
Streaming
Set "stream": true to receive output as Server-Sent Events. Each chunk is a JSON object on a line prefixed with data: , ending with data: [DONE]. NavyAI automatically sets stream_options.include_usage = true, so the last chunk before [DONE] includes a usage object with token counts.
1from openai import OpenAI
2
3client = OpenAI(api_key="sk-navy-YOUR_KEY", base_url="https://api.navy/v1")
4
5stream = client.chat.completions.create(
6 model="gpt-5",
7 messages=[{"role": "user", "content": "Stream a haiku about the sea."}],
8 stream=True
9)
10
11for chunk in stream:
12 delta = chunk.choices[0].delta.content if chunk.choices else None
13 if delta:
14 print(delta, end="", flush=True)A raw streaming chunk looks like this:
1{
2 "id": "chatcmpl-...",
3 "object": "chat.completion.chunk",
4 "created": 1716112000,
5 "model": "gpt-5",
6 "choices": [
7 { "index": 0, "delta": { "content": "Hello" }, "finish_reason": null }
8 ]
9}Tool / function calling
Pass an array of tools and let the model decide when to call them. The response will contain a tool_calls array on the assistant message; send a role: "tool" reply with the result on the next turn.
1from openai import OpenAI
2
3client = OpenAI(api_key="sk-navy-YOUR_KEY", base_url="https://api.navy/v1")
4
5tools = [{
6 "type": "function",
7 "function": {
8 "name": "get_weather",
9 "description": "Get the current weather for a city",
10 "parameters": {
11 "type": "object",
12 "properties": {
13 "city": {"type": "string", "description": "City name"}
14 },
15 "required": ["city"]
16 }
17 }
18}]
19
20response = client.chat.completions.create(
21 model="gpt-5",
22 messages=[{"role": "user", "content": "What's the weather in Tokyo?"}],
23 tools=tools,
24 tool_choice="auto"
25)
26
27print(response.choices[0].message.tool_calls)Vision support
Many models support image inputs via the image_url content type in messages. Supports both URLs and base64 data URIs.
1{
2 "role": "user",
3 "content": [
4 { "type": "text", "text": "What's in this image?" },
5 { "type": "image_url", "image_url": { "url": "https://example.com/image.png" } }
6 ]
7}Structured output
Use response_format to force JSON. { "type": "json_object" } returns any valid JSON; { "type": "json_schema", "json_schema": { ... } } validates the output against a schema before returning.
Notes
- Streaming returns OpenAI-style SSE chunks followed by
data: [DONE] - The following request fields are silently stripped before forwarding upstream:
n,service_tier,metadata,store,safety_identifier,prompt_cache_key,user,deferred,plugins,provider - Usage is tracked against your daily plan limits with model multipliers
- Streaming responses include a final
usageobject so you can log exact token counts