Chatting via API
To use the chat features of Alan via the API, you have two options:
- 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.
- Direct use of the Alan Chats API: Alternatively, you can access the chat features directly via the Alan
chatsAPI 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
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
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.
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
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
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.
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.
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-StreamBy 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.
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.
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-StreamAdvanced 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.
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-StreamFiles
To chat with files, you first need to upload the desired file(s) to Alan.
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.
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-StreamExperts
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.
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-StreamAbilities
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:
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