API مرجع
مرجع کامل برای هر نقطه پایانی، شکل درخواست و پاسخ، کد خطا و محدودیت نرخ.
محدودیتها و رفتار
| مورد | مقدار |
|---|---|
| اندازه بدنه JSON | تا 2 مگابایت (express.json({ limit: '2mb' })) |
| اهداف در هر درخواست | 1–50 کد زبان |
| آیتمهای دستهای | 1–100 آیتم در هر درخواست دستهای |
| مدلها | standard (پیشفرض) یا advanced (فقط در سطوح پولی؛ در ادامه ببینید) |
محدودیت ماهانه توکن (سطح رایگان): قبل از فراخوانی مدل، API توکنها را تقریباً به صورت ceil(content_length / 4) × (number_of_targets + 1) تخمین میزند و فقط برای سطح free، اگر تخمین از سهمیه ماهانه باقیمانده بیشتر باشد، درخواست را با 429 / token_limit_reached رد میکند (پیشفرض 100000). سطوح پولی توسط این پیشبررسی مسدود نمیشوند؛ استفاده همچنان ثبت میشود.
محدودیتهای نرخ: وقتی Redis پیکربندی شده باشد، محدودیتهای دقیقهای بر اساس سطح اعمال میشود: رایگان 5، شروعکننده 30، رشد 60، مقیاس 120، سازمانی نامحدود. در صورت رسیدن به حد، پاسخ 429 با error: "rate_limit_reached" است. اگر Redis پیکربندی نشده باشد، محدودیت نرخ نادیده گرفته میشود.
پاسخهای موفق با محدودیت نرخ ممکن است شامل X-RateLimit-Limit، X-RateLimit-Remaining، X-RateLimit-Reset باشند.
GET /health
بدون احراز هویت.
پاسخ 200
{
"status": "ok",
"timestamp": "2025-03-23T12:00:00.000Z"
}
GET /languages
بدون احراز هویت.
فهرست رسمی زبانهای پشتیبانیشده را برمیگرداند (کد، نام نمایشی، پرچم RTL). 43 ورودی وجود دارد — 36 زبان پایه و 7 گونه منطقهای. گونههای منطقهای از زیرکدهای منطقهای BCP-47 استفاده میکنند (مثلاً fr-CA، pt-BR، es-MX). کدهای این نقطه پایانی تنها مقادیری هستند که در targets در نقاط پایانی ترجمه پذیرفته میشوند.
پاسخ 200
{
"languages": [
{ "code": "en", "name": "English", "rtl": false },
{ "code": "ar", "name": "Arabic", "rtl": true }
]
}
فهرست زنده نیز از طریق GET /languages در دسترس است — در ادامه ببینید.
POST /translate
نیازمند Authorization: Bearer <api_key>.
یک رشته content را به هر زبان موجود در targets ترجمه میکند. پاسخ یک شیء JSON واحد است که کلیدهای آن دقیقاً کدهای زبان درخواستشده و مقادیر آن رشتههای ترجمهشده هستند.
بدنه درخواست
| فیلد | نوع | اجباری | توضیح |
|---|---|---|---|
content | string | بله | رشته غیرخالی برای ترجمه. |
targets | string[] | بله | آرایه غیرخالی از کدهای زبان معتبر (حداکثر 36). |
format | string | خیر | یکی از plain، markdown، json، html. اگر حذف شود، فرمت به صورت خودکار از content تشخیص داده میشود. |
source | string | خیر | نشانه زبان منبع برای مدل؛ اختیاری. |
model | string | خیر | standard (پیشفرض) یا advanced. advanced نیازمند سطح پولی است (403 در رایگان). |
پاسخ 200
{
"translations": {
"es": "...",
"fr": "..."
},
"usage": {
"input_tokens": 120,
"output_tokens": 340,
"total_tokens": 460,
"model": "standard",
"detected_format": "markdown",
"detection_confidence": 0.95
}
}
detected_format و detection_confidence فقط زمانی ظاهر میشوند که format حذف شده و تشخیص خودکار اجرا شده باشد.
مثال (cURL)
curl -sS -X POST "https://api.usepolylingo.com/v1/translate" \
-H "Authorization: Bearer $POLYLINGO_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"content": "{\"title\":\"Hello\"}",
"format": "json",
"targets": ["fr", "de"]
}'
مثال (Python 3)
pip install requests
import os, requests
url = "https://api.usepolylingo.com/v1/translate"
headers = {
"Authorization": f"Bearer {os.environ['POLYLINGO_API_KEY']}",
"Content-Type": "application/json",
}
r = requests.post(url, json={
"content": "<p>Hello <strong>world</strong></p>",
"format": "html",
"targets": ["es"],
}, timeout=120)
r.raise_for_status()
print(r.json()["translations"]["es"])
POST /translate/batch
نیازمند Authorization: Bearer <api_key>.
هر آیتم را به ترتیب پردازش میکند (یک فراخوانی مدل برای هر آیتم). اگر هر آیتمی شکست بخورد، API با 500 پاسخ میدهد و نتایج جزئی برای آن درخواست باز نمیگرداند.
بدنه درخواست
| فیلد | نوع | اجباری | توضیح |
|---|---|---|---|
items | array | بله | هر عنصر: id (رشته)، content (رشته)، format اختیاری. |
targets | string[] | بله | همان قوانین /translate. |
source | string | خیر | نشانه زبان منبع اختیاری. |
model | string | خیر | standard یا advanced (همان قوانین /translate). |
پاسخ 200
{
"results": [
{ "id": "welcome", "translations": { "fr": "...", "de": "..." } },
{ "id": "goodbye", "translations": { "fr": "...", "de": "..." } }
],
"usage": {
"total_tokens": 900,
"input_tokens": 400,
"output_tokens": 500,
"model": "standard"
}
}
مثال
curl -sS -X POST "https://api.usepolylingo.com/v1/translate/batch" \
-H "Authorization: Bearer $POLYLINGO_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"items": [
{ "id": "a", "content": "Hello", "format": "plain" },
{ "id": "b", "content": "## Title", "format": "markdown" }
],
"targets": ["es", "it"]
}'
POST /jobs
نیازمند Authorization: Bearer <api_key>.
یک کار ترجمه را در صف قرار میدهد و بلافاصله با job_id پاسخ میدهد. ترجمه در پسزمینه اجرا میشود — بدون خطر تایماوت HTTP صرفنظر از اندازه محتوا. برای نتیجه، GET /jobs/:id را نظرسنجی کنید.
این نقطه پایانی را به جای POST /translate هنگام ترجمه اسناد بزرگ (Markdown طولانی، زبانهای هدف متعدد) استفاده کنید که ممکن است مدت درخواست از تایماوت کلاینت HTTP یا پراکسی شما بیشتر شود.
بدنه درخواست
| فیلد | نوع | اجباری | توضیح |
|---|---|---|---|
content | string | بله | رشته غیرخالی برای ترجمه. |
targets | string[] | بله | آرایه غیرخالی از کدهای زبان معتبر (حداکثر 36). |
format | string | خیر | یکی از plain، markdown، json، html. اگر حذف شود، به صورت خودکار تشخیص داده میشود. |
source | string | خیر | نشانه زبان منبع؛ اختیاری. |
model | string | خیر | standard (پیشفرض) یا advanced. |
پاسخ 202
{
"job_id": "a1b2c3d4-...",
"status": "pending",
"created_at": "2025-03-23T12:00:00.000Z"
}
GET /jobs/:id
نیازمند Authorization: Bearer <api_key>.
وضعیت کاری که از طریق POST /jobs ارسال شده را نظرسنجی میکند. هر 5–10 ثانیه نظرسنجی کنید. کارها متعلق به کاربری هستند که آنها را ارسال کرده — کاربران دیگر 404 دریافت میکنند.
پاسخ (در انتظار / در حال پردازش)
{
"job_id": "a1b2c3d4-...",
"status": "pending",
"created_at": "2025-03-23T12:00:00.000Z",
"updated_at": "2025-03-23T12:00:00.000Z",
"completed_at": null,
"queue_position": 3
}
status میتواند pending (در انتظار کارگر) یا processing (کارگر آن را گرفته) باشد. queue_position (مبنای 1) تعداد کارهای در انتظار یا در حال پردازش که دقیقاً قبل از این ایجاد شدهاند را نشان میدهد — برای UI پیشرفت استفاده کنید. اگر پرسوجوی شمارش شکست بخورد، حذف میشود.
پاسخ (تکمیل شده)
{
"job_id": "a1b2c3d4-...",
"status": "completed",
"created_at": "2025-03-23T12:00:00.000Z",
"updated_at": "2025-03-23T12:00:02.000Z",
"completed_at": "2025-03-23T12:00:02.000Z",
"translations": {
"es": "...",
"fr": "..."
},
"usage": {
"input_tokens": 120,
"output_tokens": 340,
"total_tokens": 460,
"model": "standard"
}
}
پاسخ (ناموفق)
{
"job_id": "a1b2c3d4-...",
"status": "failed",
"error": "Model returned invalid JSON"
}
مثال (JavaScript)
const API = 'https://api.usepolylingo.com/v1'
const headers = {
'Authorization': `Bearer ${process.env.POLYLINGO_API_KEY}`,
'Content-Type': 'application/json',
}
// 1. ارسال
const submit = await fetch(`${API}/jobs`, {
method: 'POST',
headers,
body: JSON.stringify({ content: longMarkdown, format: 'markdown', targets: ['de', 'fr'] }),
})
const { job_id } = await submit.json()
// 2. نظرسنجی
while (true) {
await new Promise(r => setTimeout(r, 10_000))
const poll = await fetch(`${API}/jobs/${job_id}`, { headers })
const job = await poll.json()
if (job.status === 'completed') { console.log(job.translations); break }
if (job.status === 'failed') { throw new Error(job.error) }
// اختیاری: نمایش پیشرفت (queue_position مبنای 1 است، وقتی در صف نیست حذف میشود)
if (job.queue_position != null) console.log(`موقعیت در صف: ${job.queue_position}`)
}
GET /usage
نیازمند Authorization: Bearer <api_key> (جستجوی کلید استاندارد — نه مسیر داخلی فقط برای دور زدن).
استفاده توکن را برای ماه تقویمی جاری برای کاربر احراز هویت شده برمیگرداند.
پاسخ 200
{
"period_start": "2025-03-01T00:00:00.000Z",
"period_end": "2025-03-31T23:59:59.000Z",
"tokens_used": 12000,
"tokens_included": 100000,
"tokens_remaining": 88000,
"overage_tokens": 0,
"tier": "free"
}
tokens_included و tokens_remaining برای enterprise مقدار null دارند (اختصاص نامحدود در گزارشدهی).
فرمتهای محتوا
مقادیر پشتیبانیشده format: plain، markdown، json، html.
| فرمت | حفظ شده | ترجمه شده |
|---|---|---|
plain | شکست خطوط / پاراگرافها | تمام متن قابل مشاهده |
markdown | نحو، لینکها (URL بدون تغییر)، کد محصور (کلمه به کلمه) | متن و متن لینک |
json | کلیدها، ساختار، انواع غیررشتهای | فقط مقادیر رشتهای |
html | تگها و ویژگیها | گرههای متنی و ویژگیهای مناسب (نگاه کنید به prompts) |
RTL و جهت در برنامه شما
برای خروجیهای plain و markdown، API فقط متن ترجمهشده را برمیگرداند — dir="rtl" یا عناصر پوشاننده اضافه نمیکند. هنگام نمایش عربی، عبری یا فارسی، جهت متن را در UI خود تنظیم کنید (CSS direction، ویژگی dir عنصر والد یا طرحبندی i18n فریمورک شما).
برای فرمت html، نشانهگذاری ترجمهشده ممکن است شامل dir="rtl" باشد، در صورت مناسب بودن برای اهداف RTL.
پاسخهای خطا
خطاها در صورت امکان JSON هستند:
{
"error": "invalid_request",
"message": "جزئیات قابل خواندن برای انسان"
}
| HTTP | error | چه زمانی |
|---|---|---|
| 400 | invalid_request | فیلدهای بدنه گمشده/نامعتبر (مثلاً content خالی، targets نامناسب) |
| 400 | invalid_format | format در مجموعه پشتیبانیشده نیست |
| 400 | invalid_language | کد ناشناخته در targets |
| 401 | invalid_api_key | Authorization گمشده/ناقص، کلید ناشناخته، کلید لغو شده |
| 403 | advanced_not_available | model: "advanced" در سطح رایگان |
| 429 | token_limit_reached | سقف ماهانه سطح رایگان (پیشبررسی) |
| 429 | rate_limit_reached | محدودیت RPM دقیقهای (وقتی Redis فعال است) |
| 500 | translation_error | خطای مدل/شبکه؛ ایمن برای تلاش مجدد |
| 404 | not_found | GET /jobs/:id — کار وجود ندارد یا متعلق به کاربر دیگری است |
| 500 | server_error | POST /jobs — خطا در صفگذاری؛ ایمن برای تلاش مجدد |
GET /usage ممکن است با پیام عمومی 500 بازگردد اگر پرسوجوی Supabase شکست بخورد.