번역 피드백은 대시보드 클릭으로만 들어오지 않습니다. 사내 지원 도구의 한 줄일 수도 있고, 검토자의 메모일 수도 있으며, 자체 QA 대기열의 한 행일 수도 있습니다. "제품명은 번역하지 마세요", "독일어는 존칭으로 써 주세요" 같은 식이죠. 엔진 제안 API는 이런 자유 텍스트를 코드에서 바로 엔진 변경으로 바꿔 줍니다. 피드백을 텍스트로 보내면 플랫폼이 이를 바탕으로 추론하고, 엔진의 용어집, 지침, 브랜드 보이스에 반영할 수 있는 구체적이고 구조화된 수정안을 돌려주며, 사용자는 그 제안을 직접 적용할 수 있습니다.
이 기능은 대시보드 기능을 코드에서 다루는 방식이라고 보면 됩니다. 대시보드에서는 AI 평가자가 번역에 낮은 점수를 주면 제안이 자동 생성되고, 여기서는 사용자가 그 신호를 텍스트로 직접 제공합니다. 어느 쪽이든 결과는 같습니다. 검토 후 적용할 수 있는 보류 중 제안이 생성됩니다.
흐름은 두 단계로 나뉩니다. 생성은 비동기식입니다. 피드백을 넘기면 플랫폼이 백그라운드에서 추론을 수행해 엔진에 보류 중 제안을 남깁니다. 검토는 동기식입니다. 보류 중 제안을 조회하고, 각 제안이 무엇을 바꾸려는지 확인한 뒤, 하나씩 적용하거나 기각합니다. 이 페이지에서는 두 단계 모두를 다룹니다. 대시보드 경험, 즉 낮은 검토 점수에서의 자동 생성, Suggestions 탭, 알림에 대해서는 엔진 제안을 참고하세요.
번역용이 아니라 구성용 엔드포인트입니다
이 엔드포인트들은 엔진의 구성(용어집, 지침, 브랜드 보이스)을 읽고 변경합니다. 각 엔드포인트는 :id를 기준으로 단일 엔진에 한정되며, API의 다른 부분과 동일한 조직 범위 X-API-Key로 인증합니다. 콘텐츠를 번역하거나 과거 번역을 바꾸지는 않으며, 적용된 제안은 엔진의 다음 번역부터 반영됩니다.
인증
X-API-Key 헤더로 API 키를 전달하세요. 키는 조직 범위로 적용되며, 조직 내 모든 엔진에 접근할 수 있습니다. 자세한 내용은 Authentication을, 이 문서의 모든 엔드포인트가 공통으로 사용하는 오류 모델은 Errors and status codes를 참고하세요.
피드백에서 생성하기#
POST /engines/:id/suggestions/from-text엔진이 무엇을 잘못하고 있는지 일반 텍스트로 설명해 보내세요. 플랫폼은 그 텍스트와 엔진의 현재 구성을 함께 바탕으로 추론해 원자적인 수정안을 제안하며, 엔진에 이미 있는 내용은 다시 제안하지 않습니다. 생성은 비동기로 실행되므로, 이 호출은 제안이 준비될 때가 아니라 작업이 접수되는 즉시 반환됩니다.
| 매개변수 | 유형 | 설명 |
|---|---|---|
id (path) | string | 제안을 생성할 엔진입니다. |
text | string | 엔진 출력에 대한 자유 텍스트 피드백입니다. 1~10,000자이며 공백이 아닌 문자를 최소 1개 이상 포함해야 합니다. |
const response = await fetch(
`https://api.lingo.dev/engines/${engineId}/suggestions/from-text`,
{
method: "POST",
headers: {
"X-API-Key": process.env.LINGO_API_KEY,
"Content-Type": "application/json",
},
body: JSON.stringify({
text: "Our German (de-DE) translations keep using the informal 'du'. For our B2B audience they must always use the formal 'Sie'.",
}),
},
);
const { enqueued } = await response.json();
console.log(enqueued); // true – generation accepted, running in the background{ "enqueued": true }enqueued: true는 플랫폼이 작업을 수락했다는 뜻일 뿐, 제안이 이미 생성됐다는 뜻은 아닙니다. 생성은 하나의 백그라운드 단계로 진행됩니다. 즉, 사용자의 텍스트를 읽고, 구성을 바탕으로 추론하고, 이미 있는 항목과 중복을 제거한 뒤, 제안한 내용을 저장합니다. 어떤 실행에서는 실제로 아무 제안도 나오지 않을 수 있습니다. 피드백이 모호하거나, 엔진이 이미 해당 내용을 반영하고 있을 수 있기 때문입니다. 결과는 잠시 후 엔진의 제안 목록을 조회해 확인하세요.
빈 피드백은 거부됩니다
text에는 실제 메시지가 들어 있어야 합니다. 빈 문자열이나 공백만 있는 문자열은 400와 함께 거부되며, 다른 종류의 요청으로 조용히 처리되지 않습니다. 모델이 실제로 추론할 수 있는 내용을 보내세요.
검토 점수에서 바로 생성할 수도 있습니다
대시보드에서 사용하는 동일한 저점수 트리거를 코드에서도 활용할 수 있습니다. POST /engines/:id/suggestions/generate(빈 본문)는 텍스트 대신 엔진의 최근 낮은 점수 AI 평가를 바탕으로 플랫폼이 수정안을 제안하도록 요청합니다. 응답은 동일한 { "enqueued": true }이고, 생성되는 보류 중 제안도 같습니다. 구체적인 서면 피드백이 있다면 from-text를 사용하고, 평가자들이 이미 지적한 내용을 바탕으로 제안을 끌어오려면 generate를 사용하세요.
보류 중인 제안 조회하기#
GET /engines/:id/suggestions엔진의 제안을 반환합니다. 텍스트에서 트리거했든, 수동 버튼으로 실행했든, 낮은 검토 점수에서 자동 생성됐든 모든 생성 실행의 결과가 여기에 포함됩니다. 각 항목은 제안된 수정안과 그 근거로 구성됩니다.
[
{
"id": "egs_A1b2C3d4E5f6G7h8",
"ownerOrganizationId": "org_X1y2Z3a4B5c6D7e8",
"ownerEngineId": "eng_X1y2Z3a4B5c6D7e8",
"actionType": "add_instruction",
"targetKind": "instruction",
"targetId": null,
"targetLocale": "de-DE",
"payload": { "instruction": "Use the formal 'Sie' form in all German translations; never use the informal 'du'." },
"reasoning": "Feedback states the B2B audience requires formal address, but the engine has no instruction enforcing it.",
"sourceReviewLogIds": [],
"status": "pending",
"appliedTargetId": null,
"createdAt": "2026-06-18T10:30:00.000Z"
}
]| 필드 | 설명 |
|---|---|
id | egs_ 접두사가 붙은 제안 식별자입니다. 이를 apply 또는 dismiss에 전달하세요. |
actionType | add_glossary_item, update_glossary_item, add_instruction, update_instruction, add_brand_voice, update_brand_voice 중 하나입니다. |
targetKind | 수정이 영향을 미치는 엔진의 영역입니다: glossary_item, instruction, 또는 brand_voice. |
targetId | update_* 작업인 경우 변경할 항목의 id(gli_ / ins_ / bvc_)입니다. add_* 작업인 경우에는 null입니다. |
targetLocale | 제안이 적용되는 로캘입니다. |
payload | 즉시 적용 가능한 수정안입니다. 필드는 targetKind에 따라 달라지며, create/update 작업에 필요한 형식이 그대로 들어 있으므로 적용 시 추가 입력이 필요하지 않습니다. |
reasoning | 이 수정안이 제안된 이유를 짧게 설명합니다. |
sourceReviewLogIds | 해당 제안의 계기가 된 검토 로그의 실패 항목(esrl_ id)입니다. 제안이 피드백 텍스트에서 생성된 경우에는 비어 있습니다. |
status | pending, applied, 또는 dismissed. |
appliedTargetId | 제안이 적용되면 생성되거나 업데이트되는 항목입니다. 보류 중일 때는 null입니다. |
payload는 적용을 가볍게 만들어 주는 핵심입니다. 제안된 변경은 생성 시점에 이미 완전히 구조화되어 있으므로, 적용은 또 한 번의 AI 처리 없이 단순한 쓰기 작업으로 끝납니다. 결정은 사용자가 내리고, 플랫폼이 다시 추론하지는 않습니다.
제안 적용하기#
POST /engine-suggestions/:id/apply제안된 변경을 엔진에 기록하고 제안을 applied 상태로 표시합니다. 이는 목록에서 이미 확인한 payload를 그대로 쓰는 결정론적인 작업이며, 두 번째 AI 호출은 없습니다. 즉, 검토한 내용이 그대로 기록됩니다. add_* 제안은 새 용어집 항목, 지침 또는 브랜드 보이스를 생성하고, update_* 제안은 targetId로 지정된 기존 항목을 변경합니다.
const response = await fetch(
`https://api.lingo.dev/engine-suggestions/${suggestionId}/apply`,
{
method: "POST",
headers: { "X-API-Key": process.env.LINGO_API_KEY },
},
);
const applied = await response.json();
console.log(applied.status); // "applied"
console.log(applied.appliedTargetId); // "ins_…" – the instruction it just created응답은 applied 상태의 제안이며, 이제 appliedTargetId는 실제로 생성되거나 업데이트된 엔진 항목을 가리킵니다. 그 항목은 이 시점부터 일반적인 용어집 항목, 지침 또는 브랜드 보이스와 동일합니다. 다른 항목처럼 열고, 수정하고, 삭제할 수 있습니다.
적용은 과거 번역이 아니라 구성을 바꿉니다
적용은 엔진의 구성을 수정합니다. 이미 번역된 콘텐츠는 현재 출력을 그대로 유지하고, 변경 사항은 엔진이 다음에 번역할 때 반영됩니다. apply 자체가 별도로 무엇이든 다시 로컬라이즈하지는 않습니다.
제안 기각하기#
POST /engine-suggestions/:id/dismiss원하지 않는 제안을 제거하고 dismissed 상태로 표시하며, 엔진은 그대로 둡니다. 제품에 맞지 않는 제안일 때 사용하세요. 엔진은 변경되지 않고, 해당 제안도 더 이상 보류 중으로 표시되지 않습니다.
await fetch(
`https://api.lingo.dev/engine-suggestions/${suggestionId}/dismiss`,
{
method: "POST",
headers: { "X-API-Key": process.env.LINGO_API_KEY },
},
);
// The suggestion is now "dismissed"; nothing was written to the engine.처음부터 끝까지 한 바퀴#
이 네 개의 엔드포인트는 코드만으로 완전히 제어할 수 있는 하나의 사이클을 이룹니다. 피드백을 넣고, 무엇이 제안됐는지 확인하고, 동의하는 수정만 반영하면 됩니다.
생성
작성한 피드백과 함께 POST …/suggestions/from-text를 호출하세요(또는 낮은 검토 점수에서 제안을 가져오려면 …/suggestions/generate). { "enqueued": true }는 즉시 반환됩니다.
조회
잠시 후 GET /engines/:id/suggestions를 호출해 보류 중 제안을 확인하세요. 각 제안에는 payload와 reasoning가 포함됩니다.
적용 또는 기각
수정 사항을 반영하려면 POST /engine-suggestions/:id/apply, 버리려면 …/dismiss를 사용하세요. 적용된 내용은 엔진의 다음 번역부터 반영됩니다.
