API 참조

모든 엔드포인트, 요청 및 응답 형식, 오류 코드 및 속도 제한에 대한 완전한 참조입니다.

제한 및 동작

항목
JSON 본문 크기최대 2 MB (express.json({ limit: '2mb' }))
요청당 대상1–50 개의 언어 코드
배치 항목배치 요청당 1–100 항목
모델standard (기본) 또는 advanced (유료 등급만; 아래 참조)

월별 토큰 허용량 (무료 등급): 모델 호출 전에 API는 토큰을 대략 ceil(content_length / 4) × (number_of_targets + 1)로 추정하며, free 등급에 대해서만 이 추정치가 남은 월별 할당량(기본값 100000)을 초과하면 429 / token_limit_reached로 요청을 거부합니다. 유료 등급은 이 사전 검사를 차단하지 않으며, 사용량은 계속 기록됩니다.

속도 제한: Redis가 구성된 경우, 등급별로 분당 제한이 적용됩니다: 무료 5, 스타터 30, 성장 60, 스케일 120, 엔터프라이즈 무제한. 제한 초과 시 응답은 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는 유료 등급 필요 (free에서 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_formatdetection_confidenceformat이 생략되어 자동 감지가 실행된 경우에만 나타납니다.

예제 (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> 필요.

각 항목을 순차적으로 처리합니다(항목당 모델 호출 1회). 항목 중 하나라도 실패하면 API는 500을 반환하며 해당 요청에 대한 부분 결과를 반환하지 않습니다.

요청 본문

필드유형필수설명
items배열각 요소: 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로 폴링합니다.

긴 문서(긴 Markdown, 많은 대상 언어)를 번역할 때 요청 시간이 HTTP 클라이언트 또는 프록시 타임아웃을 초과할 수 있으므로 POST /translate 대신 이 엔드포인트를 사용하세요.

요청 본문

필드유형필수설명
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(`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_includedtokens_remainingenterprise의 경우 null입니다 (보고서에 무제한 할당).


콘텐츠 형식

지원되는 format 값: plain, markdown, json, html.

형식보존됨번역됨
plain줄 바꿈 / 단락모든 표시 텍스트
markdown구문, 링크 (URL 변경 없음), 펜스 코드 (있는 그대로)산문 및 링크 텍스트
json키, 구조, 비문자열 유형문자열 값만
html태그 및 속성텍스트 노드 및 적절한 속성 (프롬프트 참조)

앱에서의 RTL 및 방향

plainmarkdown 출력의 경우, API는 번역된 텍스트만 반환하며 dir="rtl" 또는 래퍼 요소를 추가하지 않습니다. 아랍어, 히브리어 또는 페르시아어를 표시할 때 UI에서 텍스트 방향(CSS direction, 상위 요소의 dir 속성 또는 프레임워크의 i18n 레이아웃)을 설정하세요.

html 형식의 경우, 번역된 마크업에 RTL 대상에 적합한 경우 dir="rtl"이 포함될 수 있습니다.


오류 응답

오류는 가능하면 JSON 형식입니다:

{
  "error": "invalid_request",
  "message": "사람이 읽을 수 있는 상세 내용"
}
HTTPerror상황
400invalid_request본문 필드 누락/잘못됨 (예: 빈 content, 잘못된 targets)
400invalid_format지원되지 않는 format
400invalid_languagetargets에 알 수 없는 코드 포함
401invalid_api_key누락/잘못된 Authorization, 알 수 없는 키, 취소된 키
403advanced_not_available무료 등급에서 model: "advanced" 요청 시
429token_limit_reached무료 등급 월별 한도 초과 시 (사전 검사)
429rate_limit_reached분당 RPM 제한 초과 시 (Redis 활성화 시)
500translation_error모델/네트워크 실패; 재시도 가능
404not_foundGET /jobs/:id — 작업이 없거나 다른 사용자 소유
500server_errorPOST /jobs — 큐에 넣기 실패; 재시도 가능

GET /usage는 Supabase 쿼리 실패 시 일반 메시지와 함께 500을 반환할 수 있습니다.

API 참조 | PolyLingo | PolyLingo