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 налаштований, застосовуються обмеження за хвилину за рівнем: free 5, starter 30, growth 60, scale 120, enterprise необмежено. При досягненні ліміту відповідь має код 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-об’єкт, ключі якого точно відповідають запитаним кодам мов, а значення — перекладені рядки.

Тіло запиту

ПолеТипОбов’язковеОпис
contentstringТакНепорожній рядок для перекладу.
targetsstring[]ТакНепорожній масив дійсних кодів мов (макс. 36).
formatstringНіОдне з plain, markdown, json, html. Якщо пропущено, формат автоматично визначається з content.
sourcestringНіПідказка про вихідну мову для моделі; необов’язково.
modelstringНі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 і не повертає часткові результати для цього запиту.

Тіло запиту

ПолеТипОбов’язковеОпис
itemsarrayТакКожен елемент: id (рядок), content (рядок), необов’язковий format.
targetsstring[]ТакТі ж правила, що й для /translate.
sourcestringНіНеобов’язкова підказка про вихідну мову.
modelstringНі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-клієнта або проксі.

Тіло запиту

ПолеТипОбов’язковеОпис
contentstringТакНепорожній рядок для перекладу.
targetsstring[]ТакНепорожній масив дійсних кодів мов (макс. 36).
formatstringНіОдне з plain, markdown, json, html. Автоматично визначається, якщо пропущено.
sourcestringНіПідказка про вихідну мову; необов’язково.
modelstringНі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
}

statuspending (очікування працівника) або 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 дорівнюють null для enterprise (необмежена квота у звітах).


Формати вмісту

Підтримувані значення format: plain, markdown, json, html.

ФорматЗбереженоПерекладено
plainПереноси рядків / абзациВесь видимий текст
markdownСинтаксис, посилання (URL без змін), блоки коду (дослівно)Проза та текст посилань
jsonКлючі, структура, не рядкові типиТільки рядкові значення
htmlТеги та атрибутиТекстові вузли та відповідні атрибути (див. підказки)

RTL та напрямок у вашому додатку

Для виводу plain та markdown API повертає лише перекладений текст — не додає dir="rtl" або обгорткові елементи. Встановлюйте напрямок тексту у вашому UI (CSS direction, атрибут dir батьківського елемента або i18n-розмітку вашого фреймворку) при відображенні арабської, івриту або перської.

Для формату html перекладена розмітка може містити dir="rtl" там, де це доречно для RTL-цілей.


Відповіді з помилками

Помилки у форматі JSON, якщо можливо:

{
  "error": "invalid_request",
  "message": "Людинозрозумілий опис"
}
HTTPerrorКоли
400invalid_requestВідсутні/недійсні поля тіла (наприклад, порожній content, неправильні targets)
400invalid_formatformat не в підтримуваному наборі
400invalid_languageНевідомий код у targets
401invalid_api_keyВідсутній/пошкоджений Authorization, невідомий ключ, відкликаний ключ
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 | PolyLingo | PolyLingo