Swiss AI GroupDocs
API reference

SwissAI API

An OpenAI-compatible chat completions API. Create a key in the portal, set the bearer token, and go — existing OpenAI SDKs work with a changed base_url.

Quickstart

Three steps to your first response:

1. In the developer dashboard, create a key under API Keys. It is shown only once — store it safely. Format: sk-souheng-…

2. Send a request to the chat endpoint:

curlcurl -N https://api.swiss-ai.one/api/v1/external/chat/completions \
  -H "Authorization: Bearer sk-souheng-YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "messages": [{ "role": "user", "content": "Say hello in Swiss German." }],
    "stream": true
  }'

3. You get back an OpenAI-compatible SSE stream (see Streaming).

Authentication

Authenticate every request with your API key in the Authorization header:

httpAuthorization: Bearer sk-souheng-YOUR_KEY
The model is bound to the key. Which model a key uses is set in the portal. The model field in the request body is ignored — you may send any value (handy for unmodified OpenAI SDKs).

API keys are managed exclusively in the portal (create, list, revoke). Up to 20 active keys per account.

Base URL

PurposeURL
API basehttps://api.swiss-ai.one
Chat Completions/api/v1/external/chat/completions
OpenAI SDK base_urlhttps://api.swiss-ai.one/api/v1/external

POST/api/v1/external/chat/completions

Generates a chat response. Streaming is on by default.

Request body

FieldTypeDefaultDescription
messages requiredarrayList of { "role", "content" }. Roles: system, user, assistant, tool.
streambooleantrueSSE streaming on/off.
temperaturenumber0.70.0–2.0.
max_tokensinteger40961–128000.
toolsarraynullTool definitions in OpenAI format.
tool_choicestringnulle.g. "auto".
Note: model is accepted but ignored (the model is determined by the key). Unknown fields are ignored.

Streaming (SSE)

With "stream": true the API returns text/event-stream in OpenAI chunk format. The stream ends with data: [DONE].

ssedata: {"id":"chatcmpl-1a2b3c4d","object":"chat.completion.chunk","created":1750000000,"model":"swissai","choices":[{"index":0,"delta":{"content":"Hallo"},"finish_reason":null}]}

data: {"id":"chatcmpl-1a2b3c4d","object":"chat.completion.chunk","created":1750000000,"model":"swissai","choices":[{"index":0,"delta":{"content":"!"},"finish_reason":null}]}

data: {"id":"chatcmpl-1a2b3c4d","object":"chat.completion.chunk","created":1750000000,"model":"swissai","choices":[{"index":0,"delta":{},"finish_reason":"stop"}]}

data: [DONE]

Without streaming

With "stream": false you receive a single chat.completion object:

json{
  "id": "chatcmpl-1a2b3c4d",
  "object": "chat.completion",
  "created": 1750000000,
  "model": "swissai",
  "choices": [
    {
      "index": 0,
      "message": { "role": "assistant", "content": "Hello! How can I help?" },
      "finish_reason": "stop"
    }
  ]
}

Tools / function calling

Pass tools in OpenAI format. When the model calls a tool, tool_calls come back (streaming or non-streaming). Send the result back as a tool message with the matching tool_call_id.

json{
  "messages": [{ "role": "user", "content": "What's the weather in Zürich?" }],
  "stream": false,
  "tools": [{
    "type": "function",
    "function": {
      "name": "get_weather",
      "description": "Current weather for a city",
      "parameters": {
        "type": "object",
        "properties": { "city": { "type": "string" } },
        "required": ["city"]
      }
    }
  }],
  "tool_choice": "auto"
}

Python

requests (streaming)

pythonimport json, requests

resp = requests.post(
    "https://api.swiss-ai.one/api/v1/external/chat/completions",
    headers={"Authorization": "Bearer sk-souheng-YOUR_KEY"},
    json={"messages": [{"role": "user", "content": "Hello"}], "stream": True},
    stream=True,
)
for line in resp.iter_lines():
    if not line:
        continue
    line = line.decode()
    if line.startswith("data: "):
        data = line[6:]
        if data == "[DONE]":
            break
        delta = json.loads(data)["choices"][0]["delta"]
        print(delta.get("content", ""), end="", flush=True)

JavaScript / Node

javascriptconst res = await fetch(
  "https://api.swiss-ai.one/api/v1/external/chat/completions",
  {
    method: "POST",
    headers: {
      "Authorization": "Bearer sk-souheng-YOUR_KEY",
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      messages: [{ role: "user", content: "Hello" }],
      stream: true,
    }),
  }
);

const reader = res.body.getReader();
const decoder = new TextDecoder();
let buffer = "";
for (;;) {
  const { done, value } = await reader.read();
  if (done) break;
  buffer += decoder.decode(value, { stream: true });
  const lines = buffer.split("\n");
  buffer = lines.pop();
  for (const line of lines) {
    if (!line.startsWith("data: ")) continue;
    const data = line.slice(6);
    if (data === "[DONE]") { reader.cancel(); break; }
    const delta = JSON.parse(data).choices[0].delta;
    if (delta.content) process.stdout.write(delta.content);
  }
}

OpenAI SDK

Existing OpenAI SDKs work by setting base_url and api_key. model is a required SDK field but is ignored server-side.

pythonfrom openai import OpenAI

client = OpenAI(
    api_key="sk-souheng-YOUR_KEY",
    base_url="https://api.swiss-ai.one/api/v1/external",
)

stream = client.chat.completions.create(
    model="swissai",  # anything — ignored
    messages=[{"role": "user", "content": "Hello"}],
    stream=True,
)
for chunk in stream:
    print(chunk.choices[0].delta.content or "", end="")
javascriptimport OpenAI from "openai";

const client = new OpenAI({
  apiKey: "sk-souheng-YOUR_KEY",
  baseURL: "https://api.swiss-ai.one/api/v1/external",
});

const stream = await client.chat.completions.create({
  model: "swissai",            // anything — ignored
  messages: [{ role: "user", content: "Hello" }],
  stream: true,
});
for await (const chunk of stream) {
  process.stdout.write(chunk.choices[0]?.delta?.content ?? "");
}

Billing & limits

  • Requests are billed token-based against your balance (wallet).
  • You can see balance and usage in the dashboard, where you can also top up.
  • Up to 20 active API keys per account.

Error codes

StatusMeaning
401API key missing, invalid or inactive.
402Balance exhausted — top up in the dashboard.
404Unknown path / endpoint.
429Rate limit exceeded — try again later.
5xxTemporary server / upstream problem.