مرجع API

يتطابق هذا المستند مع سلوك تطبيق Express في api/app.js ومع معالجات المسارات تحت api/routes/.

الحدود والسلوك

العنصرالقيمة
حجم جسم JSONحتى 2 ميغابايت (express.json({ limit: '2mb' }))
الأهداف لكل طلب1–36 رمز لغة
عناصر الدُفعة1–100 عنصر لكل طلب دفعة
النماذجstandard (افتراضي) أو advanced (للطبقات المدفوعة فقط؛ انظر أدناه)

الحد الشهري للرموز (الطبقة المجانية): قبل استدعاء النموذج، يقدر API الرموز تقريبًا كـ ceil(content_length / 4) × (number_of_targets + 1) وللطبقة free فقط، يرفض الطلب برمز 429 / token_limit_reached إذا تجاوز التقدير المنحة الشهرية المتبقية (FREE_TIER_MONTHLY_TOKENS، الافتراضي 100000). الطبقات المدفوعة غير محجوزة بواسطة هذا الفحص المسبق في enforceTokenCap؛ لا يزال الاستخدام مسجلاً.

حدود المعدل: عند تكوين Upstash Redis (UPSTASH_REDIS_REST_URL / UPSTASH_REDIS_REST_TOKEN، ولا يحتوي URL على العنصر النائب your-instance)، تنطبق حدود بالدقيقة حسب الطبقة: مجانية 5، مبتدئ 30، نمو 60، مقياس 120، مؤسسة غير محدودة. عند الوصول للحد، يكون الرد 429 مع error: "rate_limit_reached". إذا لم يتم تكوين Redis، يتم تخطي تحديد المعدل (انظر rateLimit.js).

قد تتضمن الردود الناجحة المحددة بالمعدل X-RateLimit-Limit، X-RateLimit-Remaining، X-RateLimit-Reset.


GET /health

لا مصادقة.

الاستجابة 200

{
  "status": "ok",
  "timestamp": "2025-03-23T12:00:00.000Z"
}

GET /languages

لا مصادقة.

يعيد القائمة الرسمية للغات المدعومة (الرمز، الاسم المعروض، علم RTL). هناك 36 إدخالًا؛ الرموز هي القيم الوحيدة المقبولة في targets على نقاط نهاية الترجمة.

الاستجابة 200

{
  "languages": [
    { "code": "en", "name": "English", "rtl": false },
    { "code": "ar", "name": "Arabic", "rtl": true }
  ]
}

المصدر: api/utils/languages.js.


POST /translate

يتطلب Authorization: Bearer <api_key>.

يترجم سلسلة content واحدة إلى كل لغة مدرجة في targets. يعيد النموذج كائن JSON واحد مفاتيحه هي تمامًا رموز اللغات المطلوبة وقيمه هي سلاسل مترجمة (انظر formatPrompts.js).

جسم الطلب

الحقلالنوعمطلوبالوصف
contentسلسلةنعمسلسلة غير فارغة للترجمة.
targetsمصفوفة من السلاسلنعممصفوفة غير فارغة من رموز اللغات الصالحة (بحد أقصى 36).
formatسلسلةلاواحد من plain، markdown، json، html. إذا تم حذفه، يتم الكشف التلقائي عن التنسيق من content.
sourceسلسلةلاتلميح لغة المصدر للنموذج؛ اختياري.
modelسلسلةلا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مصفوفةنعمكل عنصر: id (سلسلة)، content (سلسلة)، format اختياري.
targetsمصفوفة من السلاسلنعمنفس قواعد /translate.
sourceسلسلةلاتلميح لغة المصدر اختياري.
modelسلسلةلا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سلسلةنعمسلسلة غير فارغة للترجمة.
targetsمصفوفة من السلاسلنعممصفوفة غير فارغة من رموز اللغات الصالحة (بحد أقصى 36).
formatسلسلةلاواحد من plain، markdown، json، html. يتم الكشف تلقائيًا إذا تم حذفه.
sourceسلسلةلاتلميح لغة المصدر؛ اختياري.
modelسلسلةلا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) هو عدد الوظائف المعلقة أو المعالجة التي تم إنشاؤها قبل هذه — استخدمه لواجهة المستخدم التقدمية. يحذف عند فشل استعلام العد.

الاستجابة (مكتملة)

{
  "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(`Queue position: ${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 هما null للطبقة enterprise (منحة غير محدودة في التقارير).


تنسيقات المحتوى

القيم المدعومة لـ format: plain، markdown، json، html.

التنسيقمحفوظمترجم
plainفواصل الأسطر / الفقراتكل النص المرئي
markdownالصياغة، الروابط (URL بدون تغيير)، كود محاط (حرفي)النثر ونص الرابط
jsonالمفاتيح، الهيكل، الأنواع غير النصيةقيم النص فقط
htmlالعلامات والسماتعقد النص والسمات المناسبة (انظر المطالبات)

RTL والاتجاه في تطبيقك

لـ plain و markdown، يعيد API النص المترجم فقط — لا يضيف dir="rtl" أو عناصر تغليف. اضبط اتجاه النص في واجهة المستخدم الخاصة بك (CSS direction، سمة dir لعنصر أب، أو تخطيط i18n في الإطار) عند عرض العربية أو العبرية أو الفارسية.

لتنسيق html، قد يتضمن الترميز المترجم dir="rtl" حيثما كان مناسبًا للأهداف RTL؛ انظر formatPrompts.js واختبارات HTML في scripts/test-translation.js.


ردود الأخطاء

الأخطاء تكون JSON عند الإمكان:

{
  "error": "invalid_request",
  "message": "تفصيل قابل للقراءة من قبل الإنسان"
}
HTTPerrorمتى
400invalid_requestحقول جسم مفقودة/غير صالحة (مثل content فارغ، targets سيئة)
400invalid_formatformat غير موجود في المجموعة المدعومة
400invalid_languageرمز غير معروف في targets
401invalid_api_keyAuthorization مفقود/معطوب، مفتاح غير معروف، مفتاح ملغى
403advanced_not_availablemodel: "advanced" على الطبقة المجانية
429token_limit_reachedتجاوز الحد الشهري للطبقة المجانية (فحص مسبق)
429rate_limit_reachedحد RPM بالدقيقة (عند تمكين Redis)
500translation_errorفشل النموذج/الشبكة؛ آمن لإعادة المحاولة
404not_foundGET /jobs/:id — الوظيفة غير موجودة أو تخص مستخدمًا آخر
500server_errorPOST /jobs — فشل في وضع في قائمة الانتظار؛ آمن لإعادة المحاولة

قد يعيد GET /usage رمز 500 مع رسالة عامة إذا فشل استعلام Supabase.


النماذج الأساسية (معلوماتية)

يعرض API فقط standard و advanced. معرفات نموذج OpenAI الفعلية مكونة في api/utils/modelRouter.js ولا تُعاد في ردود API.

مرجع API | بولي لينغو | PolyLingo