Felo APIs
Chat API
ادمج بحثًا حواريًا مدعومًا بالذكاء الاصطناعي مع تحليل الاستعلامات ومصادر الويب والاستشهادات.
/v2/chatالمصادقة
Bearer API key
نوع المحتوى
application/json
ملاحظات السعر
Per API key and per user windows. Read X-RateLimit headers.
يتيح لك Chat API دمج بحث محادثاتي مدعوم بالذكاء الاصطناعي في تطبيقاتك. أرسل استعلامًا بلغة طبيعية واحصل على إجابة ذكية مولّدة من نتائج بحث ويب فورية.
لحدود المعدل واستجابات الأخطاء وسلوك إعادة المحاولة، راجع الأخطاء والحدود وإعادة المحاولة.
نظرة عامة
ينفّذ Chat API العمليات التالية:
- تحليل استعلامك وتحسينه
- البحث على الويب عن معلومات ذات صلة
- ترتيب نتائج البحث وتصفيتها
- توليد إجابة شاملة بالذكاء الاصطناعي بناءً على المصادر
- إعادة الإجابة مع استشهادات المصادر
حالات الاستخدام:
- مساعدو المحادثة بالذكاء الاصطناعي
- أدوات البحث واسترجاع المعلومات
- روبوتات دعم العملاء المزوّدة بمعرفة الويب
- التطبيقات التعليمية
- أدوات إنشاء المحتوى
المصادقة
تتطلب كل الطلبات إلى Chat API مصادقة باستخدام مفتاح API. أدرج مفتاح API في رأس Authorization:
Authorization: Bearer YOUR_API_KEYراجع دليل المصادقة لتفاصيل الحصول على مفتاح API واستخدامه.
الاستخدام مع وكلاء الذكاء الاصطناعي
ثبّت حزمة felo-ai الكاملة عندما تريد أن يستخدم وكيل البحث وكل مهارة Felo Skill أخرى متاحة. يكتشف المثبّت ديناميكيًا كل دليل حزمة يحتوي SKILL.md، لذا يشمل المهارات المستقبلية بدلًا من مجموعة ثابتة. ثبّتها في الدليل الأصلي لوكيلك: يستخدم Codex المسار ~/.codex/skills، ويستخدم Claude Code المسار ~/.claude/skills، ويستخدم OpenClaw المسار ~/.agents/skills، ويستخدم Hermes Agent المسار ~/.hermes/skills. راجع دليل إعداد وكيل الذكاء الاصطناعي اليدوي لخطوات الربط الآمن ومفتاح API والتحقق لكل منصة.
Endpoint
POST https://openapi.felo.ai/v2/chatالطلب
الرؤوس
| الرأس | مطلوب | الوصف |
|---|---|---|
Authorization | نعم | مفتاح API الخاص بك بالصيغة: Bearer YOUR_API_KEY |
Content-Type | نعم | يجب أن يكون application/json |
معاملات النص
| المعامل | النوع | مطلوب | الوصف | القيود |
|---|---|---|---|---|
query | string | نعم | سؤال المستخدم أو استعلام البحث | من 1 إلى 2000 حرف |
مثال على الطلب
{
"query": "What are the latest developments in quantum computing?"
}الاستجابة
استجابة النجاح (200 OK)
عند نجاح الطلب، يعيد API استجابة JSON بالبنية التالية:
{
"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..."
}
]
}
}حقول الاستجابة
| الحقل | النوع | الوصف |
|---|---|---|
status | string | number | حالة الاستجابة: "ok" عند النجاح؛ وتستخدم استجابات الأخطاء رمز حالة HTTP كرقم |
message | string | null | رسالة إضافية (null للطلبات الناجحة) |
data | object | بيانات الاستجابة (تظهر فقط عندما تكون الحالة "ok") |
data.id | string | معرّف فريد لجلسة المحادثة هذه |
data.message_id | string | معرّف فريد لهذه الرسالة تحديدًا |
data.answer | string | إجابة مولّدة بالذكاء الاصطناعي على الاستعلام |
data.query_analysis | object | تحليل استعلام المستخدم |
data.query_analysis.queries | string[] | استعلامات بحث محسّنة مشتقة من مدخلات المستخدم |
data.resources | array | قائمة مصادر الويب المستخدمة لتوليد الإجابة |
data.resources[].link | string | عنوان URL للمصدر |
data.resources[].title | string | عنوان صفحة المصدر |
data.resources[].snippet | string | مقتطف ذو صلة من المصدر |
استجابة الخطأ
عند حدوث خطأ، يعيد API غلاف الخطأ المشترك:
{
"status": 401,
"code": "UNAUTHORIZED",
"message": "API Key is required",
"request_id": "..."
}حقول استجابة الخطأ
| الحقل | النوع | الوصف |
|---|---|---|
status | number | رمز حالة HTTP؛ وتستخدم استجابات النجاح "ok" |
code | string | رمز الخطأ الذي يحدد نوعه |
message | string | وصف الخطأ بصيغة مفهومة للبشر |
request_id | string | معرّف فريد لهذا الطلب (مفيد للدعم) |
Error Codes (رموز الأخطاء)
| HTTP | الرمز | المعنى |
|---|---|---|
| 400 | رمز تحقق من endpoint | حقل query مفقود أو فارغ أو طويل جدًا؛ اقرأ message للمشكلة المحددة |
| 401 | UNAUTHORIZED | مفتاح API مفقود أو غير صالح أو مُبطَل |
| 429 | RATE_LIMITED | تجاوزت حد معدل |
| 502 | CHAT_FAILED | خطأ داخلي في الخدمة |
| 503 | SERVICE_UNAVAILABLE | الخدمة غير متاحة مؤقتًا |
للغلاف المشترك ورموز الأخطاء الأخرى وقواعد إعادة المحاولة، راجع الأخطاء والحدود وإعادة المحاولة.
الأمثلة
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?"
}'Response:
{
"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 Limiting (حدود المعدل)
يُعفى المستخدمون ذوو اشتراك Felo مدفوع فعّال (بما في ذلك اشتراكات المؤسسات) من كل حدود معدل /v2/chat، سواء لمصادقة مفتاح API أو OAuth. ولا تتضمن الاستجابات المعفاة رؤوس X-RateLimit-*.
يخضع المستخدمون دون اشتراك مدفوع لحدود معدل على ثلاثة أبعاد. وإذا تعذّر التحقق من حالة الاشتراك، تظل هذه الحدود مطبقة:
- لكل مفتاح API - يحدّ من الطلبات المجراة بمفتاح API واحد خلال نافذة دقيقة واحدة.
- لكل مستخدم (دقيقة) - يحدّ من إجمالي الطلبات عبر كل مفاتيح API التي يملكها مستخدم خلال نافذة دقيقة واحدة.
- لكل مستخدم (ساعة) - يحدّ من إجمالي الطلبات عبر كل مفاتيح API التي يملكها مستخدم خلال نافذة ساعة واحدة.
تجاوز أي بُعد يؤدي إلى استجابة 429 Too Many Requests.
قد تتغيّر الحدود الرقمية الدقيقة مع الوقت. اقرأها دائمًا من رؤوس الاستجابة أدناه، لا من لقطات التوثيق.
رؤوس الاستجابة (الاستجابات الخاضعة لحد المعدل، بما في ذلك 429):
| الرأس | المعنى |
|---|---|
X-RateLimit-Limit | حد أضيق بُعد مطبّق حاليًا |
X-RateLimit-Remaining | أدنى حصة متبقية عبر الأبعاد الثلاثة |
X-RateLimit-Reset | طابع زمني Unix (بالثواني) لإعادة تعيين النافذة الحالية |
عند 429، إضافةً إلى ذلك:
| الرأس | المعنى |
|---|---|
Retry-After | تأخير إعادة المحاولة الموصى به (بالثواني) |
مثال نص 429 (يعكس message الحدود المضبوطة حاليًا وقت الطلب):
{
"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": "..."
}سلوك العميل: عندما يكون موجودًا، اقرأ X-RateLimit-Remaining وتراجع استباقيًا. وعند 429، انتظر Retry-After ثانية على الأقل (أو حتى X-RateLimit-Reset) قبل إعادة المحاولة. لا تثبّت قيم الحدود في شيفرتك.
لسياسة إعادة المحاولة الكاملة وإرشادات التراجع، راجع الأخطاء والحدود وإعادة المحاولة. إذا كنت تحتاج إلى حدود معدل أعلى، فتواصل مع [email protected].
أفضل الممارسات
1. التعامل مع الأخطاء بلطف
تحقق دائمًا من حالة الاستجابة وتعامل مع الأخطاء بشكل مناسب:
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. تطبيق منطق إعادة المحاولة
للأخطاء العابرة (رموز حالة 5xx)، طبّق تراجعًا أسّيًا:
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. تخزين الاستجابات مؤقتًا
فكّر في تخزين الاستجابات مؤقتًا للاستعلامات المتطابقة لتقليل استدعاءات API وتحسين أزمنة الاستجابة.
4. التحقق من المدخلات
تحقق من مدخلات المستخدم قبل إرسالها إلى API:
- تأكد من أن الاستعلام غير فارغ
- تحقق من طول الاستعلام (من 1 إلى 2000 حرف)
- نظّف المدخلات لمنع هجمات الحقن
5. مراقبة الاستخدام
تتبّع استخدامك لـAPI للبقاء ضمن حدود المعدل وتحسين التكاليف:
- سجّل عدد الطلبات وأزمنة الاستجابة
- راقب معدلات الأخطاء
- أعدّ تنبيهات للأنماط غير المعتادة
الدعم
هل تحتاج إلى مساعدة في Chat API؟
- راجع دليل البدء
- اطّلع على توثيق المصادقة
- تواصل مع الدعم على [email protected] مع معرّف طلبك
سجل التغييرات
v2.0.0 (الحالية)
- الإصدار الأول من Chat API
- دعم الاستعلامات باللغة الطبيعية
- تكامل البحث الفوري على الويب
- إجابات مولّدة بالذكاء الاصطناعي مع استشهادات المصادر