Felo API PlatformFelo API Platform

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.

POST/v2/chat

Xá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:

  1. Phân tích và tối ưu truy vấn của bạn
  2. Tìm kiếm thông tin liên quan trên web
  3. Xếp hạng và lọc kết quả tìm kiếm
  4. Tạo câu trả lời AI toàn diện dựa trên các nguồn
  5. 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_KEY

Xem 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/chat

Yêu cầu

HeaderBắt buộcMô tả
AuthorizationCóKhóa API của bạn theo định dạng: Bearer YOUR_API_KEY
Content-TypeCóPhải là application/json

Tham số nội dung yêu cầu

Tham sốKiểuBắt buộcMô tảRàng buộc
querystringCóCâu hỏi hoặc truy vấn tìm kiếm của người dùng1-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ườngKiểuMô tả
statusstring | numberTrạ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ố
messagestring | nullThông điệp bổ sung (null cho các yêu cầu thành công)
dataobjectDữ liệu phản hồi (chỉ có khi trạng thái là "ok")
data.idstringĐịnh danh duy nhất cho phiên chat này
data.message_idstringĐịnh danh duy nhất cho thông điệp cụ thể này
data.answerstringCâu trả lời do AI tạo cho truy vấn
data.query_analysisobjectPhân tích truy vấn của người dùng
data.query_analysis.queriesstring[]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.resourcesarrayDanh sách nguồn web được dùng để tạo câu trả lời
data.resources[].linkstringURL của nguồn
data.resources[].titlestringTiêu đề của trang nguồn
data.resources[].snippetstringĐ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ườngKiểuMô tả
statusnumberMã trạng thái HTTP; phản hồi thành công dùng "ok"
codestringMã lỗi xác định loại lỗi
messagestringMô tả lỗi đọc được bằng người
request_idstringĐịnh danh duy nhất cho yêu cầu này (hữu ích cho hỗ trợ)

Mã lỗi

HTTPMãÝ nghĩa
400Mã xác thực của endpointTrường query bị thiếu, trống hoặc quá dài; đọc message để biết vấn đề cụ thể
401UNAUTHORIZEDKhóa API bị thiếu, không hợp lệ hoặc đã bị thu hồi
429RATE_LIMITEDĐã vượt giới hạn tần suất
502CHAT_FAILEDLỗi dịch vụ nội bộ
503SERVICE_UNAVAILABLEDị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-LimitGiới hạn của chiều chặt nhất hiện đang có hiệu lực
X-RateLimit-RemainingHạn mức còn lại nhỏ nhất trong ba chiều
X-RateLimit-ResetDấ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 backoff

3. 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?

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