---
title: "Translate"
description: "폰트 굵기, 색상, 레이아웃, 배지 배경은 그대로 두고 상품 이미지 속 텍스트를 번역문으로 바꿉니다."
---

> Every apinoa docs page as markdown: https://apinoa.com/llms.txt (all in one file: https://apinoa.com/llms-full.txt; this API family in one file: https://apinoa.com/docs/image-translate/llms.txt)

```http
POST /v1/image-translate/translate
```

이미지는 본문에 **원시 바이트**로 보내고(JSON도, base64도 아닙니다), 나머지 파라미터는 모두 쿼리
문자열로 보냅니다. 번역된 JPEG를 돌려받거나, `render=false`이면 텍스트를 지운 이미지와 모든 텍스트 영역을
JSON으로 돌려받습니다.

## 요청

```bash tab="cURL"
curl -X POST "https://gateway.apinoa.com/v1/image-translate/translate?source_language=zh-CN&target_language=ko" \
  -H "x-api-key: $APINOA_API_KEY" \
  -H "Content-Type: image/jpeg" \
  --data-binary @product.jpg \
  -o translated.jpg
```

```js tab="JavaScript"
import { readFile, writeFile } from "node:fs/promises";

const params = new URLSearchParams({ source_language: "zh-CN", target_language: "ko" });
const res = await fetch(`https://gateway.apinoa.com/v1/image-translate/translate?${params}`, {
  method: "POST",
  headers: { "x-api-key": process.env.APINOA_API_KEY, "Content-Type": "image/jpeg" },
  body: await readFile("product.jpg"),
});
await writeFile("translated.jpg", Buffer.from(await res.arrayBuffer()));
```

```python tab="Python"
import os

import requests

with open("product.jpg", "rb") as f:
    image = f.read()

res = requests.post(
    "https://gateway.apinoa.com/v1/image-translate/translate",
    params={"source_language": "zh-CN", "target_language": "ko"},
    headers={"x-api-key": os.environ["APINOA_API_KEY"], "Content-Type": "image/jpeg"},
    data=image,
    timeout=300,
)
res.raise_for_status()
with open("translated.jpg", "wb") as f:
    f.write(res.content)
```

## 파라미터

**헤더**

| 헤더 | 필수 | 비고 |
|---|---|---|
| `x-api-key` | 예 | API 키. |
| `Content-Type` | 예 | `image/jpeg`, `image/png`, `image/webp`, `application/octet-stream` 중 하나. |

**쿼리 문자열**

| 파라미터 | 타입 | 필수 | 비고 |
|---|---|---|---|
| `source_language` | string | 예 | 텍스트의 언어: `ch`, `zh`, `zh-CN`, `zh-TW`, `chinese_cht`, `ja`, `japan`, `en`, 또는 `auto`. `auto`는 언어 확인을 건너뛰므로 번역문이 있는 모든 영역을 그립니다. |
| `target_language` | string (2–8) | 예 | 번역할 언어. ISO 639 형식의 코드입니다. 한국어, 중국어 간체, 일본어, 라틴 문자 언어가 가장 잘 그려집니다. 언어별 폰트는 [Supported Fonts](/docs/api-reference/image-translate/supported-fonts)에 있습니다. |
| `font` | string | | [Supported Fonts](/docs/api-reference/image-translate/supported-fonts)의 `allFonts` 값, 또는 업로드한 [맞춤 폰트](/docs/api-reference/image-translate/custom-fonts)의 `user/<id>`. 기본값 `Pretendard`. 폰트에 없는 글리프는 `Pretendard`와 `NotoSansSC`로 대체됩니다. |
| `font_weight` | string | | `auto`, `Thin`, `Light`, `Regular`, `Medium`, `SemiBold`, `Bold`, `ExtraBold`, `Black` 중 하나. 기본값 `ExtraBold`. `auto`는 영역마다 원래 굵기를 따르고, 다른 값은 모든 영역에 적용됩니다. |
| `render` | boolean | | `true`(기본값)는 완성된 이미지를, `false`는 직접 그릴 수 있도록 텍스트를 지운 이미지와 영역을 JSON으로 돌려줍니다. |

## 응답

### `render=true`(기본값): 이미지

본문은 번역된 **JPEG**(`Content-Type: image/jpeg`)이며, 다음 헤더가 붙습니다.

| 헤더 | 의미 |
|---|---|
| `X-Apinoa-Request-Id` | 요청 id. 고객 지원에 문의할 때 알려 주세요. |
| `X-Apinoa-Regions-Count` | 감지되어 교체된 텍스트 영역 수. |

텍스트가 없는 이미지는 `X-Apinoa-Regions-Count: 0`과 함께 그대로 돌아옵니다.

### `render=false`: 영역을 담은 JSON

실제 응답을 첫 번째 영역만 남기고 줄인 것입니다.

```json
{
  "success": true,
  "requestId": "240d4c0348574bd7bc12f8e5d8780a87",
  "data": {
    "inpainted_base64": "/9j/4AAQSkZJRgABAQAA…",
    "regions": [
      {
        "index": 0,
        "polygon": [[83, 68], [352, 68], [352, 145], [83, 145]],
        "bbox": { "x": 83, "y": 68, "w": 269, "h": 77 },
        "text": "限时特价",
        "text_kr": "기간 한정 특가",
        "confidence": 0.999354,
        "text_color": { "r": 255, "g": 253, "b": 252 },
        "bg_color": { "r": 211, "g": 40, "b": 43 },
        "bg_std": 0.418889,
        "font_weight": "Regular",
        "is_badge": false
      }
    ],
    "regions_count": 3
  }
}
```

| 필드 | 타입 | 의미 |
|---|---|---|
| `inpainted_base64` | string | 원본 텍스트를 지운 이미지. base64 JPEG입니다. |
| `regions[].index` | integer | 영역 번호. 0부터 시작합니다. |
| `regions[].polygon` | number[][] | 네 꼭짓점. 원본 이미지 좌표입니다. |
| `regions[].bbox` | object | 경계 박스 `{x, y, w, h}`. 원본 이미지 좌표입니다. |
| `regions[].text` | string | 읽어 낸 텍스트. |
| `regions[].text_kr` | string | `target_language`로 번역한 텍스트(필드 이름은 과거의 흔적입니다). |
| `regions[].confidence` | number | 인식 신뢰도, 0–1. |
| `regions[].text_color`, `regions[].bg_color` | object | 추정한 텍스트 색과 배경색. RGB입니다. |
| `regions[].bg_std` | number | 텍스트 뒤 배경이 얼마나 고르지 않은지. 0에 가까우면 단색입니다. |
| `regions[].font_weight` | string | 감지한 굵기. |
| `regions[].is_badge` | boolean | 가격표나 할인 배지처럼 채워진 라벨 위의 텍스트이면 `true`. |
| `regions_count` | integer | 찾은 영역 수. |

## 에러

| 상태 | 코드 | 의미 |
|---|---|---|
| 400 | `BAD_REQUEST` | 본문이 비었거나, 쿼리 파라미터가 유효하지 않습니다. |
| 401 | `UNAUTHORIZED` | `x-api-key` 헤더가 없거나, 키가 유효하지 않습니다. |
| 402 | `INSUFFICIENT_BALANCE` | 잔액이 이 호출 비용에 모자랍니다. 다시 시도해도 해결되지 않으니 충전하세요. |
| 413 | `PAYLOAD_TOO_LARGE` | 본문이 20 MB를 넘습니다. 보내기 전에 크기를 줄이세요. |
| 413 | `IMAGE_TOO_LARGE` | 이미지가 8192 × 8192 px를 넘습니다. |
| 415 | `UNSUPPORTED_MEDIA_TYPE` | `Content-Type`이 이미지 타입이 아닙니다. `image/jpeg`, `image/png`, `image/webp`로 원시 바이트를 보내세요. |
| 422 | `INVALID_IMAGE` | 읽을 수 있는 이미지 데이터가 아닙니다. |
| 502 | `UPSTREAM_ERROR` | 처리를 잠시 할 수 없습니다. 다시 시도하세요. 보통 1분 안에 회복됩니다. |
| 503 | `SERVICE_UNAVAILABLE` | 일시적으로 처리 용량을 넘었습니다. 백오프로 다시 시도하세요. |

모든 코드는 [Errors](/docs/errors)에 있습니다. 실패한 호출은 과금되지 않습니다.

## 가격

각 호출은 [가격 페이지](/pricing)의 이미지 번역 요율로 과금됩니다.

## 참고

- **한도.** JPEG, PNG, WebP 이미지, 최대 8192 × 8192 px, 본문 20 MB까지입니다.
- **타임아웃.** 대부분의 호출은 1.5–3초 안에 끝나지만, 부하가 크면 최대 **5분**까지 걸릴 수 있습니다. 느린 응답이
  클라이언트 쪽에서 끊기지 않도록 HTTP 클라이언트의 타임아웃을 300초 이상으로 설정하세요.
- **직접 그리기.** `render=false`이면 `inpainted_base64`를 디코딩하고, 각 영역의 `text_kr`을
  `polygon` 안에 `text_color`, `bg_color`, `font_weight`로 그리세요.
- **나만의 폰트.** 폰트를 업로드하고 `font=user/<id>`를 넘기세요. [Custom Fonts](/docs/api-reference/image-translate/custom-fonts)를 참고하세요.
