API Dokumentation

Alles, was Sie brauchen, um CupidBot in Ihre Dating-Plattform zu integrieren

Base URL

https://api.cupidbot.de
🔑

Authentication

X-API-Key: mk_xxxxx
⏱️

Response Time

~30-70 Sekunden

Quick Start

# Quick Start Guide ## 1. Account erstellen Registrieren Sie sich auf [cupidbot.de/signup](/signup) und wählen Sie Ihren Tarif. ## 2. Email verifizieren Bestätigen Sie Ihre Email-Adresse über den Link in der Bestätigungs-Email. ## 3. API Key erstellen Nach der Verifizierung können Sie im Dashboard Ihren ersten API Key erstellen. ## 4. Erste Anfrage senden ```bash curl -X POST https://api.cupidbot.de/api/v1/chat \ -H "X-API-Key: mk_xxxxx" \ -H "Content-Type: application/json" \ -d '{ "session_id": "user_12345", "message": "Hey! Wie gehts?" }' ``` ## 5. Response erhalten ```json { "session_id": "user_12345", "response": "hey mir gehts super danke 😊 und dir?", "character": { "name": "Lisa", "age": 25, "location": "Berlin", "physical_description": "Ich bin 168cm groß, schlank mit langen braunen Haaren und grünen Augen.", "personality_summary": "freundlich, offen, humorvoll", "interests": ["Reisen", "Fotografie", "Yoga", "Kochen"] }, "photo_url": null, "timing": { "read_delay": 0.0, "thinking_delay": 0.0, "typing_delay": 0.0, "total_delay": 0.0, "show_typing": 0.0 }, "show_typing": false, "processing_time": 180.5, "timestamp": "2025-11-24T15:30:00Z", "conversation_mode": "flirty" } ``` **Wichtig:** Die Response-Zeit beträgt durchschnittlich 30-70 Sekunden pro Nachricht (GPU-Inferenz mit 14B-Modell + LoRA).

API Reference

# API Reference ## Base URL ``` https://api.cupidbot.de ``` ## Authentication Alle API-Requests benötigen einen API Key im Header: ``` X-API-Key: mk_xxxxx ``` API Keys können Sie im [Dashboard](/dashboard/keys) erstellen und verwalten. --- ## Hauptendpoint: POST /api/v1/chat Senden Sie eine Nachricht und erhalten Sie eine menschlich wirkende Antwort. ### Request Body ```json { "session_id": "user_session_12345", "message": "Hey! Wie geht's dir?", "conversation_mode": "flirty", "bot_context": { "name": "Lisa", "age": 25, "location": "Berlin", "relationship_goal": "serious", "photos": [ "https://example.com/photo1.jpg", "https://example.com/photo2.jpg" ] }, "user_context": { "city": "München", "country": "Deutschland", "current_date": "2025-11-24", "current_time": "18:30", "weather": "sonnig, 22°C", "timezone": "Europe/Berlin" }, "read_delay_multiplier": 0.0, "thinking_delay_multiplier": 0.0, "typing_delay_multiplier": 0.0 } ``` ### Request Parameter | Parameter | Typ | Pflicht | Beschreibung | |-----------|-----|---------|--------------| | `session_id` | string | **Ja** | Eindeutige Session-ID für Konversationskontinuität | | `message` | string | **Ja** | Nachricht des Users (1-1000 Zeichen) | | `conversation_mode` | string | Nein | Gesprächsstil: `flirty`, `intimate`, `casual`, `seductive` (Standard: `flirty`) | | `bot_context` | object | Nein | Bot-Charakter-Informationen (siehe BotContext unten) | | `user_context` | object | Nein | User-Kontext-Informationen (siehe UserContext unten) | | `read_delay_multiplier` | float | Nein | Multiplikator für Leseverzögerung (0.0 = sofort, 1.0 = normal, 2.0 = langsam, Standard: 0.0) | | `thinking_delay_multiplier` | float | Nein | Multiplikator für Denkverzögerung (Standard: 0.0) | | `typing_delay_multiplier` | float | Nein | Multiplikator für Tippverzögerung (Standard: 0.0) | | `debug` | boolean | Nein | Debug-Modus aktivieren (Standard: false) | ### BotContext Object | Feld | Typ | Beschreibung | |------|-----|--------------| | `name` | string | Name des Bots | | `age` | integer | Alter des Bots (18-35) | | `location` | string | Standort/Stadt des Bots | | `relationship_goal` | string | Beziehungsziel: `casual`, `serious`, `friendship`, `unsure` | | `photos` | array | Liste von Foto-URLs (Bot sendet sie während der Konversation) | ### UserContext Object | Feld | Typ | Beschreibung | |------|-----|--------------| | `city` | string | Stadt des Users | | `country` | string | Land des Users | | `current_date` | string | Aktuelles Datum (z.B. '2025-11-24' oder 'Freitag, 24. November') | | `current_time` | string | Aktuelle Uhrzeit (z.B. '18:30') | | `weather` | string | Aktuelles Wetter (z.B. 'sonnig, 22°C') | | `timezone` | string | Zeitzone des Users (z.B. 'Europe/Berlin') | ### Response ```json { "session_id": "user_session_12345", "response": "hey mir gehts super danke 😊 und dir?", "character": { "name": "Lisa", "age": 25, "location": "Berlin", "physical_description": "Ich bin 168cm groß, schlank mit langen braunen Haaren und grünen Augen.", "personality_summary": "freundlich, offen, humorvoll", "interests": ["Reisen", "Fotografie", "Yoga", "Kochen"] }, "photo_url": null, "timing": { "read_delay": 0.0, "thinking_delay": 0.0, "typing_delay": 0.0, "total_delay": 0.0, "show_typing": 0.0 }, "show_typing": false, "processing_time": 180.5, "timestamp": "2025-11-24T18:30:45.123456", "conversation_mode": "flirty", "debug": null } ``` ### Response Felder | Feld | Typ | Beschreibung | |------|-----|--------------| | `session_id` | string | Session-Identifier | | `response` | string | Bot-Antwort (Deutsch, Kleinbuchstaben, lockerer Stil) | | `character` | object | Charakter-Informationen | | `photo_url` | string/null | URL zu Foto (falls Bot eines sendet) | | `timing` | object | Simulierte menschliche Verzögerungen | | `show_typing` | boolean | Ob Typing-Indikator angezeigt werden soll | | `processing_time` | float | Server-Verarbeitungszeit in Sekunden | | `timestamp` | string | Response-Zeitstempel (ISO 8601) | | `conversation_mode` | string | Aktueller Konversationsmodus | | `debug` | object/null | Debug-Informationen (nur wenn debug=true) | ### Response-Zeit - **Durchschnitt:** 30-70 Sekunden pro Request - **Modell:** Qwen2.5-14B-Instruct mit LoRA Fine-Tuning - **Device:** GPU-Inferenz (NVIDIA RTX 4000 SFF Ada, 20GB VRAM) - **Timeout:** 600 Sekunden (10 Minuten) **Wichtig:** Implementieren Sie Client-seitiges Timeout-Handling! --- ## Zusätzliche Endpoints ### POST /api/v1/chat/preload Laden Sie bestehende Konversationshistorie vor (z.B. bei Migration von anderen Plattformen). **Use Cases:** - Migration von Konversationen von einer anderen Plattform - Wiederherstellung der Konversationshistorie nach Systemmigration - Vorab-Befüllung von Konversationen für Tests **Request:** ```json { "session_id": "user_12345", "bot_context": { "name": "Lisa", "age": 25, "location": "München", "relationship_goal": "serious" }, "messages": [ { "role": "user", "content": "Hey! Wie gehts?", "timestamp": "2025-11-24T10:00:00Z" }, { "role": "assistant", "content": "Hey! Mir gehts super! Und dir?", "timestamp": "2025-11-24T10:00:05Z" } ], "source": "client_import", "extract_facts": true, "batch_size": 20 } ``` **Request Parameter:** | Parameter | Typ | Pflicht | Beschreibung | |-----------|-----|---------|--------------| | `session_id` | string | Ja | Eindeutige Session-ID | | `messages` | array | Ja | Liste der zu ladenden Nachrichten (min. 1) | | `messages[].role` | string | Ja | Nachrichtenrolle: `user` oder `assistant` | | `messages[].content` | string | Ja | Nachrichteninhalt | | `messages[].timestamp` | string | Nein | ISO-Format Zeitstempel (optional) | | `bot_context` | object | Nein | Bot-Kontext-Informationen | | `character_id` | string | Nein | Charakter-ID (optional, kann stattdessen bot_context verwenden) | | `source` | string | Nein | Quelle der Nachrichten (Standard: `client_import`) | | `extract_facts` | boolean | Nein | Automatische Faktenextraktion (Standard: `true`) | | `batch_size` | integer | Nein | Batch-Größe für Faktenextraktion (Standard: `20`) | **Response:** ```json { "success": true, "session_id": "user_12345", "total_messages": 2, "saved_count": 2, "failed_count": 0, "cached_in_redis": 2, "extracted_facts": { "user_facts": { "name": "Max", "age": "28", "city": "München", "profession": "Software-Entwickler" }, "bot_facts": { "favorite_food": "Pizza", "hobbies": "Yoga und Reisen" } }, "facts_count": 6, "error": null } ``` **Was passiert während des Preload:** 1. **PostgreSQL-Speicherung**: Alle Nachrichten werden mit `is_preloaded=True` Flag gespeichert 2. **Redis-Cache**: Letzte 100 Nachrichten werden für schnellen Zugriff gecacht (24h TTL) 3. **Vector Memory**: Nachrichten werden zu ChromaDB für semantische Suche hinzugefügt 4. **Session-Erstellung**: Session wird erstellt, falls sie nicht existiert 5. **Charakter-Setup**: Charakter wird aus bot_context erstellt/geladen 6. **Faktenextraktion** (wenn `extract_facts=true`): - Verarbeitet Nachrichten in Batches (Standard: 20 Nachrichten pro Batch) - Extrahiert **User-Fakten** (was der User über sich gesagt hat) - Extrahiert **Bot-Fakten** (was der Bot über sich gesagt hat) - Speichert beide Typen in der Datenbank im Format: `{"user_facts": {...}, "bot_facts": {...}}` - Verwendet BASE-Modell (Qwen2.5-14B-Instruct) für Extraktion **Extrahierte Faktentypen:** **User-Fakten:** - `name`, `age`, `city`, `profession`, `hobbies`, `relationship_status`, `education`, `pets`, `siblings`, `favorite_food`, `favorite_music`, etc. **Bot-Fakten:** - `favorite_food`, `hobbies`, `interests`, `personality_traits`, `preferences`, etc. **Performance:** - **Verarbeitungszeit**: ~2-5 Sekunden pro Batch (20 Nachrichten) - **Modell**: Qwen2.5-14B-Instruct (BASE-Modell, nicht LoRA) - **Genauigkeit**: ~90%+ für explizite Fakten ### POST /api/v1/chat/{session_id}/extract-facts-batch Extrahieren Sie Fakten aus der gesamten Konversationshistorie mittels Batch-Verarbeitung. **Use Cases:** - Vorgeladene Konversationen, die ohne Faktenextraktion importiert wurden - Neuextraktion von Fakten nach Modell-Updates - Behebung fehlender Fakten in alten Konversationen **URL Parameter:** | Parameter | Typ | Pflicht | Beschreibung | |-----------|-----|---------|--------------| | `session_id` | string | Ja | Zu verarbeitende Session-ID | **Query Parameter:** | Parameter | Typ | Pflicht | Beschreibung | |-----------|-----|---------|--------------| | `batch_size` | integer | Nein | Nachrichten pro Batch (Standard: `20`) | **Response:** ```json { "success": true, "session_id": "user_12345", "total_messages": 150, "user_messages": 75, "processed_count": 75, "extracted_facts": { "user_facts": { "name": "Max", "age": "28", "city": "München", "profession": "Software-Entwickler", "hobbies": "Sport und Reisen" }, "bot_facts": { "favorite_food": "Pizza und Pasta", "hobbies": "Yoga und Fotografie" } }, "facts_count": 7 } ``` ### GET /api/v1/session/{session_id} Abrufen von Session-Informationen einschließlich Charakter-Details und Nachrichtenanzahl. **Response:** ```json { "session_id": "user_12345", "character": { "name": "Lisa", "age": 25, "location": "Berlin", "physical_description": "Ich bin 168cm groß, schlank mit langen braunen Haaren und grünen Augen.", "personality_summary": "freundlich, offen, humorvoll", "interests": ["Reisen", "Fotografie", "Yoga", "Kochen"] }, "message_count": 42, "created_at": "2025-11-24T10:00:00Z", "last_activity": "2025-11-24T18:30:00Z" } ``` **Hinweis:** Dieser Endpoint benötigt KEINE Authentifizierung (für Rückwärtskompatibilität).

Code-Beispiele

# Integration Examples ## Node.js / TypeScript ```javascript const axios = require('axios'); async function sendChatMessage(sessionId, message, botContext = null) { try { const response = await axios.post( 'https://api.cupidbot.de/api/v1/chat', { session_id: sessionId, message: message, conversation_mode: 'flirty', bot_context: botContext || { name: 'Lisa', age: 25, location: 'Berlin', relationship_goal: 'serious' }, user_context: { city: 'München', current_date: new Date().toISOString().split('T')[0], current_time: new Date().toTimeString().split(' ')[0].substring(0, 5), weather: 'sonnig, 22°C' }, read_delay_multiplier: 0.0, thinking_delay_multiplier: 0.0, typing_delay_multiplier: 0.0 }, { headers: { 'X-API-Key': process.env.CUPIDBOT_API_KEY, 'Content-Type': 'application/json' }, timeout: 600000 // 10 minutes timeout (30-70s average response time) } ); return { message: response.data.response, character: response.data.character, timing: response.data.timing, processing_time: response.data.processing_time }; } catch (error) { if (error.response?.status === 429) { console.error('Rate limit exceeded'); } else if (error.response?.status === 401) { console.error('Invalid API key'); } else if (error.code === 'ECONNABORTED') { console.error('Request timeout (>10 minutes)'); } else { console.error('Error:', error.message); } throw error; } } // Verwendung sendChatMessage('user_12345', 'Hey! Wie gehts?') .then(result => { console.log('Bot:', result.message); console.log('Processing time:', result.processing_time, 'seconds'); }) .catch(err => console.error(err)); ``` ## Python ```python import requests import os from typing import Optional, Dict from datetime import datetime def send_chat_message( session_id: str, message: str, bot_context: Optional[Dict] = None ) -> Dict: """Send a message to CupidBot API""" url = 'https://api.cupidbot.de/api/v1/chat' payload = { 'session_id': session_id, 'message': message, 'conversation_mode': 'flirty', 'user_context': { 'city': 'München', 'current_date': datetime.now().strftime('%Y-%m-%d'), 'current_time': datetime.now().strftime('%H:%M'), 'weather': 'sonnig, 22°C' }, 'read_delay_multiplier': 0.0, 'thinking_delay_multiplier': 0.0, 'typing_delay_multiplier': 0.0 } if bot_context: payload['bot_context'] = bot_context else: payload['bot_context'] = { 'name': 'Lisa', 'age': 25, 'location': 'Berlin', 'relationship_goal': 'serious' } headers = { 'X-API-Key': os.getenv('CUPIDBOT_API_KEY'), 'Content-Type': 'application/json' } try: response = requests.post( url, json=payload, headers=headers, timeout=600 # 10 minutes (30-70s average response time) ) response.raise_for_status() data = response.json() return { 'message': data['response'], 'character': data['character'], 'timing': data['timing'], 'processing_time': data['processing_time'] } except requests.exceptions.HTTPError as e: if e.response.status_code == 429: print('Rate limit exceeded') elif e.response.status_code == 401: print('Invalid API key') raise except requests.exceptions.Timeout: print('Request timeout (>10 minutes)') raise # Verwendung result = send_chat_message('user_12345', 'Hey! Wie gehts?') print(f"Bot: {result['message']}") print(f"Processing time: {result['processing_time']} seconds") ``` ## PHP ```php <?php function sendChatMessage($sessionId, $message, $botContext = null) { $url = 'https://api.cupidbot.de/api/v1/chat'; $payload = [ 'session_id' => $sessionId, 'message' => $message, 'conversation_mode' => 'flirty', 'user_context' => [ 'city' => 'München', 'current_date' => date('Y-m-d'), 'current_time' => date('H:i'), 'weather' => 'sonnig, 22°C' ], 'read_delay_multiplier' => 0.0, 'thinking_delay_multiplier' => 0.0, 'typing_delay_multiplier' => 0.0 ]; if ($botContext) { $payload['bot_context'] = $botContext; } else { $payload['bot_context'] = [ 'name' => 'Lisa', 'age' => 25, 'location' => 'Berlin', 'relationship_goal' => 'serious' ]; } $ch = curl_init($url); curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($payload)); curl_setopt($ch, CURLOPT_HTTPHEADER, [ 'X-API-Key: ' . getenv('CUPIDBOT_API_KEY'), 'Content-Type: application/json' ]); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_TIMEOUT, 600); // 10 minutes (30-70s average) $response = curl_exec($ch); $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); if (curl_errno($ch)) { throw new Exception('cURL error: ' . curl_error($ch)); } curl_close($ch); if ($httpCode === 429) { throw new Exception('Rate limit exceeded'); } elseif ($httpCode === 401) { throw new Exception('Invalid API key'); } elseif ($httpCode !== 200) { throw new Exception('HTTP error: ' . $httpCode); } $data = json_decode($response, true); return [ 'message' => $data['response'], 'character' => $data['character'], 'timing' => $data['timing'], 'processing_time' => $data['processing_time'] ]; } // Verwendung try { $result = sendChatMessage('user_12345', 'Hey! Wie gehts?'); echo "Bot: " . $result['message'] . "\n"; echo "Processing time: " . $result['processing_time'] . " seconds\n"; } catch (Exception $e) { echo 'Error: ' . $e->getMessage(); } ?> ```

Best Practices

# Best Practices ## 1. Session Management **Session-IDs:** - Verwenden Sie eindeutige Session-IDs pro User-Konversation - Format: `user_{user_id}` oder `session_{uuid}` - Speichern Sie Session-IDs persistent für Konversationskontinuität **Beispiel:** ```javascript const sessionId = `user_${userId}_${Date.now()}`; ``` ## 2. Timeout Handling **Wichtig:** API-Responses dauern 30-70 Sekunden! ```javascript // Node.js mit axios const response = await axios.post(url, data, { timeout: 120000 // 2 Minuten }); // Python mit requests response = requests.post(url, json=data, timeout=120) // PHP mit cURL curl_setopt($ch, CURLOPT_TIMEOUT, 120); ``` ## 3. Error Handling ```javascript try { const response = await sendChatMessage(sessionId, message); // Success } catch (error) { if (error.response?.status === 429) { // Rate limit exceeded console.log('Zu viele Anfragen. Bitte warten.'); } else if (error.response?.status === 401) { // Invalid API key console.error('Ungültiger API Key'); } else if (error.code === 'ECONNABORTED') { // Timeout console.error('Request timeout (>120s)'); } else { // Other errors console.error('Fehler:', error.message); } } ``` ## 4. Security **API Key Sicherheit:** - ❌ **NIEMALS** API Keys im Frontend-Code speichern - ✅ Verwenden Sie Backend-Proxy für API-Calls - ✅ Nutzen Sie Environment Variables - ✅ Rotieren Sie Keys regelmäßig im Dashboard **Beispiel Backend-Proxy (Node.js):** ```javascript // Backend API Route app.post('/api/chat', async (req, res) => { // Authentifizieren Sie Ihren User const userId = req.session.userId; // Rufen Sie CupidBot API auf const response = await axios.post( 'https://api.cupidbot.de/api/v1/chat', { session_id: `user_${userId}`, message: req.body.message }, { headers: { 'X-API-Key': process.env.CUPIDBOT_API_KEY } } ); res.json(response.data); }); ``` ## 5. Rate Limiting **Tarif-Limits beachten:** - **Free Trial:** 100 Nachrichten / 7 Tage - **Basic:** 500 Nachrichten / Tag - **Pro:** 2.000 Nachrichten / Tag - **Business:** 10.000 Nachrichten / Tag - **Enterprise:** Unlimited **Client-seitiges Rate Limiting:** ```javascript let lastRequestTime = 0; const MIN_REQUEST_INTERVAL = 1000; // 1 Sekunde async function sendMessage(message) { const now = Date.now(); const timeSinceLastRequest = now - lastRequestTime; if (timeSinceLastRequest < MIN_REQUEST_INTERVAL) { await new Promise(resolve => setTimeout(resolve, MIN_REQUEST_INTERVAL - timeSinceLastRequest) ); } lastRequestTime = Date.now(); return await apiCall(message); } ``` ## 6. Performance Optimierung **Caching:** - Cachen Sie Character-Informationen - Speichern Sie Konversationshistorie lokal - Nutzen Sie Redis für Session-Daten **Connection Pooling:** ```javascript // Node.js mit axios const axiosInstance = axios.create({ baseURL: 'https://api.cupidbot.de', timeout: 120000, headers: { 'X-API-Key': process.env.CUPIDBOT_API_KEY }, // Connection pooling httpAgent: new http.Agent({ keepAlive: true }), httpsAgent: new https.Agent({ keepAlive: true }) }); ``` ## 7. Monitoring **Wichtige Metriken:** - API Response Times (sollte 30-70s sein) - Error Rates (sollte <1% sein) - Rate Limit Hits - Nachrichtenvolumen pro Tag **Dashboard nutzen:** - Überwachen Sie Ihre Usage im [Dashboard](/dashboard/usage) - Setzen Sie Alerts für 80% Limit-Auslastung - Analysieren Sie Error-Logs ## 8. Testing **Vor Production:** - Testen Sie mit verschiedenen Nachrichtentypen - Prüfen Sie Timeout-Handling - Testen Sie Error-Szenarien (ungültiger Key, Rate Limit) - Validieren Sie Session-Kontinuität **Playground nutzen:** - Testen Sie API-Calls direkt im [Dashboard](/dashboard/keys) - Experimentieren Sie mit verschiedenen `bot_context` Parametern - Prüfen Sie Response-Qualität

Brauchen Sie Hilfe?

Unser Support-Team hilft Ihnen gerne bei der Integration