API referansı

Bu belge, api/app.js içindeki Express uygulamasının davranışı ve api/routes/ altındaki rota işleyicileri ile eşleşmektedir.

Limitler ve davranış

ÖğeDeğer
JSON gövde boyutu2 MB'a kadar (express.json({ limit: '2mb' }))
İstek başına hedefler1–36 dil kodu
Toplu öğelerToplu istekte 1–100 öğe
Modellerstandard (varsayılan) veya advanced (yalnızca ücretli katmanlar; aşağıya bakınız)

Aylık token hakkı (ücretsiz katman): Model çağrılmadan önce API, tokenleri yaklaşık olarak ceil(content_length / 4) × (number_of_targets + 1) olarak tahmin eder ve sadece free katmanı için, tahmin kalan aylık hibe (FREE_TIER_MONTHLY_TOKENS, varsayılan 100000) aşarsa isteği 429 / token_limit_reached ile reddeder. Ücretli katmanlar enforceTokenCap içindeki bu ön kontrol tarafından engellenmez; kullanım yine de kaydedilir.

Hız limitleri: Upstash Redis yapılandırıldığında (UPSTASH_REDIS_REST_URL / UPSTASH_REDIS_REST_TOKEN ve URL your-instance yer tutucusunu içermiyorsa), katmana göre dakikalık limitler uygulanır: ücretsiz 5, başlangıç 30, büyüme 60, ölçek 120, kurumsal sınırsız. Limit aşılırsa, yanıt 429 ve error: "rate_limit_reached" olur. Redis yapılandırılmamışsa, hız limitleme atlanır (bkz. rateLimit.js).

Başarılı hız limitli yanıtlar X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset içerebilir.


GET /health

Kimlik doğrulama yok.

Yanıt 200

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

GET /languages

Kimlik doğrulama yok.

Desteklenen dillerin kanonik listesini döner (kod, görüntüleme adı, RTL bayrağı). 36 giriş vardır; kodlar çeviri uç noktalarında targets içinde kabul edilen tek değerlerdir.

Yanıt 200

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

Kaynak: api/utils/languages.js.


POST /translate

Authorization: Bearer <api_key> gerektirir.

Tek bir content dizgesini targets içinde listelenen her dile çevirir. Model, anahtarları tam olarak istenen dil kodları olan ve değerleri çevrilmiş dizgiler olan tek bir JSON nesnesi döner (bkz. formatPrompts.js).

İstek gövdesi

AlanTürZorunluAçıklama
contentstringEvetBoş olmayan çevrilecek dizge.
targetsstring[]EvetGeçerli dil kodlarından oluşan boş olmayan dizi (maks 36).
formatstringHayırplain, markdown, json, html değerlerinden biri. Atlanırsa, format content'ten otomatik algılanır.
sourcestringHayırModel için kaynak dil ipucu; isteğe bağlı.
modelstringHayırstandard (varsayılan) veya advanced. advanced ücretli katman gerektirir (free katmanda 403).

Yanıt 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 ve detection_confidence yalnızca format atlanıp otomatik algılama çalıştırıldığında görünür.

Örnek (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"]
  }'

Örnek (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> gerektirir.

Her öğeyi sıralı işler (öğe başına bir model çağrısı). Herhangi bir öğe başarısız olursa, API 500 döner ve o istek için kısmi sonuç döndürmez.

İstek gövdesi

AlanTürZorunluAçıklama
itemsdiziEvetHer öğe: id (string), content (string), isteğe bağlı format.
targetsstring[]Evet/translate ile aynı kurallar.
sourcestringHayırİsteğe bağlı kaynak dil ipucu.
modelstringHayırstandard veya advanced (aynı kurallar /translate ile).

Yanıt 200

{
  "results": [
    { "id": "welcome", "translations": { "fr": "...", "de": "..." } },
    { "id": "goodbye", "translations": { "fr": "...", "de": "..." } }
  ],
  "usage": {
    "total_tokens": 900,
    "input_tokens": 400,
    "output_tokens": 500,
    "model": "standard"
  }
}

Örnek

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> gerektirir.

Bir çeviri işi kuyruğa alır ve hemen job_id ile yanıt verir. Çeviri arka planda çalışır — içerik boyutuna bakılmaksızın HTTP zaman aşımı riski yoktur. Sonuç için GET /jobs/:id sorgulanmalıdır.

Uzun Markdown veya çok sayıda hedef dil içeren büyük belgeleri çevirirken, istek süresi HTTP istemci veya proxy zaman aşımınızı aşabilir; bu durumda bu uç noktayı POST /translate yerine kullanın.

İstek gövdesi

AlanTürZorunluAçıklama
contentstringEvetBoş olmayan çevrilecek dizge.
targetsstring[]EvetGeçerli dil kodlarından oluşan boş olmayan dizi (maks 36).
formatstringHayırplain, markdown, json, html değerlerinden biri. Atlanırsa otomatik algılanır.
sourcestringHayırKaynak dil ipucu; isteğe bağlı.
modelstringHayırstandard (varsayılan) veya advanced.

Yanıt 202

{
  "job_id": "a1b2c3d4-...",
  "status": "pending",
  "created_at": "2025-03-23T12:00:00.000Z"
}

GET /jobs/:id

Authorization: Bearer <api_key> gerektirir.

POST /jobs ile gönderilen işin durumunu sorgular. Her 5–10 saniyede bir sorgulayın. İşler gönderen kullanıcıya aittir — diğer kullanıcılar 404 alır.

Yanıt (beklemede / işleniyor)

{
  "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 (işçi bekleniyor) veya processing (işçi aldı) olabilir. queue_position (1 tabanlı) bu işten önce oluşturulmuş bekleyen veya işlenen iş sayısıdır — ilerleme arayüzü için kullanılır. Sayım sorgusu başarısızsa atlanır.

Yanıt (tamamlandı)

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

Yanıt (başarısız)

{
  "job_id": "a1b2c3d4-...",
  "status": "failed",
  "error": "Model returned invalid JSON"
}

Örnek (JavaScript)

const API = 'https://api.usepolylingo.com/v1'
const headers = {
  'Authorization': `Bearer ${process.env.POLYLINGO_API_KEY}`,
  'Content-Type': 'application/json',
}

// 1. Gönder
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. Sorgula
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) }
  // İsteğe bağlı: ilerlemeyi göster (queue_position 1 tabanlıdır, kuyrukta değilse atlanır)
  if (job.queue_position != null) console.log(`Kuyruk pozisyonu: ${job.queue_position}`)
}

GET /usage

Authorization: Bearer <api_key> gerektirir (standart anahtar sorgulaması — yalnızca dahili atlama yolu değil).

Kimliği doğrulanmış kullanıcı için geçerli takvim ayına ait token kullanımını döner.

Yanıt 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 ve tokens_remaining enterprise için nulldır (raporlama için sınırsız hibe).


İçerik formatları

Desteklenen format değerleri: plain, markdown, json, html.

FormatKorunanÇevrilen
plainSatır sonları / paragraflarTüm görünür metin
markdownSözdizimi, bağlantılar (URL değişmez), kod blokları (verbatim)Düz yazı ve bağlantı metni
jsonAnahtarlar, yapı, dize olmayan türlerYalnızca dize değerleri
htmlEtiketler ve özniteliklerMetin düğümleri ve uygun öznitelikler (bkz. istemler)

Uygulamanızda RTL ve yön

plain ve markdown çıktılar için API yalnızca çevrilmiş metni döner — dir="rtl" veya sarmalayıcı öğeler eklemez. Arapça, İbranice veya Farsça gösterirken UI'nızda metin yönünü ayarlayın (CSS direction, üst öğenin dir özniteliği veya çerçevenizin i18n düzeni).

html formatı için, çevrilmiş işaretleme uygun RTL hedefler için dir="rtl" içerebilir; bkz. formatPrompts.js ve scripts/test-translation.js içindeki HTML testleri.


Hata yanıtları

Hatalar mümkün olduğunda JSON'dur:

{
  "error": "invalid_request",
  "message": "İnsan tarafından okunabilir detay"
}
HTTPerrorNe zaman
400invalid_requestEksik/geçersiz gövde alanları (ör. boş content, hatalı targets)
400invalid_formatDesteklenen kümede olmayan format
400invalid_languagetargets içinde bilinmeyen kod
401invalid_api_keyEksik/bozuk Authorization, bilinmeyen anahtar, iptal edilmiş anahtar
403advanced_not_availableÜcretsiz katmanda model: "advanced"
429token_limit_reachedÜcretsiz katman aylık sınırı aşılırsa (ön kontrol)
429rate_limit_reachedDakikalık RPM limiti (Redis etkinse)
500translation_errorModel/ağ hatası; tekrar denenebilir
404not_foundGET /jobs/:id — iş yok veya başka kullanıcıya ait
500server_errorPOST /jobs — kuyruğa alma başarısız; tekrar denenebilir

GET /usage Supabase sorgusu başarısızsa genel mesajla 500 dönebilir.


Altyapı modelleri (bilgilendirme amaçlı)

API yalnızca standard ve advanced modellerini sunar. Gerçek OpenAI model kimlikleri api/utils/modelRouter.js içinde yapılandırılmıştır ve API yanıtlarında dönmez.

API referansı | PolyLingo | PolyLingo