문자열 하나, 혹은 작은 문자열 객체를 지금 당장 다른 언어로 바꿔야 할 때가 있습니다. 폼 라벨, 알림, 사용자가 기다리고 있는 짧은 UI 카피처럼요. 이런 경우 단 한 번의 왕복을 위해 웹훅 엔드포인트를 돌리거나 작업 상태를 폴링하고 싶지는 않을 겁니다. 텍스트를 보내고, 번역 결과를 바로 받아오고 싶을 뿐이죠.
이럴 때 쓰는 것이 바로 동기식 Localize 엔드포인트입니다. 한 번 요청하면, 같은 구조의 번역된 데이터가 그대로 돌아옵니다. 소스 로캘과 대상 로캘을 지정해 키-값 콘텐츠를 POST하면, 엔진이 번역을 마칠 때까지 호출은 대기하고, 응답으로는 값만 번역되고 구조는 그대로인 동일한 객체가 반환됩니다. 추적할 작업도 없고, 다시 호출할 필요도 없습니다.
이 번역은 일반적인 모델 호출이 아닙니다. 설정해 둔 로컬라이제이션 엔진의 glossary, 브랜드 보이스, instructions, 그리고 로캘별 model selection을 그대로 거치며, async API와 동일한 엔진을 사용합니다. 차이는 오직 제공 방식뿐입니다. async는 하나의 요청을 여러 로캘로 확장해 결과가 준비되는 대로 전달하고, 이 호출은 하나의 로캘 쌍만 처리해 인라인으로 반환합니다.
로캘 하나에 블로킹 호출이면 충분한가요? 그렇다면 잘 오셨습니다.
로캘 쌍 하나만 필요하고 한 번의 왕복을 기다릴 수 있다면 이 엔드포인트를 선택하세요. 대상 로캘이 많거나, 콘텐츠가 길거나, 로캘별로 실패를 분리해 처리하고 싶다면 async Localization API가 더 적합합니다. 이 API는 하나의 요청을 받아 즉시 202를 반환하고, 각 로캘을 독립적이고 내구성 있는 백그라운드 워크플로로 실행합니다. 지연 시간 외에 또 하나의 차이도 있습니다. localization pipeline—사전 편집, human review, 역번역, 그 밖의 선택적 단계—은 async 작업에서만 실행됩니다. 이 동기 호출은 파이프라인 구성을 반영하지 않습니다.
이 페이지에서 다루는 내용
요청#
POST /process/localizeX-API-Key 헤더로 인증합니다. 키는 조직 범위로 발급되며, 조직의 모든 엔진에 접근할 수 있습니다. 키 생성 위치는 Authentication에서, 전체 오류 모델은 Errors and status codes에서 확인하세요.
| 매개변수 | 유형 | 설명 |
|---|---|---|
engineId | string (선택 사항) | 로컬라이제이션 엔진 ID(eng_...)입니다. 생략하면 조직의 기본 엔진을 사용합니다. |
sourceLocale | string | BCP-47 소스 로캘(예: en)입니다. |
targetLocale | string | BCP-47 대상 로캘(예: de)입니다. |
data | object | 번역할 키-값 콘텐츠입니다. 중첩 객체와 배열도 지원하며, 응답은 전송한 구조를 그대로 반영합니다. |
context | string (선택 사항) | 제품 화면, 대상 사용자, 목적처럼 이 번역 페이로드 전반에 적용되는 상위 컨텍스트입니다. 요청 전체에 적용됩니다. |
hints | object (선택 사항) | 키별 컨텍스트 힌트입니다. 키는 data의 키와 일치하며, 값은 breadcrumb 문자열 배열(예: { "nav.home": ["Navbar", "Home link"] })입니다. 이 정보는 문자열이 어디에 쓰이는지 엔진에 알려주어, 짧거나 중의적인 텍스트를 더 정확히 구분할 수 있게 합니다. |
{
"engineId": "eng_abc123",
"sourceLocale": "en",
"targetLocale": "de",
"data": {
"greeting": "Hello, world!",
"cta": "Get started"
},
"hints": {
"cta": ["Landing page", "Primary button"]
}
}응답#
응답에는 전송한 것과 같은 구조의 번역된 콘텐츠와, 이를 생성한 모델, 그리고 요청별 비용이 함께 담깁니다. 같은 키가 같은 중첩 구조로 그대로 돌아오므로, 코드에서는 이미 알고 있는 구조에서 번역값만 바로 읽어오면 됩니다.
| 필드 | 유형 | 설명 |
|---|---|---|
sourceLocale | string | 요청에서 전달한 BCP-47 소스 로캘이 그대로 반환됩니다. |
targetLocale | string | 요청에서 전달한 BCP-47 대상 로캘이 그대로 반환됩니다. |
data | object | 입력 구조와 동일한 번역된 키-값 콘텐츠입니다. |
model | string (선택 사항) | 이 번역을 생성한 LLM model입니다. 형식은 provider/model(예: anthropic/claude-sonnet-4.5)입니다. 폴백 체인에서 실제로 어떤 모델이 실행됐는지 확인할 때 참고하세요. LLM 호출이 없었다면 이 필드는 반환되지 않습니다. 자세한 내용은 아래 콜아웃을 참고하세요. |
usage | object (선택 사항) | 토큰 수와 요청별 USD 비용입니다. LLM 호출이 없었다면 이 필드는 반환되지 않습니다. |
usage 객체는 호출 비용을 항목별로 보여주므로, 별도의 청구 조회 없이도 비용을 바로 귀속할 수 있습니다.
| 필드 | 유형 | 설명 |
|---|---|---|
inputTokens | number | 모든 청크에서 소비된 총 입력 토큰 수입니다. |
outputTokens | number | 모든 청크에서 생성된 총 출력 토큰 수입니다. |
cacheReadTokens | number | 모델이 보고하는 경우, 제공업체의 프롬프트 캐시에서 제공된 입력 토큰 수입니다. |
cacheWriteTokens | number | 모델이 보고하는 경우, 제공업체의 프롬프트 캐시에 기록된 입력 토큰 수입니다. |
llmCost | number | 상위 LLM 제공업체 비용(USD)입니다. 비용이 보고되지 않았다면 0입니다. |
localizationCost | number | outputTokens를 기준으로 계산된 Lingo.dev의 토큰당 USD 비용입니다. |
cost | number | 총 요청 비용(USD)(llmCost + localizationCost)입니다. |
{
"sourceLocale": "en",
"targetLocale": "de",
"data": {
"greeting": "Hallo, Welt!",
"cta": "Jetzt starten"
},
"model": "anthropic/claude-sonnet-4.5",
"usage": {
"inputTokens": 2789,
"outputTokens": 861,
"cacheReadTokens": 0,
"cacheWriteTokens": 0,
"llmCost": 0.02129,
"localizationCost": 0.001722,
"cost": 0.023012
}
}`model`과 `usage`가 없는 경우
data가 비어 있으면, 즉 번역할 키가 없으면 엔드포인트는 LLM을 호출하지 않고 바로 종료되며 응답에서 model와 usage를 생략합니다. 비용 필드가 빠지는 경우는 이것뿐이고, 이유도 단순합니다. 비용 자체가 발생하지 않았기 때문입니다. 번역된 내용이 없으니 지출도 없습니다. 실제 번역이 실행된 모든 요청에는 두 필드가 모두 포함됩니다. 따라서 파서에서는 이 필드들을 선택 사항으로 처리하면 빈 입력 케이스도 문제없이 다룰 수 있습니다.
예시#
같은 호출을 다섯 가지 언어로 보여줍니다. 이해를 돕기 위해 각 예제는 평면 객체를 사용하지만, data는 중첩 객체와 배열도 지원하며 응답은 전송한 구조 그대로 반환됩니다.
const response = await fetch(
"https://api.lingo.dev/process/localize",
{
method: "POST",
headers: {
"X-API-Key": "your_api_key",
"Content-Type": "application/json",
},
body: JSON.stringify({
engineId: "eng_abc123",
sourceLocale: "en",
targetLocale: "de",
data: {
greeting: "Hello, world!",
cta: "Get started",
},
}),
}
);
const { data } = await response.json();
// { greeting: "Hallo, Welt!", cta: "Jetzt starten" }로컬라이제이션 중 일어나는 일#
하나의 POST 뒤에는 여러 단계가 숨어 있습니다. 그리고 그 단계를 이해할 만한 이유가 있습니다. 바로 이 과정 덕분에 결과물이 일회성 모델 추측이 아니라, 나머지 로컬라이즈된 콘텐츠와 일관된 출력으로 이어지기 때문입니다. 요청이 엔드포인트에 도달하면 엔진은 전체 구성을 다음 순서대로 적용합니다.
모델 선택 – 로캘 쌍에 맞는 최우선 LLM model을 선택합니다. 로캘별 모델이 와일드카드(
*) 모델보다 우선합니다. 기본 모델이 실패하면 엔진은 자동으로 다음 순위의 모델로 넘어갑니다.브랜드 보이스 – 대상 로캘에 맞는 브랜드 보이스를 불러오고, 로캘별 설정이 없으면 와일드카드 브랜드 보이스로 대체합니다.
지침 – 와일드카드 지침을 포함해 대상 로캘과 일치하는 모든 instruction을 불러옵니다.
용어집 조회 – 입력 값을 검색 가능한 청크로 나누고 임베딩을 생성한 뒤, 엔진의 glossary를 대상으로 벡터 유사도 검색을 수행합니다. 일치한 용어는 정확한 번역을 강제하거나, 번역 불가 용어로 표시해 원문 그대로 통과시킵니다.
생성 – 구성된 프롬프트를 선택된 모델로 보내고, 이후 JSON 응답을 파싱하고 검증합니다.
이 과정은 async API가 작업별로 실행하는 엔진 단계 파이프라인과 동일합니다. sync를 호출하든 async를 호출하든 달라지는 것은 전달 방식뿐이지, 번역이 만들어지는 방식은 아닙니다. 그래서 여기서 번역된 문자열과 async 작업에서 번역된 같은 문자열은 동일한 glossary 용어와 동일한 보이스를 따르게 됩니다.
모델 폴백은 자동으로 이뤄지며, 응답에서 실제 실행된 모델을 확인할 수 있습니다
기본 모델이 실패하면 엔진은 순위 순서대로 다음 모델을 시도합니다. 이 과정은 투명하게 처리되며, 어떤 모델이 번역을 생성했든 응답 구조는 동일합니다. 폴백이 있었는지 알려주는 유일한 신호는 응답의 model 필드입니다. 체인에서 정확히 어떤 모델이 특정 요청을 처리했는지 알아야 할 때 이 값을 확인하세요.
