For agents Are you a coding agent? Get the full docs here: https://appelon.ai/llms.txt
API reference / Chat completions

Chat completions

GRONINGEN · NL

Generate text from a conversation. Supports streaming, system prompts, and multi-turn conversations.

Chat completions

POST /v1/chat/completions

Request body

Parameter Type Description
model string Model to use. gemma for chat, qwen for long documents. See Models. Required
messages array Array of message objects with role and content. Required
stream boolean Stream partial responses as server-sent events. Default false.
temperature number Sampling temperature, 0-2. Lower = more deterministic. Default 1.
max_tokens integer Maximum tokens to generate. Model decides if not set.
top_p number Nucleus sampling threshold, 0-1. Default 1.
top_k integer Only sample from the k most likely next tokens. Default -1 (off).
min_p number Drop tokens whose probability is below this fraction of the most likely token, 0-1. Default 0 (off).
frequency_penalty number Penalize a token more each time it has already appeared, -2 to 2. Positive = less repetition. Default 0.
presence_penalty number Penalize any token that has already appeared, however often, -2 to 2. Positive = more new topics. Default 0.
repetition_penalty number Multiplicative penalty on tokens from the prompt and output so far. Above 1 discourages repetition; 1.05-1.1 is usually enough. Default 1 (off).
seed integer Fixes the random sampling, for reproducible output with the same request.
tools array Tool definitions the model may call. See Tool calling.
tool_choice string or object auto (default when tools is set), none, or a specific tool to force.
user string Your own end-user identifier, for usage attribution. Max 128 characters. See Usage attribution.
session_id string Groups requests into one conversation or run. Max 128 characters. See Usage attribution.

top_k, min_p and repetition_penalty are not part of the OpenAI API, so the OpenAI SDKs have no argument for them. Pass them in extra_body (Python) or as extra fields in the request body (JavaScript, curl):

response = client.chat.completions.create(
    model="gemma",
    messages=[...],
    frequency_penalty=0.3,
    extra_body={"top_k": 30, "repetition_penalty": 1.05},
)

Keep repetition penalties low for reports and summaries: names and technical terms have to recur, and high values make the model reach for synonyms.

Message roles

Each message in the array has a role that determines how it’s treated.

Role Description
system Sets context for the conversation. Placed first in messages array.
user Messages from the user. The model generates a response to this.
assistant Previous model responses. Use for multi-turn conversations.

Example request

import os
from openai import OpenAI

client = OpenAI(
    base_url="https://router.appelon.ai/v1",
    api_key=os.environ["APPELON_API_KEY"]
)

response = client.chat.completions.create(
    model="gemma",
    messages=[
        {"role": "system", "content": "You are a helpful assistant."},
        {"role": "user", "content": "What is the capital of the Netherlands?"}
    ]
)

print(response.choices[0].message.content)
# → "The capital of the Netherlands is Amsterdam."

Response

Returns a completion object with the generated message.

{
  "id": "chatcmpl-abc123",
  "object": "chat.completion",
  "model": "RedHatAI/gemma-4-31B-it-FP8-block",
  "choices": [{
    "index": 0,
    "message": {
      "role": "assistant",
      "content": "The capital of the Netherlands is Amsterdam."
    },
    "finish_reason": "stop"
  }],
  "usage": {
    "prompt_tokens": 28,
    "completion_tokens": 12,
    "total_tokens": 40
  }
}

Streaming

Set stream: true to receive tokens as they’re generated.

stream = client.chat.completions.create(
    model="gemma",
    messages=[{"role": "user", "content": "Tell me a story"}],
    stream=True
)

for chunk in stream:
    print(chunk.choices[0].delta.content, end="")

Tool calling

Both chat models support tool calling, in the standard OpenAI shape: pass tools, and the model may answer with tool_calls instead of content. This is what agent frameworks and the n8n AI Agent node rely on.

tools = [{
    "type": "function",
    "function": {
        "name": "get_weather",
        "description": "Get the current weather for a city",
        "parameters": {
            "type": "object",
            "properties": {"city": {"type": "string"}},
            "required": ["city"],
        },
    },
}]

response = client.chat.completions.create(
    model="gemma",
    messages=[{"role": "user", "content": "Wat voor weer is het in Groningen?"}],
    tools=tools,
)

call = response.choices[0].message.tool_calls[0]
print(call.function.name)       # get_weather
print(call.function.arguments)  # {"city": "Groningen"}

Run the tool yourself, then send the result back as a tool message carrying the same tool_call_id, and call the model again with the extended history. That loop is the whole mechanism behind every coding agent.

Notes

  • Both models work, but they use different parsers underneath. If a prompt produces reliable tool calls on one and not the other, try the other before rewriting the prompt.
  • Parallel tool calls may come back as several entries in one tool_calls array. Answer each one with its own tool message.
  • Streaming delivers tool calls in fragments: arguments arrives as a string built up across chunks, so accumulate before parsing it as JSON.

Tools built on this