הפניה ל-API

מסמך זה תואם את ההתנהגות של אפליקציית Express ב-api/app.js ואת מטפלי הנתיבים תחת api/routes/.

מגבלות והתנהגות

פריטערך
גודל גוף JSONעד 2 MB (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 ארוך, שפות יעד רבות) שבהם משך הבקשה עלול לחרוג מתזמון הלקוח או הפרוקסי שלך.

גוף הבקשה

שדהסוגחובהתיאור
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 | PolyLingo