Felo API PlatformFelo API Platform

Felo APIs

Chat API

เชื่อมต่อการค้นหาแบบสนทนาที่ขับเคลื่อนด้วย AI พร้อมการวิเคราะห์คำค้น แหล่งข้อมูลเว็บ และการอ้างอิง

POST/v2/chat

การยืนยันตัวตน

Bearer API key

ประเภทเนื้อหา

application/json

หมายเหตุเรื่องข้อจำกัด

Per API key and per user windows. Read X-RateLimit headers.

Chat API ช่วยให้คุณผสานการค้นหาแบบสนทนาที่ขับเคลื่อนด้วย AI เข้ากับแอปพลิเคชันของคุณ ส่งคำถามด้วยภาษาธรรมชาติแล้วรับคำตอบอัจฉริยะที่สร้างจากผลการค้นหาเว็บแบบเรียลไทม์

สำหรับขีดจำกัดอัตรา การตอบกลับข้อผิดพลาด และพฤติกรรมการลองใหม่ โปรดดู ข้อผิดพลาด ขีดจำกัด และการลองใหม่

ภาพรวม

Chat API ดำเนินการต่อไปนี้:

  1. วิเคราะห์และปรับแต่งคำถามของคุณ
  2. ค้นหาเว็บเพื่อหาข้อมูลที่เกี่ยวข้อง
  3. จัดอันดับและกรองผลการค้นหา
  4. สร้างคำตอบที่ครอบคลุมด้วย AI จากแหล่งที่มา
  5. ส่งคำตอบพร้อมการอ้างอิงแหล่งที่มา

กรณีการใช้งาน:

  • ผู้ช่วย AI แบบสนทนา
  • เครื่องมือค้นคว้าและค้นคืนข้อมูล
  • แชตบอตสนับสนุนลูกค้าที่มีความรู้จากเว็บ
  • แอปพลิเคชันเพื่อการศึกษา
  • เครื่องมือสร้างเนื้อหา

การรับรองความถูกต้อง

คำขอทั้งหมดไปยัง Chat API ต้องรับรองความถูกต้องด้วยคีย์ API ให้ใส่คีย์ API ใน header Authorization:

Authorization: Bearer YOUR_API_KEY

ดูคู่มือการรับรองความถูกต้องสำหรับรายละเอียดการรับและใช้คีย์ API

ใช้กับ AI Agent

ติดตั้งแพ็กเกจ felo-ai ที่ครบถ้วนเมื่อคุณต้องการให้ Agent ใช้ Search และ Felo Skill อื่น ๆ ที่มีให้ใช้ทั้งหมด ตัวติดตั้งจะค้นหาไดเรกทอรีแพ็กเกจทุกไดเรกทอรีที่มี SKILL.md แบบไดนามิก จึงรวม Skill ในอนาคตด้วย ไม่ใช่ชุดย่อยแบบตายตัว ให้ติดตั้งในไดเรกทอรีดั้งเดิมสำหรับ Agent ของคุณ: Codex ใช้ ~/.codex/skills, Claude Code ใช้ ~/.claude/skills, OpenClaw ใช้ ~/.agents/skills และ Hermes Agent ใช้ ~/.hermes/skills ดูคู่มือการตั้งค่า AI Agent ด้วยตนเองสำหรับลิงก์ที่ปลอดภัย คีย์ API และขั้นตอนการตรวจสอบของแต่ละแพลตฟอร์ม

Endpoint

POST https://openapi.felo.ai/v2/chat

คำขอ

Headerจำเป็นคำอธิบาย
Authorizationใช่คีย์ API ของคุณในรูปแบบ: Bearer YOUR_API_KEY
Content-Typeใช่ต้องเป็น application/json

พารามิเตอร์ในเนื้อหาคำขอ

พารามิเตอร์ชนิดจำเป็นคำอธิบายข้อจำกัด
querystringใช่คำถามหรือคำค้นของผู้ใช้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..."
      }
    ]
  }
}

ฟิลด์ของการตอบกลับ

ฟิลด์ชนิดคำอธิบาย
statusstring | numberสถานะการตอบกลับ: "ok" เมื่อสำเร็จ การตอบกลับข้อผิดพลาดใช้รหัสสถานะ HTTP เป็นตัวเลข
messagestring | nullข้อความเพิ่มเติม (null สำหรับคำขอที่สำเร็จ)
dataobjectข้อมูลการตอบกลับ (มีเฉพาะเมื่อ status เป็น "ok")
data.idstringตัวระบุเฉพาะของเซสชันแชตนี้
data.message_idstringตัวระบุเฉพาะของข้อความนี้
data.answerstringคำตอบที่สร้างโดย AI สำหรับคำถาม
data.query_analysisobjectการวิเคราะห์คำถามของผู้ใช้
data.query_analysis.queriesstring[]คำค้นที่ปรับแต่งแล้วซึ่งได้จากอินพุตของผู้ใช้
data.resourcesarrayรายการแหล่งข้อมูลเว็บที่ใช้สร้างคำตอบ
data.resources[].linkstringURL ของแหล่งที่มา
data.resources[].titlestringชื่อของหน้าแหล่งที่มา
data.resources[].snippetstringข้อความที่ตัดตอนมาและเกี่ยวข้องจากแหล่งที่มา

การตอบกลับข้อผิดพลาด

เมื่อเกิดข้อผิดพลาด API จะส่งซองข้อผิดพลาดที่ใช้ร่วมกัน:

{
  "status": 401,
  "code": "UNAUTHORIZED",
  "message": "API Key is required",
  "request_id": "..."
}

ฟิลด์ของการตอบกลับข้อผิดพลาด

ฟิลด์ชนิดคำอธิบาย
statusnumberรหัสสถานะ HTTP การตอบกลับที่สำเร็จใช้ "ok"
codestringรหัสข้อผิดพลาดที่ระบุประเภทของข้อผิดพลาด
messagestringคำอธิบายข้อผิดพลาดที่มนุษย์อ่านได้
request_idstringตัวระบุเฉพาะของคำขอนี้ (มีประโยชน์สำหรับการสนับสนุน)

รหัสข้อผิดพลาด (Error Codes)

HTTPรหัสความหมาย
400รหัสการตรวจสอบเฉพาะ endpointฟิลด์ query หายไป ว่าง หรือยาวเกินไป ให้อ่าน message สำหรับปัญหาเฉพาะ
401UNAUTHORIZEDคีย์ API หายไป ไม่ถูกต้อง หรือถูกเพิกถอน
429RATE_LIMITEDเกินขีดจำกัดอัตรา
502CHAT_FAILEDข้อผิดพลาดภายในบริการ
503SERVICE_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?"
  }'

การตอบกลับ:

{
  "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 (เบราว์เซอร์/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 การตอบกลับที่ได้รับการยกเว้นจะไม่มี header X-RateLimit-*

ผู้ใช้ที่ไม่มีการสมัครสมาชิกแบบชำระเงินจะขึ้นอยู่กับขีดจำกัดอัตราในสามมิติ หากไม่สามารถตรวจสอบสถานะการสมัครสมาชิกได้ ขีดจำกัดเหล่านี้ยังคงมีผล:

  • ต่อคีย์ API - จำกัดคำขอที่ทำด้วยคีย์ API เดียวภายในหน้าต่าง 1 นาที
  • ต่อผู้ใช้ (นาที) - จำกัดคำขอรวมจากทุกคีย์ API ที่ผู้ใช้เป็นเจ้าของภายในหน้าต่าง 1 นาที
  • ต่อผู้ใช้ (ชั่วโมง) - จำกัดคำขอรวมจากทุกคีย์ API ที่ผู้ใช้เป็นเจ้าของภายในหน้าต่าง 1 ชั่วโมง

การเกินมิติใดมิตินึงจะทำให้เกิดการตอบกลับ 429 Too Many Requests

ขีดจำกัดเชิงตัวเลขที่แน่นอนอาจเปลี่ยนแปลงได้ตามเวลา ควรอ่านจาก header ของการตอบกลับด้านล่างเสมอ ไม่ใช่จากสแนปช็อตของเอกสาร

Header ของการตอบกลับ (การตอบกลับที่อยู่ภายใต้ขีดจำกัดอัตรา รวมถึง 429):

Headerความหมาย
X-RateLimit-Limitขีดจำกัดของมิติที่เข้มงวดที่สุดที่บังคับใช้อยู่ในปัจจุบัน
X-RateLimit-Remainingโควตาที่เหลือน้อยที่สุดในสามมิติ
X-RateLimit-Resetเวลาประทับ Unix (วินาที) เมื่อหน้าต่างปัจจุบันรีเซ็ต

เมื่อได้รับ 429 เพิ่มเติม:

Headerความหมาย
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": "..."
}

พฤติกรรมของไคลเอนต์: เมื่อมี header ให้อ่าน 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 backoff

3. แคชการตอบกลับ

พิจารณาแคชการตอบกลับสำหรับคำถามที่เหมือนกันเพื่อลดการเรียก API และปรับปรุงเวลาการตอบสนอง

4. ตรวจสอบอินพุต

ตรวจสอบอินพุตของผู้ใช้ก่อนส่งไปยัง API:

  • ตรวจสอบว่าคำถามไม่ว่างเปล่า
  • ตรวจสอบความยาวของคำถาม (1-2000 ตัวอักษร)
  • ทำความสะอาดอินพุตเพื่อป้องกันการโจมตีแบบ injection

5. ติดตามการใช้งาน

ติดตามการใช้งาน API ของคุณเพื่อให้อยู่ในขีดจำกัดอัตราและเพิ่มประสิทธิภาพต้นทุน:

  • บันทึกจำนวนคำขอและเวลาการตอบสนอง
  • ติดตามอัตราข้อผิดพลาด
  • ตั้งการแจ้งเตือนสำหรับรูปแบบที่ผิดปกติ

การสนับสนุน

ต้องการความช่วยเหลือเกี่ยวกับ Chat API หรือไม่

บันทึกการเปลี่ยนแปลง

v2.0.0 (ปัจจุบัน)

  • การเปิดตัว Chat API ครั้งแรก
  • รองรับคำถามด้วยภาษาธรรมชาติ
  • ผสานการค้นหาเว็บแบบเรียลไทม์
  • คำตอบที่สร้างโดย AI พร้อมการอ้างอิงแหล่งที่มา