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 به شما امکان می‌دهد جستجوی گفت‌وگویی مبتنی بر هوش مصنوعی را در برنامه‌های خود ادغام کنید. یک پرسش به زبان طبیعی بفرستید و پاسخی هوشمند بر پایه نتایج جستجوی وب در زمان واقعی دریافت کنید.

برای محدودیت‌های نرخ، پاسخ‌های خطا و رفتار تلاش دوباره، خطاها، محدودیت‌ها و تلاش دوباره را ببینید.

مرور

Chat API عملیات زیر را انجام می‌دهد:

  1. پرسش شما را تحلیل و بهینه‌سازی می‌کند
  2. وب را برای اطلاعات مرتبط جستجو می‌کند
  3. نتایج جستجو را رتبه‌بندی و فیلتر می‌کند
  4. بر پایه منابع، پاسخی جامع با هوش مصنوعی تولید می‌کند
  5. پاسخ را همراه با استناد به منابع برمی‌گرداند

کاربردها:

  • دستیارهای گفت‌وگویی هوش مصنوعی
  • ابزارهای پژوهش و بازیابی اطلاعات
  • ربات‌های پشتیبانی مشتری با دانش وب
  • برنامه‌های آموزشی
  • ابزارهای تولید محتوا

احراز هویت

همه درخواست‌ها به Chat API با یک کلید API احراز هویت می‌شوند. کلید API خود را در سرآیند Authorization بگنجانید:

Authorization: Bearer YOUR_API_KEY

برای جزئیات دریافت و استفاده از کلید API راهنمای احراز هویت را ببینید.

استفاده با عامل‌های هوش مصنوعی

وقتی می‌خواهید یک عامل از Search و هر Felo Skill در دسترس دیگر استفاده کند، بسته کامل felo-ai را نصب کنید. نصب‌کننده به‌صورت پویا هر پوشه بسته شامل SKILL.md را کشف می‌کند، پس Skillهای آینده را هم در بر می‌گیرد، نه یک زیرمجموعه ثابت را. آن‌ها را در پوشه بومی عامل خود نصب کنید: 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 باشد

پارامترهای بدنه

پارامترنوعالزامیتوضیحمحدودیت‌ها
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پاسخ تولیدشده با هوش مصنوعی به پرسش
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 (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 را در پنجره 1 دقیقه‌ای محدود می‌کند.
  • برای هر کاربر (دقیقه) - درخواست‌های تجمعی همه کلید APIهای متعلق به یک کاربر را در پنجره 1 دقیقه‌ای محدود می‌کند.
  • برای هر کاربر (ساعت) - درخواست‌های تجمعی همه کلید APIهای متعلق به یک کاربر را در پنجره 1 ساعته محدود می‌کند.

عبور از هر بُعد پاسخ 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 backoff

3. پاسخ‌ها را کش کنید

برای پرسش‌های یکسان، کش کردن پاسخ‌ها را در نظر بگیرید تا فراخوانی‌های API کم شود و زمان پاسخ بهتر شود.

4. ورودی را اعتبارسنجی کنید

پیش از فرستادن به API، ورودی کاربر را اعتبارسنجی کنید:

  • مطمئن شوید پرسش خالی نیست
  • طول پرسش را بررسی کنید (1-2000 کاراکتر)
  • ورودی را پاک‌سازی کنید تا از حملات تزریق جلوگیری شود

5. مصرف را پایش کنید

مصرف API خود را پیگیری کنید تا در محدودیت‌های نرخ بمانید و هزینه‌ها را بهینه کنید:

  • شمار درخواست‌ها و زمان‌های پاسخ را ثبت کنید
  • نرخ خطا را پایش کنید
  • برای الگوهای غیرعادی هشدار تنظیم کنید

پشتیبانی

به کمک با Chat API نیاز دارید؟

تاریخچه تغییرات

v2.0.0 (جاری)

  • انتشار نخستین Chat API
  • پشتیبانی از پرسش‌های زبان طبیعی
  • یکپارچگی با جستجوی وب در زمان واقعی
  • پاسخ‌های تولیدشده با هوش مصنوعی همراه با استناد به منابع