RunarsRunars Docs
EndpointsAPI Endpoints

POST /v1/chat/completions

OpenAI Chat Completions API compatible endpoint

Generate a response using the OpenAI Chat Completions format. This endpoint is compatible with the OpenAI SDK and Codex CLI.

Endpoint

POST https://runars.ca/v1/chat/completions

Authentication

Include your API key in one of two ways:

Option 1: Authorization header (recommended)

-H "Authorization: Bearer sk-runars-..."

Option 2: Custom header

-H "x-api-key: sk-runars-..."

Request body

For a comparison of common parameters across all endpoints, see Parameters Reference.

FieldTypeRequiredDescription
modelstringYesModel identifier, must be "glm-5.3-flash"
messagesarrayYesArray of message objects with role and content
max_tokensintegerNoMaximum tokens in the response (default: unlimited)
temperaturenumberNoSampling temperature (0–2, default: 1)
top_pnumberNoNucleus sampling threshold (0–1)
streambooleanNoEnable streaming (default: false)
toolsarrayNoArray of tool/function definitions (optional for tool calling)
tool_choicestring|objectNoWhich tool to use ("auto", "required", or specific tool)
stream_optionsobjectNoStreaming options, including include_usage

Message format

Each message in the messages array:

{
  "role": "user" or "assistant",
  "content": "text content"
}

Or with tool calls:

{
  "role": "assistant",
  "content": "Optional text",
  "tool_calls": [
    {
      "id": "call_...",
      "type": "function",
      "function": {
        "name": "tool_name",
        "arguments": "{...}"
      }
    }
  ]
}

Response (non-streaming)

{
  "id": "chatcmpl-abc123xyz",
  "object": "chat.completion",
  "created": 1695312456,
  "model": "glm-5.3-flash",
  "choices": [
    {
      "index": 0,
      "message": {
        "role": "assistant",
        "content": "The response text here."
      },
      "finish_reason": "stop",
      "logprobs": null
    }
  ],
  "usage": {
    "prompt_tokens": 42,
    "completion_tokens": 15,
    "total_tokens": 57
  }
}

Response (streaming)

With stream: true, the endpoint returns server-sent events (unnamed data chunks):

data: {"id":"chatcmpl-abc123xyz","object":"chat.completion.chunk","created":1695312456,"model":"glm-5.3-flash","choices":[{"index":0,"delta":{"role":"assistant"},"finish_reason":null}]}

data: {"id":"chatcmpl-abc123xyz","object":"chat.completion.chunk","created":1695312456,"model":"glm-5.3-flash","choices":[{"index":0,"delta":{"content":"The"},"finish_reason":null}]}

data: {"id":"chatcmpl-abc123xyz","object":"chat.completion.chunk","created":1695312456,"model":"glm-5.3-flash","choices":[{"index":0,"delta":{"content":" response"},"finish_reason":null}]}

data: {"id":"chatcmpl-abc123xyz","object":"chat.completion.chunk","created":1695312456,"model":"glm-5.3-flash","choices":[{"index":0,"delta":{},"finish_reason":"stop"}]}

Streaming chunk fields:

  • Initial chunk includes delta.role: "assistant"
  • Text chunks include delta.content: "..."
  • Tool call chunks include delta.tool_calls: [...] with function name and arguments
  • Final chunk has empty delta and finish_reason set
  • Optional final chunk with usage field (if stream_options.include_usage: true)

Examples

Simple text request

curl https://runars.ca/v1/chat/completions \
  -H "Authorization: Bearer sk-runars-..." \
  -H "content-type: application/json" \
  -d '{
    "model": "glm-5.3-flash",
    "messages": [
      {
        "role": "user",
        "content": "What is the capital of France?"
      }
    ]
  }'

Using the OpenAI SDK with streaming

import OpenAI from "openai"

const openai = new OpenAI({
  baseURL: "https://runars.ca/v1",
  apiKey: process.env.OPENAI_API_KEY,
})

const stream = await openai.chat.completions.create({
  model: "glm-5.3-flash",
  messages: [
    {
      role: "user",
      content: "Tell me a short story about a robot.",
    },
  ],
  stream: true,
})

for await (const chunk of stream) {
  if (chunk.choices[0].delta.content) {
    process.stdout.write(chunk.choices[0].delta.content)
  }
}

With tool calling

curl https://runars.ca/v1/chat/completions \
  -H "Authorization: Bearer sk-runars-..." \
  -H "content-type: application/json" \
  -d '{
    "model": "glm-5.3-flash",
    "tools": [
      {
        "type": "function",
        "function": {
          "name": "get_weather",
          "description": "Get the current weather",
          "parameters": {
            "type": "object",
            "properties": {
              "location": {
                "type": "string",
                "description": "City name"
              }
            },
            "required": ["location"]
          }
        }
      }
    ],
    "messages": [
      {
        "role": "user",
        "content": "What is the weather in Toronto?"
      }
    ]
  }'

The response will include a tool_calls array with the tool name and arguments. You can then send the tool result back in a subsequent message.

Streaming with usage tracking

To get token usage in a streaming response, pass stream_options:

curl https://runars.ca/v1/chat/completions \
  -H "Authorization: Bearer sk-runars-..." \
  -H "content-type: application/json" \
  -d '{
    "model": "glm-5.3-flash",
    "stream": true,
    "stream_options": {
      "include_usage": true
    },
    "messages": [
      {
        "role": "user",
        "content": "Say hello"
      }
    ]
  }'

The final message will include usage data.

Error responses

400 Bad Request

Invalid request:

{
  "error": {
    "message": "Invalid request: missing required field 'messages'",
    "type": "invalid_request_error",
    "param": null,
    "code": null
  }
}

401 Unauthorized

Invalid or missing API key:

{
  "error": {
    "message": "Unauthorized",
    "type": "invalid_request_error",
    "param": null,
    "code": "invalid_api_key"
  }
}

429 Too Many Requests

Rate limit exceeded:

{
  "error": {
    "message": "Rate limit exceeded",
    "type": "server_error",
    "param": null,
    "code": "insufficient_quota"
  }
}

The response includes a Retry-After header indicating how long to wait.

Token usage

  • Prompt tokens: Input tokens (messages + any system prompt).
  • Completion tokens: Output tokens.
  • Total tokens: Sum of prompt and completion tokens.

All count towards pricing and rate limits. See Pricing for rates.

On this page