Felo API PlatformFelo API Platform

Felo APIs

Chat API

Integrasikan carian perbualan dipacu AI dengan analisis pertanyaan, sumber web dan petikan.

POST/v2/chat

Pengesahan

Bearer API key

Jenis kandungan

application/json

Nota had kadar

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

Chat API membolehkan anda menyepadukan carian perbualan berkuasa AI ke dalam aplikasi anda. Hantar pertanyaan bahasa semula jadi dan terima jawapan pintar yang dijana daripada hasil carian web masa nyata.

Untuk had kadar, respons ralat, dan tingkah laku cuba semula, lihat Ralat, Had, dan Cuba Semula.

Gambaran Keseluruhan

Chat API melaksanakan operasi berikut:

  1. Menganalisis dan mengoptimumkan pertanyaan anda
  2. Mencari di web untuk maklumat berkaitan
  3. Menyusun dan menapis hasil carian
  4. Menjana jawapan AI yang menyeluruh berdasarkan sumber
  5. Mengembalikan jawapan bersama petikan sumber

Kes Penggunaan:

  • Pembantu AI perbualan
  • Alat penyelidikan dan pengambilan maklumat
  • Chatbot sokongan pelanggan dengan pengetahuan web
  • Aplikasi pendidikan
  • Alat penciptaan kandungan

Pengesahan

Semua permintaan kepada Chat API memerlukan pengesahan menggunakan Kunci API. Sertakan Kunci API anda dalam pengepala Authorization:

Authorization: Bearer YOUR_API_KEY

Lihat Panduan Pengesahan untuk butiran tentang mendapatkan dan menggunakan Kunci API anda.

Guna dengan Ejen AI

Pasang pakej lengkap felo-ai apabila anda mahu Ejen menggunakan Search dan setiap Felo Skill lain yang tersedia. Pemasang menemui secara dinamik setiap direktori pakej yang mengandungi SKILL.md, jadi ia merangkumi Skill masa hadapan dan bukannya subset tetap. Pasang dalam direktori asli untuk Ejen anda: Codex menggunakan ~/.codex/skills, Claude Code menggunakan ~/.claude/skills, OpenClaw menggunakan ~/.agents/skills, dan Hermes Agent menggunakan ~/.hermes/skills. Lihat panduan persediaan Ejen AI manual untuk langkah pautan selamat, kunci API, dan pengesahan bagi setiap platform.

Endpoint

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

Permintaan

Pengepala

PengepalaWajibPenerangan
AuthorizationYaKunci API anda dalam format: Bearer YOUR_API_KEY
Content-TypeYaMesti application/json

Parameter Badan

ParameterJenisWajibPeneranganKekangan
querystringYaSoalan atau pertanyaan carian pengguna1-2000 aksara

Contoh Permintaan

{
  "query": "What are the latest developments in quantum computing?"
}

Respons

Respons Berjaya (200 OK)

Apabila permintaan berjaya, API mengembalikan respons JSON dengan struktur berikut:

{
  "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..."
      }
    ]
  }
}

Medan Respons

MedanJenisPenerangan
statusstring | numberStatus respons: "ok" apabila berjaya; respons ralat menggunakan kod status HTTP sebagai nombor
messagestring | nullMesej tambahan (null untuk permintaan berjaya)
dataobjectData respons (hanya hadir apabila status ialah "ok")
data.idstringPengecam unik untuk sesi chat ini
data.message_idstringPengecam unik untuk mesej khusus ini
data.answerstringJawapan yang dijana AI untuk pertanyaan
data.query_analysisobjectAnalisis pertanyaan pengguna
data.query_analysis.queriesstring[]Pertanyaan carian dioptimumkan yang diperoleh daripada input pengguna
data.resourcesarraySenarai sumber web yang digunakan untuk menjana jawapan
data.resources[].linkstringURL sumber
data.resources[].titlestringTajuk halaman sumber
data.resources[].snippetstringPetikan berkaitan daripada sumber

Respons Ralat

Apabila ralat berlaku, API mengembalikan sampul ralat yang dikongsi:

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

Medan Respons Ralat

MedanJenisPenerangan
statusnumberKod status HTTP; respons berjaya menggunakan "ok"
codestringKod ralat yang mengenal pasti jenis ralat
messagestringPenerangan ralat yang boleh dibaca manusia
request_idstringPengecam unik untuk permintaan ini (berguna untuk sokongan)

Kod Ralat

HTTPKodMaksud
400Kod pengesahan endpointMedan query tiada, kosong, atau terlalu panjang; baca message untuk masalah khusus
401UNAUTHORIZEDKunci API tiada, tidak sah, atau telah dibatalkan
429RATE_LIMITEDHad kadar telah dilampaui
502CHAT_FAILEDRalat perkhidmatan dalaman
503SERVICE_UNAVAILABLEPerkhidmatan tidak tersedia sementara

Untuk sampul yang dikongsi, kod ralat lain, dan peraturan cuba semula, lihat Ralat, Had, dan Cuba Semula.

Contoh

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?"
  }'

Respons:

{
  "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 (Pelayar/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)
    }
}

Had Kadar

Pengguna dengan langganan Felo berbayar yang berkesan (termasuk langganan perusahaan) dikecualikan daripada semua had kadar /v2/chat, bagi pengesahan Kunci API dan OAuth. Respons yang dikecualikan tidak menyertakan pengepala X-RateLimit-*.

Pengguna tanpa langganan berbayar tertakluk kepada had kadar pada tiga dimensi. Jika status langganan tidak dapat disahkan, had ini masih terpakai:

  • Setiap Kunci API - mengehadkan permintaan yang dibuat dengan satu Kunci API dalam tetingkap 1 minit.
  • Setiap Pengguna (minit) - mengehadkan jumlah permintaan merentas semua Kunci API yang dimiliki oleh pengguna dalam tetingkap 1 minit.
  • Setiap Pengguna (jam) - mengehadkan jumlah permintaan merentas semua Kunci API yang dimiliki oleh pengguna dalam tetingkap 1 jam.

Mana-mana dimensi yang dilampaui mencetuskan respons 429 Too Many Requests.

Had berangka yang tepat mungkin berubah dari semasa ke semasa. Sentiasa baca daripada pengepala respons di bawah, bukan daripada petikan dokumentasi.

Pengepala respons (respons yang tertakluk kepada had kadar, termasuk 429):

PengepalaMaksud
X-RateLimit-LimitHad dimensi paling ketat yang sedang berkuat kuasa
X-RateLimit-RemainingKuota baki minimum merentas tiga dimensi
X-RateLimit-ResetCap masa Unix (saat) apabila tetingkap semasa ditetapkan semula

Pada 429, tambahan pula:

PengepalaMaksud
Retry-AfterKelewatan cuba semula yang disyorkan (saat)

Contoh badan 429 (message menggambarkan had yang dikonfigurasikan semasa pada masa permintaan):

{
  "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": "..."
}

Tingkah laku klien: apabila hadir, baca X-RateLimit-Remaining dan berundur secara proaktif. Pada 429, tunggu sekurang-kurangnya Retry-After saat (atau sehingga X-RateLimit-Reset) sebelum mencuba semula. Jangan kod keras nilai had.

Untuk dasar cuba semula penuh dan panduan pengunduran, lihat Ralat, Had, dan Cuba Semula. Jika anda memerlukan had kadar lebih tinggi, hubungi [email protected].

Amalan Terbaik

1. Kendalikan Ralat dengan Baik

Sentiasa semak status respons dan kendalikan ralat dengan sewajarnya:

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. Laksanakan Logik Cuba Semula

Untuk ralat sementara (kod status 5xx), laksanakan pengunduran eksponen:

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. Cache Respons

Pertimbangkan untuk menyimpan respons dalam cache bagi pertanyaan yang serupa untuk mengurangkan panggilan API dan meningkatkan masa respons.

4. Sahkan Input

Sahkan input pengguna sebelum menghantar kepada API:

  • Pastikan pertanyaan tidak kosong
  • Semak panjang pertanyaan (1-2000 aksara)
  • Sucikan input untuk mengelakkan serangan suntikan

5. Pantau Penggunaan

Jejaki penggunaan API anda untuk kekal dalam had kadar dan mengoptimumkan kos:

  • Log bilangan permintaan dan masa respons
  • Pantau kadar ralat
  • Sediakan makluman untuk corak luar biasa

Sokongan

Perlukan bantuan dengan Chat API?

Log Perubahan

v2.0.0 (Semasa)

  • Keluaran awal Chat API
  • Sokongan untuk pertanyaan bahasa semula jadi
  • Integrasi carian web masa nyata
  • Jawapan yang dijana AI dengan petikan sumber