Sechs erstklassige LLMs (FlowAI, ChatGPT, Claude, Gemini, Grok, Perplexity) hinter einer einzigen, OpenAI-kompatiblen Chat-Completions-Schnittstelle. Tauschen Sie jeden bestehenden OpenAI-SDK-Aufruf gegen unsere Basis-URL und nutzen Sie Streaming, faire Limits und Trace-IDs ab Tag eins.
https://creativeskyline.de/api/flowai/v1/models
https://creativeskyline.de/api/flowai/v1/chat/completions
pk_-Präfix aus Profil → API-ZugangAlle Endpunkte hängen am gemeinsamen Versions-Prefix:
BASE_URL/api/flowai/v1
Versionierung folgt dem OpenAI-Schema. Breaking Changes erscheinen unter v2, sodass bestehende Integrationen nicht brechen.
Die FlowAI-API akzeptiert nur den Standard-OpenAI-Header Authorization: Bearer …. Token in Query-Parametern, im Body oder in alternativen Headern werden mit HTTP 401 und Code invalid_token_source abgelehnt.
Authorization: Bearer pk_dein_api_key\nAccept: application/json\nContent-Type: application/json
https://creativeskyline.de/api/flowai/v1/models
https://creativeskyline.de/api/flowai/v1/chat/completions
Endpoint: GET /api/flowai/v1/models
Liefert die Liste der Modell-Aliase, die fĂĽr Ihren Account freigeschaltet sind.
{\n "object": "list",\n "data": [\n {"id":"flowai","object":"model","created":1735000000,"owned_by":"creativeskyline"},\n {"id":"chatgpt","object":"model","created":1735000000,"owned_by":"creativeskyline"}\n ],\n "flowai_request_id": "01HXYZ…ULID"\n}flowai - Allrounder: kombiniert die besten Modelle für jede Aufgabechatgpt - Kreativ: Brainstorming, Texte, E-Mails, Copywritingclaude - Analytisch: lange Dokumente, präzise Anweisungen, Nuancengemini - Technisch: Datenanalyse, Kalkulationen, multimodalgrok - Schnell: prägnante Antworten, Faktencheck, Quick-Lookupsperplexity - Recherche: aktuelle Web-Quellen, fundierte Recherche-Antworten
https://creativeskyline.de/api/flowai/v1/models
https://creativeskyline.de/api/flowai/v1/chat/completions
model - einer der sechs Aliase (string, kebab-case)messages[] - 1 bis 50 Einträge mit role (system/user/assistant/tool) und contentstream - Boolean (Standard: false)temperature - 0 bis 2max_tokens - 1 bis 128.000top_p, frequency_penalty, presence_penalty, stop, seed, user/api/flowai/v1/chat/completions
Sendet eine Konversation und erhält eine vollständige JSON-Antwort. Standardverhalten ohne stream oder mit stream: false. Body-Limit: 128 KB, max. 50 Nachrichten, max. 32.000 Zeichen pro Nachricht.
model
string
*
Modell-Alias: flowai, chatgpt, claude, gemini, grok oder perplexity
messages
array
*
1 bis 50 Nachrichten mit role (system/user/assistant) und content
stream
boolean
false (Standard) für vollständige JSON-Antwort
temperature
number
Kreativität 0 bis 2
max_tokens
integer
1 bis 128.000
{"id":"chatcmpl_01HXYZ…ULID","object":"chat.completion","created":1735000000,"model":"claude","choices":[{"index":0,"message":{"role":"assistant","content":"Das Reinheitsgebot von 1516 erlaubt für Bier nur …"},"finish_reason":"stop"}],"usage":{"prompt_tokens":42,"completion_tokens":87,"total_tokens":129},"flowai_request_id":"01HXYZ…ULID"}
/api/flowai/v1/chat/completions
SSE / Streaming
SSE
Sendet eine Konversation und empfängt die Antwort Token für Token via Server-Sent Events. Setzen Sie "stream": true im Body. Antwort kommt mit Content-Type: text/event-stream; Proxy-Buffering ist über X-Accel-Buffering: no deaktiviert.
model
string
*
Modell-Alias: flowai, chatgpt, claude, gemini, grok oder perplexity
messages
array
*
1 bis 50 Nachrichten mit role und content
stream
boolean
*
true - aktiviert den SSE-Streaming-Modus
data: {"id":"chatcmpl_01HXYZ…","object":"chat.completion.chunk","created":1735000000,"model":"claude","choices":[{"index":0,"delta":{"role":"assistant"},"finish_reason":null}]}
data: {"id":"chatcmpl_01HXYZ…","object":"chat.completion.chunk","created":1735000000,"model":"claude","choices":[{"index":0,"delta":{"content":"Das "},"finish_reason":null}]}
data: {"id":"chatcmpl_01HXYZ…","object":"chat.completion.chunk","created":1735000000,"model":"claude","choices":[{"index":0,"delta":{"content":"Reinheitsgebot "},"finish_reason":null}]}
data: {"id":"chatcmpl_01HXYZ…","object":"chat.completion.chunk","created":1735000000,"model":"claude","choices":[{"index":0,"delta":{},"finish_reason":"stop"}],"usage":{"prompt_tokens":42,"completion_tokens":87,"total_tokens":129}}
data: [DONE]
https://creativeskyline.de/api/flowai/v1/models
https://creativeskyline.de/api/flowai/v1/chat/completions
Übergrößen werden mit HTTP 413 und Code payload_too_large abgelehnt.
Antworten enthalten OpenAI-kompatible Header: x-ratelimit-limit-requests, x-ratelimit-remaining-requests, x-ratelimit-reset-requests.
https://creativeskyline.de/api/flowai/v1/models
https://creativeskyline.de/api/flowai/v1/chat/completions
Alle Fehlerantworten haben dieselbe OpenAI-kompatible Struktur. Das Top-Level-Feld flowai_request_id ist immer enthalten.
{\n "error": {\n "message": "Authorization: Bearer header is required on the FlowAI API.",\n "type": "authentication_error",\n "code": "invalid_token_source",\n "param": null\n },\n "flowai_request_id": "01HXYZ…ULID"\n}400 invalid_field_value - Validierung fehlgeschlagen (Typ, Bereich, Pflichtfeld)400 unsupported_field - Feld noch nicht unterstützt (z.B. tools, response_format)401 invalid_token_source - Token nicht via Authorization: Bearer übergeben401 invalid_api_key - Token unbekannt, abgelaufen oder widerrufen401 no_active_subscription - Workspace hat keinen aktiven Pro-Tarif404 model_not_found - Unbekannter Alias (gültige Aliase siehe /v1/models)413 payload_too_large - Request-Body über 128 KB429 rate_limit_exceeded - 60/min oder 5/sec überschritten502 provider_unavailable - Upstream-Provider nicht erreichbar/api/flowai/v1/chat/completions
curl -X POST "https://creativeskyline.de/api/flowai/v1/chat/completions" \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{"model": "value", "messages": [], "stream": true, "temperature": 0, "max_tokens": 0}'
use Illuminate\Support\Facades\Http;
$response = Http::withToken('YOUR_API_TOKEN')
->post('https://creativeskyline.de/api/flowai/v1/chat/completions', [
'model' => 'value',
'messages' => [],
'stream' => true,
'temperature' => 0,
'max_tokens' => 0,
]);
$data = $response->json();
const response = await fetch('https://creativeskyline.de/api/flowai/v1/chat/completions', {
method: 'POST',
headers: {
'Authorization': 'Bearer YOUR_API_TOKEN',
'Accept': 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
model: 'value',
messages: [],
stream: true,
temperature: 0,
max_tokens: 0,
}),
});
const data = await response.json();
import requests
headers = {
'Authorization': 'Bearer YOUR_API_TOKEN',
'Accept': 'application/json',
}
payload = {
'model': 'value',
'messages': [],
'stream': True,
'temperature': 0,
'max_tokens': 0,
}
response = requests.post(
'https://creativeskyline.de/api/flowai/v1/chat/completions',
headers=headers,
json=payload,
)
data = response.json()
/api/flowai/v1/chat/completions
# Das -N-Flag deaktiviert cURLs internen Zeilenpuffer, sodass SSE-Frames live durchlaufen
curl -N -X POST "https://creativeskyline.de/api/flowai/v1/chat/completions" \
-H "Authorization: Bearer pk_dein_api_key" \
-H "Content-Type: application/json" \
-d '{
"model": "claude",
"stream": true,
"messages": [
{ "role": "user", "content": "Erkläre Server-Sent Events in zwei Sätzen." }
]
}'
// PHP Streaming mit HTTP-Stream-Wrapper
$context = stream_context_create([
'http' => [
'method' => 'POST',
'header' => implode("\r\n", [
'Authorization: Bearer ' . getenv('FLOWAI_API_KEY'),
'Content-Type: application/json',
'Accept: text/event-stream',
]),
'content' => json_encode([
'model' => 'claude',
'stream' => true,
'messages' => [['role' => 'user', 'content' => 'Erkläre SSE in zwei Sätzen.']],
]),
],
]);
$stream = fopen('https://creativeskyline.de/api/flowai/v1/chat/completions', 'r', false, $context);
while (!$feof($stream)) {
$line = fgets($stream);
if (str_starts_with($line, 'data: ')) {
$data = trim(substr($line, 6));
if ($data === '[DONE]') break;
$chunk = json_decode($data, true);
echo $chunk['choices'][0]['delta']['content'] ?? '';
}
}
fclose($stream);
import OpenAI from "openai";
const client = new OpenAI({
apiKey: process.env.FLOWAI_API_KEY,
baseURL: "https://creativeskyline.de/api/flowai/v1",
});
const stream = await client.chat.completions.create({
model: "claude",
stream: true,
messages: [
{ role: "user", content: "Erkläre Server-Sent Events in zwei Sätzen." },
],
});
for await (const chunk of stream) {
process.stdout.write(chunk.choices[0]?.delta?.content ?? "");
}
// Oder mit nativer EventSource (Browser):
// const source = new EventSource('https://creativeskyline.de/api/flowai/v1/chat/completions');
// source.onmessage = (e) => {
// if (e.data === '[DONE]') { source.close(); return; }
// const chunk = JSON.parse(e.data);
// console.log(chunk.choices[0]?.delta?.content ?? '');
// };
from openai import OpenAI
client = OpenAI(
api_key="pk_dein_api_key",
base_url="https://creativeskyline.de/api/flowai/v1",
)
# openai-SDK kĂĽmmert sich automatisch um SSE-Parsing
with client.chat.completions.stream(
model="claude",
messages=[{"role": "user", "content": "Erkläre SSE in zwei Sätzen."}],
) as stream:
for text in stream.text_stream:
print(text, end="", flush=True)
# Alternativ mit Requests (manuelles SSE-Parsing)
# import requests
# resp = requests.post(
# 'https://creativeskyline.de/api/flowai/v1/chat/completions',
# headers={'Authorization': 'Bearer pk_...', 'Accept': 'text/event-stream'},
# json={'model': 'claude', 'stream': True, 'messages': [...]},
# stream=True,
# )
# for line in resp.iter_lines():
# if line.startswith(b'data: '):
# data = line[6:]
# if data == b'[DONE]': break
# chunk = json.loads(data)
# print(chunk['choices'][0]['delta'].get('content', ''), end='', flush=True)
curl -X POST "https://creativeskyline.de/api/flowai/v1/chat/completions" \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{"model": "value", "messages": [], "stream": true, "temperature": 0, "max_tokens": 0}'
use Illuminate\Support\Facades\Http;
$response = Http::withToken('YOUR_API_TOKEN')
->post('https://creativeskyline.de/api/flowai/v1/chat/completions', [
'model' => 'value',
'messages' => [],
'stream' => true,
'temperature' => 0,
'max_tokens' => 0,
]);
$data = $response->json();
const response = await fetch('https://creativeskyline.de/api/flowai/v1/chat/completions', {
method: 'POST',
headers: {
'Authorization': 'Bearer YOUR_API_TOKEN',
'Accept': 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
model: 'value',
messages: [],
stream: true,
temperature: 0,
max_tokens: 0,
}),
});
const data = await response.json();
import requests
headers = {
'Authorization': 'Bearer YOUR_API_TOKEN',
'Accept': 'application/json',
}
payload = {
'model': 'value',
'messages': [],
'stream': True,
'temperature': 0,
'max_tokens': 0,
}
response = requests.post(
'https://creativeskyline.de/api/flowai/v1/chat/completions',
headers=headers,
json=payload,
)
data = response.json()
# Das -N-Flag deaktiviert cURLs internen Zeilenpuffer, sodass SSE-Frames live durchlaufen
curl -N -X POST "https://creativeskyline.de/api/flowai/v1/chat/completions" \
-H "Authorization: Bearer pk_dein_api_key" \
-H "Content-Type: application/json" \
-d '{
"model": "claude",
"stream": true,
"messages": [
{ "role": "user", "content": "Erkläre Server-Sent Events in zwei Sätzen." }
]
}'
// PHP Streaming mit HTTP-Stream-Wrapper
$context = stream_context_create([
'http' => [
'method' => 'POST',
'header' => implode("\r\n", [
'Authorization: Bearer ' . getenv('FLOWAI_API_KEY'),
'Content-Type: application/json',
'Accept: text/event-stream',
]),
'content' => json_encode([
'model' => 'claude',
'stream' => true,
'messages' => [['role' => 'user', 'content' => 'Erkläre SSE in zwei Sätzen.']],
]),
],
]);
$stream = fopen('https://creativeskyline.de/api/flowai/v1/chat/completions', 'r', false, $context);
while (!$feof($stream)) {
$line = fgets($stream);
if (str_starts_with($line, 'data: ')) {
$data = trim(substr($line, 6));
if ($data === '[DONE]') break;
$chunk = json_decode($data, true);
echo $chunk['choices'][0]['delta']['content'] ?? '';
}
}
fclose($stream);
import OpenAI from "openai";
const client = new OpenAI({
apiKey: process.env.FLOWAI_API_KEY,
baseURL: "https://creativeskyline.de/api/flowai/v1",
});
const stream = await client.chat.completions.create({
model: "claude",
stream: true,
messages: [
{ role: "user", content: "Erkläre Server-Sent Events in zwei Sätzen." },
],
});
for await (const chunk of stream) {
process.stdout.write(chunk.choices[0]?.delta?.content ?? "");
}
// Oder mit nativer EventSource (Browser):
// const source = new EventSource('https://creativeskyline.de/api/flowai/v1/chat/completions');
// source.onmessage = (e) => {
// if (e.data === '[DONE]') { source.close(); return; }
// const chunk = JSON.parse(e.data);
// console.log(chunk.choices[0]?.delta?.content ?? '');
// };
from openai import OpenAI
client = OpenAI(
api_key="pk_dein_api_key",
base_url="https://creativeskyline.de/api/flowai/v1",
)
# openai-SDK kĂĽmmert sich automatisch um SSE-Parsing
with client.chat.completions.stream(
model="claude",
messages=[{"role": "user", "content": "Erkläre SSE in zwei Sätzen."}],
) as stream:
for text in stream.text_stream:
print(text, end="", flush=True)
# Alternativ mit Requests (manuelles SSE-Parsing)
# import requests
# resp = requests.post(
# 'https://creativeskyline.de/api/flowai/v1/chat/completions',
# headers={'Authorization': 'Bearer pk_...', 'Accept': 'text/event-stream'},
# json={'model': 'claude', 'stream': True, 'messages': [...]},
# stream=True,
# )
# for line in resp.iter_lines():
# if line.startswith(b'data: '):
# data = line[6:]
# if data == b'[DONE]': break
# chunk = json.loads(data)
# print(chunk['choices'][0]['delta'].get('content', ''), end='', flush=True)