Felo APIs
Chat API
Intégrez une recherche conversationnelle assistée par IA avec analyse des requêtes, ressources web et citations.
/v2/chatAuthentification
Bearer API key
Type de contenu
application/json
Notes sur les limites
Per API key and per user windows. Read X-RateLimit headers.
L'API Chat vous permet d'intégrer une recherche conversationnelle propulsée par l'IA dans vos applications. Envoyez une requête en langage naturel et recevez une réponse intelligente générée à partir de résultats de recherche web en temps réel.
Pour les limites de débit, les réponses d'erreur et le comportement de nouvelle tentative, consultez Erreurs, limites et nouvelles tentatives.
Aperçu
L'API Chat effectue les opérations suivantes :
- Elle analyse et optimise votre requête
- Elle recherche sur le web les informations pertinentes
- Elle classe et filtre les résultats de recherche
- Elle génère une réponse IA complète à partir des sources
- Elle renvoie la réponse accompagnée des citations des sources
Cas d'usage :
- Assistants IA conversationnels
- Outils de recherche et de récupération d'informations
- Chatbots d'assistance client enrichis par la connaissance du web
- Applications éducatives
- Outils de création de contenu
Authentification
Toutes les requêtes à l'API Chat nécessitent une authentification par clé API. Incluez votre clé API dans l'en-tête Authorization :
Authorization: Bearer YOUR_API_KEYConsultez le guide d'authentification pour les détails sur l'obtention et l'utilisation de votre clé API.
Utilisation avec des agents IA
Installez le paquet complet felo-ai lorsque vous voulez qu'un agent utilise Search et tous les autres Felo Skills disponibles. L'installateur découvre dynamiquement chaque répertoire de paquet contenant SKILL.md, il inclut donc les Skills futurs plutôt qu'un sous-ensemble figé. Installez-les dans le répertoire natif de votre agent : Codex utilise ~/.codex/skills, Claude Code utilise ~/.claude/skills, OpenClaw utilise ~/.agents/skills et Hermes Agent utilise ~/.hermes/skills. Consultez le guide d'installation manuelle des agents IA pour les étapes sûres de création de liens, de clé API et de vérification pour chaque plateforme.
Endpoint
POST https://openapi.felo.ai/v2/chatRequête
En-têtes
| En-tête | Requis | Description |
|---|---|---|
Authorization | Oui | Votre clé API au format : Bearer YOUR_API_KEY |
Content-Type | Oui | Doit être application/json |
Paramètres du corps
| Paramètre | Type | Requis | Description | Contraintes |
|---|---|---|---|---|
query | string | Oui | La question ou la requête de recherche de l'utilisateur | 1 à 2000 caractères |
Exemple de requête
{
"query": "What are the latest developments in quantum computing?"
}Réponse
Réponse de succès (200 OK)
Lorsque la requête aboutit, l'API renvoie une réponse JSON avec la structure suivante :
{
"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..."
}
]
}
}Champs de réponse
| Champ | Type | Description |
|---|---|---|
status | string | number | Statut de la réponse : "ok" en cas de succès ; les réponses d'erreur utilisent le code de statut HTTP sous forme de nombre |
message | string | null | Message supplémentaire (null pour les requêtes réussies) |
data | object | Données de réponse (présentes uniquement lorsque status vaut "ok") |
data.id | string | Identifiant unique de cette session de chat |
data.message_id | string | Identifiant unique de ce message spécifique |
data.answer | string | Réponse générée par l'IA à la requête |
data.query_analysis | object | Analyse de la requête de l'utilisateur |
data.query_analysis.queries | string[] | Requêtes de recherche optimisées dérivées de la saisie de l'utilisateur |
data.resources | array | Liste des sources web utilisées pour générer la réponse |
data.resources[].link | string | URL de la source |
data.resources[].title | string | Titre de la page source |
data.resources[].snippet | string | Extrait pertinent de la source |
Réponse d'erreur
Lorsqu'une erreur se produit, l'API renvoie l'enveloppe d'erreur commune :
{
"status": 401,
"code": "UNAUTHORIZED",
"message": "API Key is required",
"request_id": "..."
}Champs de réponse d'erreur
| Champ | Type | Description |
|---|---|---|
status | number | Code de statut HTTP ; les réponses de succès utilisent "ok" |
code | string | Code d'erreur identifiant le type d'erreur |
message | string | Description de l'erreur lisible par un humain |
request_id | string | Identifiant unique de cette requête (utile pour le support) |
Codes d'erreur
| HTTP | Code | Signification |
|---|---|---|
| 400 | Code de validation de l'endpoint | Un champ query est manquant, vide ou trop long ; lisez message pour le problème précis |
| 401 | UNAUTHORIZED | La clé API est manquante, invalide ou révoquée |
| 429 | RATE_LIMITED | Une limite de débit a été dépassée |
| 502 | CHAT_FAILED | Erreur interne du service |
| 503 | SERVICE_UNAVAILABLE | Service temporairement indisponible |
Pour l'enveloppe commune, les autres codes d'erreur et les règles de nouvelle tentative, consultez Erreurs, limites et nouvelles tentatives.
Exemples
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?"
}'Réponse :
{
"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 (navigateur / 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)
}
}Limitation de débit
Les utilisateurs disposant d'un abonnement Felo payant effectif (y compris les abonnements entreprise) sont exemptés de toutes les limites de débit de /v2/chat, pour l'authentification par clé API comme par OAuth. Les réponses exemptées n'incluent pas d'en-têtes X-RateLimit-*.
Les utilisateurs sans abonnement payant sont soumis à des limites de débit sur trois dimensions. Si le statut d'abonnement ne peut pas être vérifié, ces limites s'appliquent :
- Par clé API : limite les requêtes effectuées avec une même clé API dans une fenêtre de 1 minute.
- Par utilisateur (minute) : limite le total des requêtes de toutes les clés API appartenant à un utilisateur dans une fenêtre de 1 minute.
- Par utilisateur (heure) : limite le total des requêtes de toutes les clés API appartenant à un utilisateur dans une fenêtre de 1 heure.
Le dépassement de n'importe quelle dimension déclenche une réponse 429 Too Many Requests.
Les limites numériques exactes peuvent évoluer. Lisez-les toujours dans les en-têtes de réponse ci-dessous, et non dans des instantanés de documentation.
En-têtes de réponse (réponses soumises à limitation, y compris 429) :
| En-tête | Signification |
|---|---|
X-RateLimit-Limit | Limite de la dimension la plus restrictive actuellement en vigueur |
X-RateLimit-Remaining | Quota restant minimal sur les trois dimensions |
X-RateLimit-Reset | Horodatage Unix (secondes) de la réinitialisation de la fenêtre en cours |
Sur un 429, en plus :
| En-tête | Signification |
|---|---|
Retry-After | Délai de nouvelle tentative recommandé (secondes) |
Exemple de corps 429 (le message reflète les limites configurées au moment de la requête) :
{
"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": "..."
}Comportement du client : lorsqu'il est présent, lisez X-RateLimit-Remaining et réduisez proactivement la cadence. Sur un 429, attendez au moins Retry-After secondes (ou jusqu'à X-RateLimit-Reset) avant de réessayer. Ne codez pas les valeurs de limite en dur.
Pour la politique complète de nouvelle tentative et les conseils de backoff, consultez Erreurs, limites et nouvelles tentatives. Si vous avez besoin de limites de débit plus élevées, contactez [email protected].
Bonnes pratiques
1. Gérer les erreurs proprement
Vérifiez toujours le statut de la réponse et traitez les erreurs comme il se doit :
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. Implémenter une logique de nouvelle tentative
Pour les erreurs transitoires (codes de statut 5xx), implémentez un backoff exponentiel :
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. Mettre les réponses en cache
Envisagez de mettre en cache les réponses aux requêtes identiques pour réduire les appels API et améliorer les temps de réponse.
4. Valider les entrées
Validez la saisie de l'utilisateur avant de l'envoyer à l'API :
- Assurez-vous que la requête n'est pas vide
- Vérifiez la longueur de la requête (1 à 2000 caractères)
- Assainissez l'entrée pour prévenir les attaques par injection
5. Surveiller l'utilisation
Suivez votre utilisation de l'API pour rester dans les limites de débit et optimiser les coûts :
- Journalisez le nombre de requêtes et les temps de réponse
- Surveillez les taux d'erreur
- Configurez des alertes pour les schémas inhabituels
Support
Besoin d'aide avec l'API Chat ?
- Consultez le guide de démarrage
- Consultez la documentation d'authentification
- Contactez le support à [email protected] en indiquant votre request ID
Journal des modifications
v2.0.0 (actuelle)
- Version initiale de l'API Chat
- Prise en charge des requêtes en langage naturel
- Intégration de la recherche web en temps réel
- Réponses générées par l'IA avec citations des sources