Felo APIs
Chat API
Tích hợp tìm kiếm hội thoại dựa trên AI với phân tích truy vấn, nguồn web và trích dẫn.
/v2/chatXác thực
Bearer API key
Loại nội dung
application/json
Ghi chú về giới hạn
Per API key and per user windows. Read X-RateLimit headers.
Chat API cho phép bạn tích hợp tìm kiếm hội thoại do AI hỗ trợ vào ứng dụng của mình. Gửi một truy vấn bằng ngôn ngữ tự nhiên và nhận câu trả lời thông minh được tạo từ kết quả tìm kiếm web theo thời gian thực.
Về giới hạn tần suất, phản hồi lỗi và hành vi thử lại, xem Lỗi, giới hạn và thử lại.
Tổng quan
Chat API thực hiện các thao tác sau:
- Phân tích và tối ưu truy vấn của bạn
- Tìm kiếm thông tin liên quan trên web
- Xếp hạng và lọc kết quả tìm kiếm
- Tạo câu trả lời AI toàn diện dựa trên các nguồn
- Trả về câu trả lời cùng trích dẫn nguồn
Trường hợp sử dụng:
- Trợ lý AI hội thoại
- Công cụ nghiên cứu và truy xuất thông tin
- Chatbot hỗ trợ khách hàng có kiến thức web
- Ứng dụng giáo dục
- Công cụ tạo nội dung
Xác thực
Mọi yêu cầu đến Chat API đều yêu cầu xác thực bằng khóa API. Đưa khóa API của bạn vào header Authorization:
Authorization: Bearer YOUR_API_KEYXem Hướng dẫn xác thực để biết chi tiết về cách lấy và sử dụng khóa API.
Dùng với AI Agent
Cài gói felo-ai đầy đủ khi bạn muốn một Agent sử dụng Search và mọi Felo Skill khác hiện có. Trình cài đặt tự động khám phá mọi thư mục gói có chứa SKILL.md, nên nó bao gồm cả các Skill trong tương lai thay vì một tập con cố định. Hãy cài chúng vào thư mục gốc của Agent: Codex dùng ~/.codex/skills, Claude Code dùng ~/.claude/skills, OpenClaw dùng ~/.agents/skills và Hermes Agent dùng ~/.hermes/skills. Xem hướng dẫn thiết lập AI Agent thủ công để biết các bước tạo liên kết an toàn, khóa API và xác minh cho từng nền tảng.
Endpoint
POST https://openapi.felo.ai/v2/chatYêu cầu
Header
| Header | Bắt buộc | Mô tả |
|---|---|---|
Authorization | Có | Khóa API của bạn theo định dạng: Bearer YOUR_API_KEY |
Content-Type | Có | Phải là application/json |
Tham số nội dung yêu cầu
| Tham số | Kiểu | Bắt buộc | Mô tả | Ràng buộc |
|---|---|---|---|---|
query | string | Có | Câu hỏi hoặc truy vấn tìm kiếm của người dùng | 1-2000 ký tự |
Ví dụ yêu cầu
{
"query": "What are the latest developments in quantum computing?"
}Phản hồi
Phản hồi thành công (200 OK)
Khi yêu cầu thành công, API trả về phản hồi JSON với cấu trúc sau:
{
"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..."
}
]
}
}Các trường phản hồi
| Trường | Kiểu | Mô tả |
|---|---|---|
status | string | number | Trạng thái phản hồi: "ok" khi thành công; phản hồi lỗi dùng mã trạng thái HTTP dưới dạng số |
message | string | null | Thông điệp bổ sung (null cho các yêu cầu thành công) |
data | object | Dữ liệu phản hồi (chỉ có khi trạng thái là "ok") |
data.id | string | Định danh duy nhất cho phiên chat này |
data.message_id | string | Định danh duy nhất cho thông điệp cụ thể này |
data.answer | string | Câu trả lời do AI tạo cho truy vấn |
data.query_analysis | object | Phân tích truy vấn của người dùng |
data.query_analysis.queries | string[] | Các truy vấn tìm kiếm được tối ưu hóa từ đầu vào của người dùng |
data.resources | array | Danh sách nguồn web được dùng để tạo câu trả lời |
data.resources[].link | string | URL của nguồn |
data.resources[].title | string | Tiêu đề của trang nguồn |
data.resources[].snippet | string | Đoạn trích liên quan từ nguồn |
Phản hồi lỗi
Khi có lỗi, API trả về cấu trúc lỗi dùng chung:
{
"status": 401,
"code": "UNAUTHORIZED",
"message": "API Key is required",
"request_id": "..."
}Các trường phản hồi lỗi
| Trường | Kiểu | Mô tả |
|---|---|---|
status | number | Mã trạng thái HTTP; phản hồi thành công dùng "ok" |
code | string | Mã lỗi xác định loại lỗi |
message | string | Mô tả lỗi đọc được bằng người |
request_id | string | Định danh duy nhất cho yêu cầu này (hữu ích cho hỗ trợ) |
Mã lỗi
| HTTP | Mã | Ý nghĩa |
|---|---|---|
| 400 | Mã xác thực của endpoint | Trường query bị thiếu, trống hoặc quá dài; đọc message để biết vấn đề cụ thể |
| 401 | UNAUTHORIZED | Khóa API bị thiếu, không hợp lệ hoặc đã bị thu hồi |
| 429 | RATE_LIMITED | Đã vượt giới hạn tần suất |
| 502 | CHAT_FAILED | Lỗi dịch vụ nội bộ |
| 503 | SERVICE_UNAVAILABLE | Dịch vụ tạm thời không khả dụng |
Về cấu trúc lỗi dùng chung, các mã lỗi khác và quy tắc thử lại, xem Lỗi, giới hạn và thử lại.
Ví dụ
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?"
}'Phản hồi:
{
"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 (Trình duyệt/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)
}
}Giới hạn tần suất
Người dùng có gói đăng ký Felo trả phí đang hiệu lực (bao gồm gói doanh nghiệp) được miễn mọi giới hạn tần suất của /v2/chat, cho cả xác thực bằng khóa API lẫn OAuth. Các phản hồi được miễn không bao gồm header X-RateLimit-*.
Người dùng không có gói trả phí chịu giới hạn tần suất trên ba chiều. Nếu không thể xác minh trạng thái đăng ký, các giới hạn này vẫn được áp dụng:
- Theo khóa API - giới hạn các yêu cầu thực hiện bằng một khóa API trong cửa sổ 1 phút.
- Theo người dùng (phút) - giới hạn tổng số yêu cầu trên mọi khóa API do một người dùng sở hữu trong cửa sổ 1 phút.
- Theo người dùng (giờ) - giới hạn tổng số yêu cầu trên mọi khóa API do một người dùng sở hữu trong cửa sổ 1 giờ.
Bất kỳ chiều nào bị vượt sẽ kích hoạt phản hồi 429 Too Many Requests.
Các giới hạn số chính xác có thể thay đổi theo thời gian. Luôn đọc chúng từ các header phản hồi bên dưới, không đọc từ ảnh chụp tài liệu.
Header phản hồi (các phản hồi chịu giới hạn tần suất, bao gồm 429):
| Header | Ý nghĩa |
|---|---|
X-RateLimit-Limit | Giới hạn của chiều chặt nhất hiện đang có hiệu lực |
X-RateLimit-Remaining | Hạn mức còn lại nhỏ nhất trong ba chiều |
X-RateLimit-Reset | Dấu thời gian Unix (giây) khi cửa sổ hiện tại đặt lại |
Khi gặp 429, ngoài ra:
| Header | Ý nghĩa |
|---|---|
Retry-After | Độ trễ thử lại được khuyến nghị (giây) |
Ví dụ nội dung 429 (message phản ánh các giới hạn đang được cấu hình tại thời điểm yêu cầu):
{
"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": "..."
}Hành vi của máy khách: khi có, hãy đọc X-RateLimit-Remaining và chủ động giãn nhịp. Khi gặp 429, hãy chờ ít nhất Retry-After giây (hoặc đến X-RateLimit-Reset) trước khi thử lại. Không gán cứng các giá trị giới hạn.
Về chính sách thử lại đầy đủ và hướng dẫn giãn nhịp, xem Lỗi, giới hạn và thử lại. Nếu bạn cần giới hạn tần suất cao hơn, hãy liên hệ [email protected].
Thực tiễn tốt nhất
1. Xử lý lỗi một cách nhẹ nhàng
Luôn kiểm tra trạng thái phản hồi và xử lý lỗi phù hợp:
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. Triển khai logic thử lại
Với các lỗi tạm thời (mã trạng thái 5xx), hãy triển khai thời gian chờ tăng dần theo cấp số nhân:
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. Lưu cache phản hồi
Cân nhắc lưu cache phản hồi cho các truy vấn giống hệt để giảm số lệnh gọi API và cải thiện thời gian phản hồi.
4. Xác thực đầu vào
Xác thực đầu vào của người dùng trước khi gửi đến API:
- Đảm bảo truy vấn không trống
- Kiểm tra độ dài truy vấn (1-2000 ký tự)
- Làm sạch đầu vào để ngăn chặn tấn công injection
5. Giám sát mức sử dụng
Theo dõi mức sử dụng API của bạn để nằm trong giới hạn tần suất và tối ưu chi phí:
- Ghi lại số lượng yêu cầu và thời gian phản hồi
- Giám sát tỷ lệ lỗi
- Thiết lập cảnh báo cho các mẫu bất thường
Hỗ trợ
Cần trợ giúp với Chat API?
- Xem lại Hướng dẫn bắt đầu
- Xem Tài liệu xác thực
- Liên hệ hỗ trợ tại [email protected] kèm request ID của bạn
Nhật ký thay đổi
v2.0.0 (Hiện tại)
- Bản phát hành đầu tiên của Chat API
- Hỗ trợ truy vấn bằng ngôn ngữ tự nhiên
- Tích hợp tìm kiếm web theo thời gian thực
- Câu trả lời do AI tạo kèm trích dẫn nguồn