Felo API PlatformFelo API Platform

Felo APIs

Chat API

Integrieren Sie KI-gestützte konversationelle Suche mit Query-Analyse, Web-Ressourcen und Zitaten.

POST/v2/chat

Authentifizierung

Bearer API key

Inhaltstyp

application/json

Hinweise zu Limits

Per API key and per user windows. Read X-RateLimit headers.

Die Chat API ermöglicht es Ihnen, KI-gestützte Konversationssuche in Ihre Anwendungen zu integrieren. Senden Sie eine natürlichsprachliche Abfrage und erhalten Sie eine intelligente Antwort, die aus Echtzeit-Websuche-Ergebnissen generiert wird.

Informationen zu Rate-Limits, Fehlerantworten und Wiederholungsverhalten finden Sie unter Fehler, Limits und Wiederholungen.

Überblick

Die Chat API führt die folgenden Schritte aus:

  1. Analysiert und optimiert Ihre Abfrage
  2. Durchsucht das Web nach relevanten Informationen
  3. Bewertet und filtert die Suchergebnisse
  4. Generiert eine umfassende KI-Antwort auf Grundlage der Quellen
  5. Gibt die Antwort zusammen mit Quellenangaben zurück

Anwendungsfälle:

  • Konversations-KI-Assistenten
  • Recherche- und Informationsabruf-Tools
  • Kundensupport-Chatbots mit Webwissen
  • Bildungsanwendungen
  • Content-Erstellungstools

Authentifizierung

Alle Anfragen an die Chat API erfordern eine Authentifizierung mit einem API-Schlüssel. Fügen Sie Ihren API-Schlüssel in den Authorization-Header ein:

Authorization: Bearer YOUR_API_KEY

Details zum Erhalten und Verwenden Ihres API-Schlüssels finden Sie im Authentifizierungsleitfaden.

Verwendung mit KI-Agenten

Installieren Sie das vollständige Paket felo-ai, wenn ein Agent Search und jeden anderen verfügbaren Felo-Skill verwenden soll. Der Installer ermittelt dynamisch jedes Paketverzeichnis mit SKILL.md und schließt daher künftige Skills ein, statt einer festen Teilmenge. Installieren Sie sie im nativen Verzeichnis für Ihren Agenten: Codex verwendet ~/.codex/skills, Claude Code verwendet ~/.claude/skills, OpenClaw verwendet ~/.agents/skills und Hermes Agent verwendet ~/.hermes/skills. Die manuelle Einrichtungsanleitung für KI-Agenten beschreibt die sichere Verknüpfung, den API-Schlüssel und die Prüfungsschritte für jede Plattform.

Endpoint

POST https://openapi.felo.ai/v2/chat

Anfrage

HeaderErforderlichBeschreibung
AuthorizationJaIhr API-Schlüssel im Format: Bearer YOUR_API_KEY
Content-TypeJaMuss application/json sein

Textkörper-Parameter

ParameterTypErforderlichBeschreibungEinschränkungen
querystringJaDie Frage oder Suchabfrage des Benutzers1–2000 Zeichen

Beispielanfrage

{
  "query": "What are the latest developments in quantum computing?"
}

Antwort

Erfolgreiche Antwort (200 OK)

Bei erfolgreicher Anfrage gibt die API eine JSON-Antwort mit folgender Struktur zurück:

{
  "status": "ok",
  "message": null,
  "data": {
    "id": "HabCj883yHLSXc8mWqu4Eq",
    "message_id": "18ea8517-5559-4f48-a355-1f8a79e73b71",
    "answer": "Recent developments in quantum computing include...",
    "query_analysis": {
      "queries": [
        "quantum computing latest developments 2025",
        "quantum computing breakthroughs"
      ]
    },
    "resources": [
      {
        "link": "https://example.com/quantum-news",
        "title": "Latest Quantum Computing Breakthroughs",
        "snippet": "Scientists have achieved a major milestone..."
      },
      {
        "link": "https://example.com/quantum-research",
        "title": "Quantum Computing Research 2025",
        "snippet": "New quantum algorithms show promise..."
      }
    ]
  }
}

Antwortfelder

FeldTypBeschreibung
statusstring | numberAntwortstatus: "ok" bei Erfolg; Fehlerantworten verwenden den HTTP-Statuscode als Zahl
messagestring | nullZusätzliche Meldung (null bei erfolgreichen Anfragen)
dataobjectAntwortdaten (nur vorhanden, wenn status "ok" ist)
data.idstringEindeutige Kennung dieser Chat-Sitzung
data.message_idstringEindeutige Kennung dieser Nachricht
data.answerstringKI-generierte Antwort auf die Abfrage
data.query_analysisobjectAnalyse der Benutzerabfrage
data.query_analysis.queriesstring[]Optimierte Suchabfragen, die aus der Benutzereingabe abgeleitet wurden
data.resourcesarrayListe der Webquellen, die zur Erstellung der Antwort verwendet wurden
data.resources[].linkstringURL der Quelle
data.resources[].titlestringTitel der Quellseite
data.resources[].snippetstringRelevanter Auszug aus der Quelle

Fehlerantwort

Bei einem Fehler gibt die API die gemeinsame Fehlerhülle zurück:

{
  "status": 401,
  "code": "UNAUTHORIZED",
  "message": "API Key is required",
  "request_id": "..."
}

Felder der Fehlerantwort

FeldTypBeschreibung
statusnumberHTTP-Statuscode; erfolgreiche Antworten verwenden "ok"
codestringFehlercode, der die Fehlerart angibt
messagestringMenschenlesbare Fehlerbeschreibung
request_idstringEindeutige Kennung dieser Anfrage (hilfreich für den Support)

Fehlercodes

HTTP-StatusCodeBedeutung
400Validierungscode des EndpointsDas Feld query fehlt, ist leer oder zu lang; lesen Sie message für das konkrete Problem
401UNAUTHORIZEDDer API-Schlüssel fehlt, ist ungültig oder widerrufen
429RATE_LIMITEDEin Rate-Limit wurde überschritten
502CHAT_FAILEDInterner Dienstfehler
503SERVICE_UNAVAILABLEDienst vorübergehend nicht verfügbar

Informationen zur gemeinsamen Fehlerhülle, zu weiteren Fehlercodes und zu Wiederholungsregeln finden Sie unter Fehler, Limits und Wiederholungen.

Beispiele

cURL

curl -X POST https://openapi.felo.ai/v2/chat \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "query": "What are the benefits of renewable energy?"
  }'

Antwort:

{
  "status": "ok",
  "message": null,
  "data": {
    "id": "HabCj883yHLSXc8mWqu4Eq",
    "message_id": "18ea8517-5559-4f48-a355-1f8a79e73b71",
    "answer": "Renewable energy offers numerous benefits including reduced greenhouse gas emissions, decreased air pollution, energy independence, job creation, and long-term cost savings. Solar, wind, and hydroelectric power are sustainable alternatives to fossil fuels that help combat climate change while providing reliable electricity.",
    "query_analysis": {
      "queries": [
        "renewable energy benefits",
        "advantages of renewable energy sources"
      ]
    },
    "resources": [
      {
        "link": "https://example.com/renewable-benefits",
        "title": "Top Benefits of Renewable Energy",
        "snippet": "Renewable energy sources provide clean, sustainable power..."
      }
    ]
  }
}

Python

import requests
import os

# Get API key from environment variable
api_key = os.environ.get('FELO_API_KEY')

url = 'https://openapi.felo.ai/v2/chat'
headers = {
    'Authorization': f'Bearer {api_key}',
    'Content-Type': 'application/json'
}
data = {
    'query': 'What are the benefits of renewable energy?'
}

try:
    response = requests.post(url, headers=headers, json=data)
    response.raise_for_status()  # Raise exception for HTTP errors

    result = response.json()

    if result['status'] == 'ok':
        print('Answer:', result['data']['answer'])
        print('\nSources:')
        for resource in result['data']['resources']:
            print(f"- {resource['title']}: {resource['link']}")
    else:
        print(f"Error: {result['code']} - {result['message']}")

except requests.exceptions.RequestException as e:
    print(f'Request failed: {e}')

JavaScript (Node.js)

const fetch = require('node-fetch');

const apiKey = process.env.FELO_API_KEY;
const url = 'https://openapi.felo.ai/v2/chat';

const headers = {
  'Authorization': `Bearer ${apiKey}`,
  'Content-Type': 'application/json'
};

const body = JSON.stringify({
  query: 'What are the benefits of renewable energy?'
});

fetch(url, { method: 'POST', headers, body })
  .then(response => {
    if (!response.ok) {
      throw new Error(`HTTP error! status: ${response.status}`);
    }
    return response.json();
  })
  .then(data => {
    if (data.status === 'ok') {
      console.log('Answer:', data.data.answer);
      console.log('\nSources:');
      data.data.resources.forEach(resource => {
        console.log(`- ${resource.title}: ${resource.link}`);
      });
    } else {
      console.error(`Error: ${data.code} - ${data.message}`);
    }
  })
  .catch(error => {
    console.error('Request failed:', error);
  });

JavaScript (Browser/Fetch API)

const apiKey = 'YOUR_API_KEY'; // In production, get this from your backend

fetch('https://openapi.felo.ai/v2/chat', {
  method: 'POST',
  headers: {
    'Authorization': `Bearer ${apiKey}`,
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    query: 'What are the benefits of renewable energy?'
  })
})
  .then(response => {
    if (!response.ok) {
      throw new Error(`HTTP error! status: ${response.status}`);
    }
    return response.json();
  })
  .then(data => {
    if (data.status === 'ok') {
      console.log('Answer:', data.data.answer);

      // Display sources
      const sourcesList = data.data.resources.map(resource =>
        `<li><a href="${resource.link}">${resource.title}</a></li>`
      ).join('');

      document.getElementById('answer').innerHTML = data.data.answer;
      document.getElementById('sources').innerHTML = sourcesList;
    } else {
      console.error(`Error: ${data.code} - ${data.message}`);
    }
  })
  .catch(error => {
    console.error('Request failed:', error);
  });

Go

package main

import (
    "bytes"
    "encoding/json"
    "fmt"
    "io"
    "net/http"
    "os"
)

type ChatRequest struct {
    Query string `json:"query"`
}

type ChatResponse struct {
    Status  string `json:"status"`
    Message string `json:"message,omitempty"`
    Data    struct {
        ID            string `json:"id"`
        MessageID     string `json:"message_id"`
        Answer        string `json:"answer"`
        QueryAnalysis struct {
            Queries []string `json:"queries"`
        } `json:"query_analysis"`
        Resources []struct {
            Link    string `json:"link"`
            Title   string `json:"title"`
            Snippet string `json:"snippet"`
        } `json:"resources"`
    } `json:"data,omitempty"`
    Code      string `json:"code,omitempty"`
    RequestID string `json:"request_id,omitempty"`
}

func main() {
    apiKey := os.Getenv("FELO_API_KEY")
    url := "https://openapi.felo.ai/v2/chat"

    requestBody := ChatRequest{
        Query: "What are the benefits of renewable energy?",
    }

    jsonData, err := json.Marshal(requestBody)
    if err != nil {
        fmt.Printf("Error marshaling request: %v\n", err)
        return
    }

    req, err := http.NewRequest("POST", url, bytes.NewBuffer(jsonData))
    if err != nil {
        fmt.Printf("Error creating request: %v\n", err)
        return
    }

    req.Header.Set("Authorization", "Bearer "+apiKey)
    req.Header.Set("Content-Type", "application/json")

    client := &http.Client{}
    resp, err := client.Do(req)
    if err != nil {
        fmt.Printf("Error making request: %v\n", err)
        return
    }
    defer resp.Body.Close()

    body, err := io.ReadAll(resp.Body)
    if err != nil {
        fmt.Printf("Error reading response: %v\n", err)
        return
    }

    var chatResp ChatResponse
    err = json.Unmarshal(body, &chatResp)
    if err != nil {
        fmt.Printf("Error unmarshaling response: %v\n", err)
        return
    }

    if chatResp.Status == "ok" {
        fmt.Println("Answer:", chatResp.Data.Answer)
        fmt.Println("\nSources:")
        for _, resource := range chatResp.Data.Resources {
            fmt.Printf("- %s: %s\n", resource.Title, resource.Link)
        }
    } else {
        fmt.Printf("Error: %s - %s\n", chatResp.Code, chatResp.Message)
    }
}

Rate-Limits

Benutzer mit einem aktiven kostenpflichtigen Felo-Abonnement (einschließlich Unternehmensabonnements) sind von allen Rate-Limits für /v2/chat ausgenommen, sowohl bei der Authentifizierung per API-Schlüssel als auch per OAuth. Ausgenommene Antworten enthalten keine X-RateLimit-*-Header.

Für Benutzer ohne kostenpflichtiges Abonnement gelten Rate-Limits in drei Dimensionen. Wenn der Abonnementstatus nicht verifiziert werden kann, gelten diese Limits weiterhin:

  • Pro API-Schlüssel – begrenzt Anfragen mit einem einzelnen API-Schlüssel innerhalb eines 1-Minuten-Fensters.
  • Pro Benutzer (Minute) – begrenzt die Gesamtzahl der Anfragen über alle API-Schlüssel eines Benutzers innerhalb eines 1-Minuten-Fensters.
  • Pro Benutzer (Stunde) – begrenzt die Gesamtzahl der Anfragen über alle API-Schlüssel eines Benutzers innerhalb eines 1-Stunden-Fensters.

Wird eine Dimension überschritten, führt dies zu einer Antwort 429 Too Many Requests.

Die genauen numerischen Limits können sich im Laufe der Zeit ändern. Lesen Sie sie immer aus den unten beschriebenen Antwort-Headern, nicht aus Dokumentations-Snapshots.

Antwort-Header (Antworten, die Rate-Limits unterliegen, einschließlich 429):

HeaderBedeutung
X-RateLimit-LimitLimit der derzeit strengsten aktiven Dimension
X-RateLimit-RemainingKleinstes verbleibendes Kontingent über die drei Dimensionen
X-RateLimit-ResetUnix-Zeitstempel (Sekunden), zu dem das aktuelle Fenster zurückgesetzt wird

Zusätzlich bei 429:

HeaderBedeutung
Retry-AfterEmpfohlene Wartezeit vor der Wiederholung (Sekunden)

Beispiel-Textkörper für 429 (die message spiegelt die zum Anfragezeitpunkt konfigurierten Limits wider):

{
  "status": 429,
  "code": "RATE_LIMITED",
  "message": "Too many requests. Limit: <N>/min per API key, <M>/min per user, <H>/hour per user.",
  "request_id": "..."
}

Client-Verhalten: Wenn vorhanden, lesen Sie X-RateLimit-Remaining und warten Sie proaktiv. Warten Sie bei 429 mindestens Retry-After Sekunden (oder bis X-RateLimit-Reset), bevor Sie es erneut versuchen. Kodieren Sie Limitwerte nicht fest.

Die vollständige Wiederholungsrichtlinie und Hinweise zum Backoff finden Sie unter Fehler, Limits und Wiederholungen. Wenn Sie höhere Rate-Limits benötigen, wenden Sie sich an [email protected].

Bewährte Methoden

1. Fehler sauber behandeln

Prüfen Sie immer den Antwortstatus und behandeln Sie Fehler angemessen:

if result['status'] == 'ok':
    # Process successful response
    answer = result['data']['answer']
else:
    # Handle error
    error_code = result['code']
    error_message = result['message']
    # Log error, show user-friendly message, etc.

2. Wiederholungslogik implementieren

Für vorübergehende Fehler (5xx-Statuscodes) implementieren Sie exponentielles Backoff:

import time

max_retries = 3
retry_delay = 1  # seconds

for attempt in range(max_retries):
    response = requests.post(url, headers=headers, json=data)

    if response.status_code < 500:
        break  # Success or client error, don't retry

    if attempt < max_retries - 1:
        time.sleep(retry_delay * (2 ** attempt))  # Exponential backoff

3. Antworten cachen

Erwägen Sie, Antworten für identische Abfragen zu cachen, um API-Aufrufe zu reduzieren und Antwortzeiten zu verbessern.

4. Eingaben validieren

Validieren Sie Benutzereingaben, bevor Sie sie an die API senden:

  • Stellen Sie sicher, dass die Abfrage nicht leer ist
  • Prüfen Sie die Länge der Abfrage (1–2000 Zeichen)
  • Bereinigen Sie Eingaben, um Injection-Angriffe zu verhindern

5. Nutzung überwachen

Verfolgen Sie Ihre API-Nutzung, um Rate-Limits einzuhalten und Kosten zu optimieren:

  • Protokollieren Sie Anfragezahlen und Antwortzeiten
  • Überwachen Sie Fehlerraten
  • Richten Sie Warnungen für ungewöhnliche Muster ein

Support

Benötigen Sie Hilfe zur Chat API?

Änderungsprotokoll

v2.0.0 (aktuell)

  • Erste Veröffentlichung der Chat API
  • Unterstützung für natürlichsprachliche Abfragen
  • Integration der Echtzeit-Websuche
  • KI-generierte Antworten mit Quellenangaben