Felo APIs
Chat API
Dodaj wyszukiwanie konwersacyjne AI z analizą zapytań, źródłami internetowymi i cytowaniami.
/v2/chatUwierzytelnianie
Bearer API key
Typ zawartości
application/json
Uwagi o limitach
Per API key and per user windows. Read X-RateLimit headers.
API Chat umożliwia integrację wyszukiwania konwersacyjnego opartego na AI z aplikacjami. Wyślij zapytanie w języku naturalnym i otrzymaj inteligentną odpowiedź wygenerowaną na podstawie wyników wyszukiwania w sieci w czasie rzeczywistym.
Informacje o limitach szybkości, odpowiedziach błędów i zachowaniu przy ponawianiu znajdziesz w Błędach, limitach i ponawianiu.
Przegląd
API Chat wykonuje następujące operacje:
- Analizuje i optymalizuje zapytanie
- Przeszukuje sieć w poszukiwaniu istotnych informacji
- Ranguje i filtruje wyniki wyszukiwania
- Generuje kompleksową odpowiedź AI na podstawie źródeł
- Zwraca odpowiedź wraz z cytowaniami źródeł
Zastosowania:
- konwersacyjne asystenty AI
- narzędzia do badań i wyszukiwania informacji
- chatboty wsparcia klienta z wiedzą z sieci
- aplikacje edukacyjne
- narzędzia do tworzenia treści
Uwierzytelnianie
Wszystkie żądania do API Chat wymagają uwierzytelnienia kluczem API. Dołącz klucz API do nagłówka Authorization:
Authorization: Bearer YOUR_API_KEYSzczegóły uzyskiwania i używania klucza API znajdziesz w przewodniku uwierzytelniania.
Użycie z agentami AI
Zainstaluj kompletny pakiet felo-ai, gdy chcesz, aby agent używał Search i każdego innego dostępnego Felo Skill. Instalator dynamicznie wykrywa każdy katalog pakietu zawierający SKILL.md, więc obejmuje przyszłe Skills, a nie stały podzbiór. Zainstaluj je w natywnym katalogu swojego agenta: Codex używa ~/.codex/skills, Claude Code używa ~/.claude/skills, OpenClaw używa ~/.agents/skills, a Hermes Agent używa ~/.hermes/skills. Bezpieczne dowiązania, klucz API i kroki weryfikacji dla każdej platformy znajdziesz w podręczniku konfiguracji agenta AI.
Endpoint
POST https://openapi.felo.ai/v2/chatŻądanie
Nagłówki
| Nagłówek | Wymagany | Opis |
|---|---|---|
Authorization | Tak | Twój klucz API w formacie: Bearer YOUR_API_KEY |
Content-Type | Tak | Musi mieć wartość application/json |
Parametry treści
| Parametr | Typ | Wymagany | Opis | Ograniczenia |
|---|---|---|---|---|
query | string | Tak | Pytanie użytkownika lub zapytanie wyszukiwania | od 1 do 2000 znaków |
Przykładowe żądanie
{
"query": "What are the latest developments in quantum computing?"
}Odpowiedź
Odpowiedź sukcesu (200 OK)
Gdy żądanie się powiedzie, API zwraca odpowiedź JSON o następującej strukturze:
{
"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..."
}
]
}
}Pola odpowiedzi
| Pole | Typ | Opis |
|---|---|---|
status | string | number | Stan odpowiedzi: "ok" przy powodzeniu; odpowiedzi błędów używają kodu statusu HTTP jako liczby |
message | string | null | Dodatkowy komunikat (null dla skutecznych żądań) |
data | object | Dane odpowiedzi (obecne tylko wtedy, gdy status to "ok") |
data.id | string | Unikalny identyfikator tej sesji czatu |
data.message_id | string | Unikalny identyfikator tej konkretnej wiadomości |
data.answer | string | Odpowiedź wygenerowana przez AI na zapytanie |
data.query_analysis | object | Analiza zapytania użytkownika |
data.query_analysis.queries | string[] | Zoptymalizowane zapytania wyszukiwania wyprowadzone z danych wejściowych użytkownika |
data.resources | array | Lista źródeł sieciowych użytych do wygenerowania odpowiedzi |
data.resources[].link | string | Adres URL źródła |
data.resources[].title | string | Tytuł strony źródłowej |
data.resources[].snippet | string | Istotny fragment ze źródła |
Odpowiedź błędu
Gdy wystąpi błąd, API zwraca wspólną kopertę błędów:
{
"status": 401,
"code": "UNAUTHORIZED",
"message": "API Key is required",
"request_id": "..."
}Pola odpowiedzi błędu
| Pole | Typ | Opis |
|---|---|---|
status | number | Kod statusu HTTP; odpowiedzi sukcesu używają "ok" |
code | string | Kod błędu identyfikujący typ błędu |
message | string | Czytelny dla człowieka opis błędu |
request_id | string | Unikalny identyfikator tego żądania (przydatny w pomocy technicznej) |
Kody błędów
| HTTP | Kod | Znaczenie |
|---|---|---|
| 400 | kod walidacji endpointu | Pole query jest brakujące, puste lub zbyt długie; przeczytaj message, aby poznać konkretny problem |
| 401 | UNAUTHORIZED | Klucz API jest brakujący, nieprawidłowy lub unieważniony |
| 429 | RATE_LIMITED | Przekroczono limit szybkości |
| 502 | CHAT_FAILED | Wewnętrzny błąd usługi |
| 503 | SERVICE_UNAVAILABLE | Usługa tymczasowo niedostępna |
Informacje o wspólnej kopercie, innych kodach błędów i zasadach ponawiania znajdziesz w Błędach, limitach i ponawianiu.
Przykłady
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?"
}'Odpowiedź:
{
"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 (przeglądarka/API Fetch)
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)
}
}Limity szybkości
Użytkownicy z aktywną płatną subskrypcją Felo (w tym subskrypcją enterprise) są zwolnieni ze wszystkich limitów szybkości /v2/chat, zarówno przy uwierzytelnianiu kluczem API, jak i OAuth. Zwolnione odpowiedzi nie zawierają nagłówków X-RateLimit-*.
Użytkownicy bez płatnej subskrypcji podlegają limitom szybkości w trzech wymiarach. Jeśli nie można zweryfikować statusu subskrypcji, limity nadal obowiązują:
- Na klucz API — ogranicza żądania wykonywane jednym kluczem API w oknie 1 minuty.
- Na użytkownika (minuta) — ogranicza łączne żądania ze wszystkich kluczy API należących do użytkownika w oknie 1 minuty.
- Na użytkownika (godzina) — ogranicza łączne żądania ze wszystkich kluczy API należących do użytkownika w oknie 1 godziny.
Przekroczenie któregokolwiek wymiaru wywołuje odpowiedź 429 Too Many Requests.
Dokładne wartości liczbowe limitów mogą się zmieniać w czasie. Zawsze odczytuj je z nagłówków odpowiedzi poniżej, a nie z migawek dokumentacji.
Nagłówki odpowiedzi (odpowiedzi podlegające limitom szybkości, w tym 429):
| Nagłówek | Znaczenie |
|---|---|
X-RateLimit-Limit | Limit najciaśniejszego aktualnie obowiązującego wymiaru |
X-RateLimit-Remaining | Minimalny pozostały limit spośród trzech wymiarów |
X-RateLimit-Reset | Znacznik czasu Unix (w sekundach), kiedy resetuje się bieżące okno |
Przy 429 dodatkowo:
| Nagłówek | Znaczenie |
|---|---|
Retry-After | Zalecane opóźnienie ponowienia (w sekundach) |
Przykładowa treść 429 (message odzwierciedla aktualnie skonfigurowane limity w chwili żądania):
{
"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": "..."
}Zachowanie klienta: gdy są obecne, odczytuj X-RateLimit-Remaining i wycofuj się proaktywnie. Przy 429 odczekaj co najmniej Retry-After sekund (lub do X-RateLimit-Reset) przed ponowieniem. Nie wpisuj wartości limitów na stałe w kodzie.
Pełne zasady ponawiania i wskazówki dotyczące wycofywania znajdziesz w Błędach, limitach i ponawianiu. Jeśli potrzebujesz wyższych limitów szybkości, skontaktuj się pod adresem [email protected].
Najlepsze praktyki
1. Łagodna obsługa błędów
Zawsze sprawdzaj status odpowiedzi i odpowiednio obsługuj błędy:
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. Wdrożenie logiki ponawiania
Dla błędów przejściowych (kody statusu 5xx) wdróż wykładnicze opóźnienie:
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 backoff3. Buforowanie odpowiedzi
Rozważ buforowanie odpowiedzi dla identycznych zapytań, aby zmniejszyć liczbę wywołań API i skrócić czas odpowiedzi.
4. Walidacja danych wejściowych
Waliduj dane wejściowe użytkownika przed wysłaniem ich do API:
- upewnij się, że zapytanie nie jest puste
- sprawdź długość zapytania (od 1 do 2000 znaków)
- oczyść dane wejściowe, aby zapobiec atakom iniekcji
5. Monitorowanie zużycia
Śledź zużycie API, aby mieścić się w limitach szybkości i optymalizować koszty:
- zapisuj w logach liczby żądań i czasy odpowiedzi
- monitoruj wskaźniki błędów
- skonfiguruj alerty dla nietypowych wzorców
Pomoc
Potrzebujesz pomocy z API Chat?
- Przejrzyj przewodnik pierwsze kroki
- Sprawdź dokumentację uwierzytelniania
- Skontaktuj się z pomocą pod adresem [email protected], podając identyfikator żądania
Historia zmian
v2.0.0 (bieżąca)
- pierwsze wydanie API Chat
- obsługa zapytań w języku naturalnym
- integracja wyszukiwania w sieci w czasie rzeczywistym
- odpowiedzi generowane przez AI z cytowaniami źródeł