OpenAI Chat Completions

Official docs: Create chat completion · Streaming responses · Text generation

POST /v1/chat/completions is the broadest text entrypoint: the official OpenAI SDKs, most third-party clients, and most existing code build requests in this shape, so switching to ModelGo usually means replacing only the base URL and API key.

ItemValue
EndpointPOST /v1/chat/completions
Base URL (OpenAI SDK)https://api.modelgo.ai/v1
AuthenticationAuthorization: Bearer $MODELGO_API_KEY
Protocol valueopenai_chat_completions

Request examples

bash
curl https://api.modelgo.ai/v1/chat/completions \
  -H "Authorization: Bearer $MODELGO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "<model>",
    "messages": [{"role": "user", "content": "Introduce ModelGo in one sentence."}],
    "max_tokens": 256
  }'
python
import os
from openai import OpenAI

client = OpenAI(
    api_key=os.environ["MODELGO_API_KEY"],
    base_url="https://api.modelgo.ai/v1",
)

resp = client.chat.completions.create(
    model="<model>",
    messages=[{"role": "user", "content": "Introduce ModelGo in one sentence."}],
)
print(resp.choices[0].message.content)

Common fields

FieldDescription
modelPlatform logical model name
messagesConversation array; role is system / developer / user / assistant / tool
contentA string, or an array of content blocks such as text and images; multimodal support depends on the model
max_tokens / max_completion_tokensOutput cap. Newer models accept only max_completion_tokens; the gateway rewrites per model, so either spelling works
temperature / top_pSampling parameters
tools / tool_choiceFunction definitions and selection policy; return results as a role: "tool" message
streamtrue returns SSE
stream_optionsThe gateway forces include_usage on for billing; clients do not need to set it

Newer fields and roles are absorbed per upstream capability: against an upstream that only accepts the legacy role set, developer is downgraded to system; against a model that only accepts the new field, max_tokens is respelled as max_completion_tokens. Callers do not need to rewrite requests per upstream.

Responses and streaming

Non-streaming responses carry object: "chat.completion", with text in choices[0].message.content and usage in usage. Some reasoning models additionally return reasoning_content; in that case usage.completion_tokens may be noticeably larger than the max_tokens you sent.

Streaming ("stream": true) returns Content-Type: text/event-stream with one data: {"choices":[{"delta":{...}}]} frame per chunk and a terminating data: [DONE]. The gateway forces stream_options.include_usage on the inner upstream, so streaming calls are also billed on the usage the upstream actually reports.

Key conventions

  • When a logical model does not declare openai_chat_completions, this entrypoint answers HTTP 400 with error_class=model_protocol_not_offered (app_error_id=4005). Switch the entrypoint or the model; do not reshape the body.
  • The error envelope is OpenAI-shaped: {"error":{"code":..., "message":..., "metadata":{...}}}, plus a top-level trace_id matching X-Trace-ID.
  • Request bodies are capped at 10 MiB; exceeding it answers HTTP 400 client_invalid with the limit spelled out.
  • An error chunk mid-stream means failure — such a break does not also carry an independent HTTP status.

Compare entrypoints on the text generation overview; the Anthropic-native wire is on Anthropic Messages; the full error list is in Errors & Rate Limits.