Referencje API

Kompletna referencja dla każdego punktu końcowego, kształtu żądania i odpowiedzi, kodu błędu oraz limitu szybkości.

Limity i zachowanie

ElementWartość
Rozmiar ciała JSONDo 2 MB (express.json({ limit: '2mb' }))
Cele na żądanie1–50 kodów języków
Elementy partii1–100 elementów na żądanie partii
Modelestandard (domyślny) lub advanced (tylko płatne poziomy; patrz poniżej)

Miesięczny limit tokenów (poziom darmowy): Przed wywołaniem modelu API szacuje tokeny jako mniej więcej ceil(content_length / 4) × (number_of_targets + 1) i tylko dla poziomu free odrzuca żądanie z kodem 429 / token_limit_reached, jeśli szacowana wartość przekroczyłaby pozostały miesięczny limit (domyślnie 100000). Poziomy płatne nie są blokowane przez tę wstępną kontrolę; użycie jest nadal rejestrowane.

Limity szybkości: Gdy Redis jest skonfigurowany, obowiązują limity na minutę według poziomu: darmowy 5, startowy 30, wzrost 60, skala 120, enterprise bez limitu. Po przekroczeniu limitu odpowiedź to 429 z error: "rate_limit_reached". Jeśli Redis nie jest skonfigurowany, limitowanie szybkości jest pomijane.

Udane odpowiedzi z limitowaniem szybkości mogą zawierać nagłówki X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset.


GET /health

Brak uwierzytelniania.

Odpowiedź 200

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

GET /languages

Brak uwierzytelniania.

Zwraca kanoniczną listę obsługiwanych języków (kod, nazwa wyświetlana, flaga RTL). Jest 43 wpisów — 36 języków bazowych i 7 wariantów regionalnych. Warianty regionalne używają podtagów regionu BCP-47 (np. fr-CA, pt-BR, es-MX). Kody z tego punktu końcowego są jedynymi wartościami akceptowanymi w targets na punktach końcowych tłumaczenia.

Odpowiedź 200

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

Lista na żywo jest również dostępna przez GET /languages — patrz poniżej.


POST /translate

Wymaga Authorization: Bearer <api_key>.

Tłumaczy pojedynczy ciąg content na każdy język wymieniony w targets. Odpowiedź to pojedynczy obiekt JSON, którego klucze to dokładnie żądane kody języków, a wartości to przetłumaczone ciągi.

Treść żądania

PoleTypWymaganeOpis
contentstringTakNiepusty ciąg do przetłumaczenia.
targetsstring[]TakNiepusta tablica prawidłowych kodów języków (maks. 36).
formatstringNieJeden z plain, markdown, json, html. Jeśli pominięty, format jest automatycznie wykrywany z content.
sourcestringNieWskazówka dotycząca języka źródłowego dla modelu; opcjonalne.
modelstringNiestandard (domyślny) lub advanced. advanced wymaga płatnego poziomu (403 na darmowym).

Odpowiedź 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 i detection_confidence pojawiają się tylko wtedy, gdy format został pominięty i uruchomiono automatyczne wykrywanie.

Przykład (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"]
  }'

Przykład (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

Wymaga Authorization: Bearer <api_key>.

Przetwarza każdy element sekwencyjnie (jedno wywołanie modelu na element). Jeśli którykolwiek element się nie powiedzie, API zwraca 500 i nie zwraca częściowych wyników dla tego żądania.

Treść żądania

PoleTypWymaganeOpis
itemsarrayTakKażdy element: id (string), content (string), opcjonalny format.
targetsstring[]TakTe same zasady co w /translate.
sourcestringNieOpcjonalna wskazówka języka źródłowego.
modelstringNiestandard lub advanced (te same zasady co w /translate).

Odpowiedź 200

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

Przykład

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

Wymaga Authorization: Bearer <api_key>.

Umieszcza zadanie tłumaczenia w kolejce i zwraca natychmiast job_id. Tłumaczenie odbywa się w tle — brak ryzyka przekroczenia limitu czasu HTTP niezależnie od rozmiaru zawartości. Polluj GET /jobs/:id po wynik.

Użyj tego punktu końcowego zamiast POST /translate podczas tłumaczenia dużych dokumentów (długi Markdown, wiele języków docelowych), gdzie czas trwania żądania może przekroczyć limit czasu klienta HTTP lub proxy.

Treść żądania

PoleTypWymaganeOpis
contentstringTakNiepusty ciąg do przetłumaczenia.
targetsstring[]TakNiepusta tablica prawidłowych kodów języków (maks. 36).
formatstringNieJeden z plain, markdown, json, html. Automatycznie wykrywany, jeśli pominięty.
sourcestringNieWskazówka języka źródłowego; opcjonalne.
modelstringNiestandard (domyślny) lub advanced.

Odpowiedź 202

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

GET /jobs/:id

Wymaga Authorization: Bearer <api_key>.

Polluje status zadania przesłanego przez POST /jobs. Polluj co 5–10 sekund. Zadania należą do użytkownika, który je przesłał — inni użytkownicy otrzymują 404.

Odpowiedź (pending / processing)

{
  "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 to pending (oczekuje na pracownika) lub processing (pracownik przejął zadanie). queue_position (liczone od 1) to ile zadań oczekujących lub przetwarzanych zostało utworzonych ściśle przed tym — użyj tego do UI postępu. Pomijane, gdy zapytanie o liczbę się nie powiedzie.

Odpowiedź (completed)

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

Odpowiedź (failed)

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

Przykład (JavaScript)

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

// 1. Prześlij
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. Poll
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) }
  // Opcjonalnie: pokaż postęp (queue_position liczone od 1, pomijane gdy nie w kolejce)
  if (job.queue_position != null) console.log(`Queue position: ${job.queue_position}`)
}

GET /usage

Wymaga Authorization: Bearer <api_key> (standardowe wyszukiwanie klucza — nie wewnętrzna ścieżka omijająca).

Zwraca użycie tokenów za bieżący miesiąc kalendarzowy dla uwierzytelnionego użytkownika.

Odpowiedź 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 i tokens_remainingnull dla enterprise (nieograniczona pula w raportowaniu).


Formaty treści

Obsługiwane wartości format: plain, markdown, json, html.

FormatZachowaneTłumaczone
plainZłamania linii / akapityCały widoczny tekst
markdownSkładnia, linki (URL bez zmian), fenced code (dosłownie)Proza i tekst linków
jsonKlucze, struktura, typy niebędące stringamiTylko wartości stringowe
htmlTag-i i atrybutyWęzły tekstowe i odpowiednie atrybuty (patrz podpowiedzi)

RTL i kierunek w Twojej aplikacji

Dla wyjścia plain i markdown API zwraca tylko przetłumaczony tekst — nie dodaje dir="rtl" ani elementów opakowujących. Ustaw kierunek tekstu w UI (CSS direction, atrybut dir elementu nadrzędnego lub układ i18n Twojego frameworka) podczas wyświetlania języka arabskiego, hebrajskiego lub perskiego.

Dla formatu html przetłumaczony markup może zawierać dir="rtl" tam, gdzie jest to odpowiednie dla celów RTL.


Odpowiedzi błędów

Błędy są w formacie JSON, jeśli to możliwe:

{
  "error": "invalid_request",
  "message": "Szczegóły czytelne dla człowieka"
}
HTTPerrorKiedy
400invalid_requestBrakujące/nieprawidłowe pola w ciele (np. puste content, złe targets)
400invalid_formatformat nie jest w obsługiwanym zestawie
400invalid_languageNieznany kod w targets
401invalid_api_keyBrakujący/błędny Authorization, nieznany klucz, cofnięty klucz
403advanced_not_availablemodel: "advanced" na darmowym poziomie
429token_limit_reachedMiesięczny limit darmowego poziomu zostałby przekroczony (wstępna kontrola)
429rate_limit_reachedLimit RPM na minutę (gdy Redis jest włączony)
500translation_errorBłąd modelu/sieci; bezpieczne do ponownego wywołania
404not_foundGET /jobs/:id — zadanie nie istnieje lub należy do innego użytkownika
500server_errorPOST /jobs — nie udało się dodać do kolejki; bezpieczne do ponownego wywołania

GET /usage może zwrócić 500 z ogólnym komunikatem, jeśli zapytanie Supabase się nie powiedzie.

Referencje API | PolyLingo | PolyLingo