OpenAI Chat Completions
The Chat Completions API (POST {base_url}/chat/completions) with an API key. Works against OpenAI and any endpoint implementing that format: Ollama, vLLM, LM Studio, OpenRouter, Synthetic, LiteLLM.
This is not the legacy /v1/completions endpoint, which is a different protocol: a bare prompt string in, choices[].text out, no tool calling. Several of those same servers also expose it; meka does not implement it.
For the same key against OpenAI’s newer protocol, see openai-responses.
Configuration
| Setting | Value |
|---|---|
Account backend | openai-chat-completions |
| Default base URL | https://api.openai.com/v1 |
| Credential | API key (sk-...) kept in the store |
| Auth method | Bearer token (Authorization: Bearer <key>) |
Quickest start
meka account add openai --backend openai-chat-completions
meka profile add work --account openai --model gpt-6-astra
meka account add prompts for your OpenAI API key, saves it to the store, and writes the
[accounts.openai] table. To read the key from a pipe instead of prompting, pass
--api-key-stdin. meka profile add then writes the profile that names the model.
Config file
The two commands write this for you (the key stays in the store, not here):
default_profile = "work"
[accounts.openai]
backend = "openai-chat-completions"
[profiles.work]
account = "openai"
model = "gpt-6-astra"
Supported models
Any model reachable over the Chat Completions API that supports tool calling. For OpenAI’s current line-up, see OpenAI’s models overview; meka profile add suggests gpt-6-astra for a profile on an OpenAI account. Against a compatible endpoint the valid names are that server’s: whatever Ollama, vLLM, LM Studio or OpenRouter serves. meka forwards the model string verbatim and doesn’t gate which strings are valid.
Custom base URL
To use an OpenAI-compatible endpoint, set the account’s base_url when creating it:
# Ollama (no real key; pipe a placeholder)
printf 'unused' | meka account add ollama --backend openai-chat-completions \
--base-url http://localhost:11434/v1 --api-key-stdin
meka profile add llama --account ollama --model llama3
# OpenRouter
meka account add openrouter --backend openai-chat-completions \
--base-url https://openrouter.ai/api/v1
meka profile add sonnet --account openrouter --model anthropic/claude-sonnet-5.5
The resulting tables (the key, if any, lives in the store):
[accounts.ollama]
backend = "openai-chat-completions"
base_url = "http://localhost:11434/v1"
[profiles.llama]
account = "ollama"
model = "llama3"
API details
Endpoint: POST {base_url}/chat/completions
Tool format: Tools are sent as function definitions:
{
"type": "function",
"function": {
"name": "file_read",
"description": "Read the contents of a file at the given path.",
"parameters": { "type": "object", "properties": { ... } }
}
}
Tool results: Sent back as messages with role: "tool" and the corresponding tool_call_id.
Streaming: Uses Server-Sent Events (SSE) with data: {...} lines. The stream ends with data: [DONE].
Usage: a streamed request asks for its usage with stream_options.include_usage, which OpenAI’s own API needs before it reports any; an endpoint that refuses the field takes the account’s stream_usage set to false. The cached_tokens an endpoint reports under prompt_tokens_details count as cache reads in /status and the per-turn usage line.
Reasoning: the reasoning_content an endpoint streams (or reasoning, as vLLM and OpenRouter spell it) is shown as thinking, kept in the session, and sent back on every later request as the assistant message’s reasoning_content. DeepSeek’s thinking mode rejects a request with tools that omits an earlier turn’s reasoning; the other endpoints accept or ignore it. Reasoning another backend recorded is never sent here.