PrivyTranslate

데스크톱 Local API · v1

기기를 벗어나지 않는 번역 엔드포인트.

macOS 앱은 127.0.0.1에 바인딩된 REST 및 WebSocket API를 열 수 있습니다. 직접 만든 스크립트와 도구가 앱과 같은 로컬 우선 파이프라인으로 번역하게 됩니다.

개요

PrivyTranslate 설정에서 Local API를 켜세요. 그러면 서비스는 루프백 인터페이스에서만 대기합니다. 다른 컴퓨터에서는 닿을 수 없고, 어떤 요청도 어딘가로 중계되지 않습니다.

기본 URLhttp://127.0.0.1:49321/v1
API 버전v1
플랫폼macOS
콘텐츠 유형application/json

OpenAPI JSON 내려받기 ↓

인증

Local API를 켜면 설정 화면에 API 토큰이 표시됩니다. /health와 /capabilities를 제외한 모든 엔드포인트가 이 토큰을 요구합니다. 세 가지 전달 방식을 지원합니다.

  • X-Privy-Token 헤더 — HTTP 요청의 기본 형식입니다.
  • Authorization: Bearer — HTTP 요청과 WebSocket 핸드셰이크 모두에서 받습니다.
  • ?token= 또는 ?access_token= — 헤더를 설정할 수 없는 브라우저 WebSocket 클라이언트를 위한 쿼리 매개변수입니다.

토큰은 다른 자격 증명과 똑같이 다루세요. 가진 쪽에게 이 컴퓨터에서의 번역 권한을 주는 것입니다.

엔드포인트

번역

POST /translate는 최대 128개의 문자열을 한 번에 받아 항목마다 하나씩 순서대로 결과를 돌려줍니다. source의 기본값은 auto이고 target은 필수입니다.

요청

curl
curl -s http://127.0.0.1:49321/v1/translate \
  -H "X-Privy-Token: $PRIVY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "source": "auto",
    "target": "zh-Hans",
    "texts": ["Could you confirm the revised delivery schedule?"],
    "mode": "paragraph",
    "format": "text",
    "options": { "engine": "auto", "sensitive": true }
  }'

mode에는 selection, paragraph, webpage, subtitle, message, document를 쓸 수 있습니다. format에는 text, html, markdown을 쓸 수 있습니다. options 안에서 engine은 특정 백엔드를 고정하고(local-llm, ollama, lm-studio, openai-compatible), sensitive: true는 해당 요청을 번역 기록에서 제외합니다.

응답

200 · application/json
{
  "id": "tr_8F2A6D4E-5F58-4A37-8E92-7B4FD40BE2D2",
  "object": "translation",
  "created": 1755561600,
  "engine": "local-llm",
  "model": "translategemma-4b-it.Q4_K_M.gguf",
  "source": "en",
  "target": "zh-Hans",
  "results": [
    {
      "index": 0,
      "text": "能否确认修订后的交付时间表?",
      "detected_source": "en",
      "confidence": 0.98,
      "alternatives": []
    }
  ],
  "usage": { "input_chars": 48, "output_chars": 15, "latency_ms": 412 }
}

언어 감지

POST /detect는 번역하지 않고 각 항목의 언어 코드와 0에서 1 사이의 신뢰도 점수를 돌려줍니다.

curl
curl -s http://127.0.0.1:49321/v1/detect \
  -H "Authorization: Bearer $PRIVY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "texts": ["Guten Morgen", "早上好"] }'
200 · application/json
{
  "id": "det_8F2A6D4E-5F58-4A37-8E92-7B4FD40BE2D2",
  "object": "language_detection",
  "created": 1755561600,
  "results": [
    { "index": 0, "language": "de", "confidence": 0.97 },
    { "index": 1, "language": "zh-Hans", "confidence": 0.99 }
  ],
  "usage": { "input_chars": 16, "latency_ms": 24 }
}

WebSocket

GET /ws/translate는 WebSocket으로 업그레이드합니다. 보내는 각 프레임은 TranslateRequest이고, 받는 각 프레임은 TranslateResponse 또는 ErrorResponse입니다. 짧은 항목을 연달아 번역하면서 요청마다 드는 부담을 피하고 싶을 때 쓰세요.

JavaScript
const socket = new WebSocket(
  "ws://127.0.0.1:49321/v1/ws/translate?token=" + PRIVY_TOKEN
);

socket.addEventListener("open", () => {
  socket.send(JSON.stringify({
    target: "ja",
    texts: ["The quarterly invoice is attached."]
  }));
});

socket.addEventListener("message", (event) => {
  const frame = JSON.parse(event.data);
  if (frame.error) console.error(frame.error.message);
  else console.log(frame.results[0].text);
});

한도와 언어

GET /capabilities가 실제 값을 알려 줍니다. 아래는 기본값입니다.

max_items128
max_chars_per_item8000
max_total_chars50000

언어 코드

대상 언어는 BCP 47 코드를 씁니다. source는 여기에 더해 auto도 받습니다.

  • enEnglish
  • zh-Hans简体中文
  • zh-Hant繁體中文
  • ja日本語
  • ko한국어
  • frFrançais
  • deDeutsch
  • esEspañol
  • viTiếng Việt
  • thไทย
  • idBahasa Indonesia
  • msBahasa Melayu
  • filFilipino
  • myမြန်မာ
  • kmខ្មែរ
  • loລາວ

오류

실패하면 안정적인 type을 가진 하나의 error 객체가 돌아옵니다.

invalid_request_error 400, 413, 422 잘못된 본문, 알 수 없는 필드, 또는 한도를 넘은 배치.
authentication_error 401, 403 API 토큰이 없거나 잘못됐거나 취소됨.
server_error 500, 503 번역 파이프라인이 실패했거나 앱이 아직 준비되지 않음.
400 · application/json
{
  "error": {
    "code": "batch_too_large",
    "message": "texts exceeds max_items (128)",
    "type": "invalid_request_error",
    "param": "texts"
  }
}