Skip to content

Chatting via API

To use the chat features of Alan via the API, you have two options:

  1. OpenAI-compatible API interface: You can use the OpenAI-compatible API interface of Alan if you do not require Alan-specific features. This interface is particularly useful if you are already using OpenAI clients or libraries in your application or if you want to generate responses in a lightweight manner.
  2. Direct use of the Alan Chats API: Alternatively, you can access the chat features directly via the Alan chats API endpoints. This allows for seamless integration of the chat functionalities into your applications with all Alan-specific features.

OpenAI-compatible API interface of Alan

This section provides the necessary steps to use Alan via the OpenAI-compatible API interface. This allows using Alan directly through the official OpenAI client or indirectly through other OpenAI-compatible software.

The responses received are not persisted as chats and are therefore not visible in the Alan user interface. Also note that these endpoints do not support Alan-specific features such as knowledge databases, experts or abilities.

Provided endpoints

To enable usage with OpenAI-compatible software, Alan offers multiple endpoints. These include:

  • GET /oai/models: Lists all available models that can be used via the OpenAI-compatible API and is used to check the status of deployed models.

  • GET /oai/models/{model}: Retrieves detailed information about a specific model.

  • GET /oai/chat/completions: Generates text responses based on a chat history.

  • GET /oai/embeddings: Generates embeddings from text.

The provided endpoints match the official OpenAI endpoints in terms of expected input and generated output.

Using the official OpenAI client

The following code example demonstrates how to use Alan with the official OpenAI client. Both the asynchronous and synchronous OpenAI clients can be used.

Preparation

Using Alan with an OpenAI client requires a valid Alan API key.

Synchronous client
python
from openai import OpenAI

api_key = ""  # Enter API-Key. Starts with "alan-"
base_url = "https://app.alan.de/api/v1/oai"

sync_client = OpenAI(api_key=api_key, base_url=base_url)
Asynchronous client
python
from openai import AsyncOpenAI

api_key = ""  # Enter API-Key. Starts with "alan-"
base_url = "https://app.alan.de/api/v1/oai"

async_client = AsyncOpenAI(api_key=api_key, base_url=base_url)

Retrieving available models and specific model information

You can retrieve all available models and their status. The response schema matches the OpenAI format.

python
print(sync_client.models.list())

model = "comma-soft/comma-llm-agentic"
print(sync_client.models.retrieve(model))

Generating chat completions

To chat with a model, use the Chat Completions endpoint. Here, text responses are generated based on a chat history matching the OpenAI standard. When using this endpoint, depending on the model, only the following parameters are considered in addition to messages, model, and stream: temperature, top_p, max_token. The parameter ranges, types, and response format match the OpenAI standard.

Streaming response
python
completion = sync_client.chat.completions.create(
    messages=[{"role": "user", "content": "How are you?"}],
    model="comma-soft/comma-llm-agentic",
    temperature=...,
    top_p=...,
    max_token=...,
    stream=True
)

for chunk in completion:
    print(chunk)
Non-streaming response
python
completion = sync_client.chat.completions.create(
    messages=[{"role": "user", "content": "How are you?"}],
    model="comma-soft/comma-llm-agentic",
    stream=False
)

print(completion)

Embeddings

Additionally, you can generate embeddings, i.e., calculate a numerical vector for a given input text. All available parameters can be used.

python
embeddings = sync_client.embeddings.create(input="Dies ist ein Text!", model="comma-soft/comma-embedding-20251125")
print(embeddings)

Limitations

Currently, we only support the basic functionality described above. An extension to include advanced features like Guided Generation or Beam Search is currently not available.

Alan chats API

To use the full chatting features of Alan, you can access the Alan chats API endpoints directly. These endpoints are more complex to use but support all Alan-specific features such as knowledge databases, experts and abilities.

A complete overview of the available endpoints and their usage can be found in the Swagger documentation.

The following describes the basic steps to use the chats API and illustrates them with example code in Python.

Chatting with Alan

To receive responses from Alan, you first need to start a new chat and then send requests to this chat.

Sending initial request

To start a new chat with Alan, send your initial request to the POST /chats/ endpoint.

python
import requests
import json

API_KEY = ""  # Enter API-Key. Starts with "alan-"

url = "https://app.alan.de/api/v1/chats/"

headers = {"accept": "application/json", "Content-Type": "application/json",  "Authorization": f"Bearer {API_KEY}"}

payload = json.dumps({
  "content": "Write an engaging LinkedIn post about the importance of AI for the economic location Germany.",
  "settings": {
    "model": "comma-soft/comma-llm-agentic"
  }
})

response = requests.request("POST", url, headers=headers, data=payload)
print(response.text)  # SSE-Event-Stream

By default, all chats you create via this endpoint are usable via API as well as visible in the Alan user interface.

To start a chat via the API that should not be visible in the Alan user interface, set the parameter api_only to True in the request.

Processing responses

The responses from Alan are returned in SSE format and need to be processed accordingly.

In the following example, the chat and message objects are extracted from the SSE stream and printed.

python
chat_response = response.text

# Extract SSE response
events = [
    json.loads(event)
    for event_line in chat_response.split("\n\n")
    if (event := event_line.removeprefix("data:").strip())
]

# Reconstruct chat state from events
# chat id -> chat data
chat_state: dict[str, dict[str, typing.Any]] = {}
# chat id -> message id -> message data
messages: dict[str, dict[str, dict[str, typing.Any]]] = {}

for event in events:
    match event["kind"]:
        case "chat":
            chat_id = event["chat"]["resource_id"]
            chat_state[chat_id] = event["chat"]
        case "message":
            chat_id = event["message"]["chat_id"]
            message_id = event["message"]["resource_id"]
            if chat_id not in messages:
                messages[chat_id] = {}
            messages[chat_id][message_id] = event["message"]
        case "state" | "keep_alive" | "tokens" | "file" | "error":
            pass  # ignore for now

# Output reconstructed state
print(
    json.dumps(
        {
            "chats": chat_state,
            "messages": messages,
        },
        indent=2,
        ensure_ascii=False,
    )
)

Sending follow-up requests

To send follow-up requests to an existing chat, use the POST /chats/{chat_id}/generate endpoint.

The responses are also returned in SSE format and can be processed as described above.

python
import requests
import json

API_KEY = ""  # Enter API-Key. Starts with "alan-"

chat_id = ""  # Enter ID of the existing chat to be continued
url = f"https://app.alan.de/api/v1/chats/{chat_id}/generate

headers = {"accept": "application/json", "Content-Type": "application/json",  "Authorization": f"Bearer {API_KEY}"}

message_id = ""  # Enter ID of the previous message to respond to
payload = json.dumps({
    "previous_message_id": message_id,
    "content": "Make the LinkedIn post less formal."
})

response = requests.request("POST", url, headers=headers, data=payload)
print(response.text)  # SSE-Event-Stream

Advanced features

To utilize the advanced features of Alan, you can pass additional parameters in the chat request.

The most important additional parameters are described below.

Some parameters can also be updated in existing chats using the PUT chat endpoint (see Swagger documentation). The updates will then be considered from the next generation onwards.

Knowledge databases

To use knowledge databases, add the IDs of the desired knowledge database(s) in the chat request.

python
import requests
import json

API_KEY = ""  # Enter API-Key. Starts with "alan-"

url = "https://app.alan.de/api/v1/chats/"

headers = {"accept": "application/json", "Content-Type": "application/json",  "Authorization": f"Bearer {API_KEY}"}
knowledgebase_ids = [""]  # Enter IDs of the desired knowledge database(s)
payload = json.dumps({
    "content": "What is the importance of AI for the economic location Germany?",
    "settings": {
      "model": "comma-soft/comma-llm-agentic",
      "knowledgebase_ids": knowledgebase_ids
    }
})

response = requests.request("POST", url, headers=headers, data=payload)
print(response.text)  # SSE-Event-Stream

Files

To chat with files, you first need to upload the desired file(s) to Alan.

python
import requests
import json

API_KEY = ""  # Enter API-Key. Starts with "alan-"

url = "https://app.alan.de/api/v1/files/"

headers = {"accept": "application/json", "Content-Type": "multipart/form-data",  "Authorization": f"Bearer {API_KEY}"}

file_path = ""  # Enter file path
with open(file_path, "rb") as f:
    file_content = f.read()
files = {"file": (file_path.name, file_content, "text/plain")}

response = requests.request("POST", url, headers=headers, files=files)

file_id = response.json()["resource_id"]

Once the files are uploaded and fully processed (status_parsing is processed or fallback), you can add the IDs of the uploaded file(s) in the chat request.

Note that the files you add must not contain more text than Alan can process at once.

python
import requests
import json

API_KEY = ""  # Enter API-Key. Starts with "alan-"

url = "https://app.alan.de/api/v1/chats/"

headers = {"accept": "application/json", "Content-Type": "application/json",  "Authorization": f"Bearer {API_KEY}"}

file_ids = [""]  # Enter IDs of the desired file(s)
payload = json.dumps({
    "content": "Summarize the attached article about the importance of AI for the economic location Germany.",
    "settings": {
      "model": "comma-soft/comma-llm-agentic"
    },
    "attached_files": file_ids
})

response = requests.request("POST", url, headers=headers, data=payload)
print(response.text)  # SSE-Event-Stream

Experts

To use experts, add the ID of the desired expert in the chat request.

Note that the expert must be configured to have the desired model set in the expert.

All parameters you set in the settings field of the chat request are ignored when using an expert.

python
import requests
import json

API_KEY = ""  # Enter API-Key. Starts with "alan-"

url = "https://app.alan.de/api/v1/chats/"

headers = {"accept": "application/json", "Content-Type": "application/json",  "Authorization": f"Bearer {API_KEY}"}

expert_id = ""  # Enter ID of the desired expert
payload = json.dumps({
    "content": "Write a post about the importance of AI for the economic location Germany.",
    "expert_id": expert_id,
    "load_expert_instead_of_settings": True
})

response = requests.request("POST", url, headers=headers, data=payload)
print(response.text)  # SSE-Event-Stream

Abilities

To use abilities, add the IDs of the desired ability(ies) in the chat request.

In the settings field of the chat request, you can fill the parameter abilities_system to use abilities included in Alan. You can retrieve the available abilities included in Alan beforehand via the GET /abilities/system endpoint

To use connected abilities, fill the parameter abilities_mcp in the settings field with the IDs of the desired connected ability(ies). You can retrieve the available connected abilities beforehand via the GET /abilities/mcp endpoint.

To set the approval behavior for used abilities on a per-chat basis, fill the parameter ability_approval_preferences in the settings field.

For example, you can use the internet ability with automatic usage approval as follows:

python
import requests
import json

API_KEY = ""  # Enter API-Key. Starts with "alan-"

url = "https://app.alan.de/api/v1/chats/"

headers = {"accept": "application/json", "Content-Type": "application/json",  "Authorization": f"Bearer {API_KEY}"}

payload = json.dumps({
    "content": "What are the current news about the AI industry in Germany?",
    "settings": {
      "model": "comma-soft/comma-llm-agentic",
      "abilities_system": ["web"],
      "ability_approval_preferences": {
          "web": "auto"
      }
    }
})

response = requests.request("POST", url, headers=headers, data=payload)
print(response.text)  # SSE-Event-Stream