# 템플릿 및 필드 API 참조

> 추출 템플릿과 해당 필드를 생성 및 관리하고, 내장 프리셋 템플릿을 탐색하며, ImageToTable.ai v1 API의 출력 필드 순서를 제어합니다.

**템플릿**은 문서에서 추출하려는 **필드**의 저장된 재사용 가능 목록입니다. 템플릿의 `id`를 [배치 처리 시작](/developers/reference/batches#start-processing-a-batch)에 전달하면 매 호출마다 필드를 다시 나열할 필요가 없습니다. 또한 [프리셋](#list-presets)에서 템플릿을 빌드하거나, 템플릿을 완전히 건너뛰고 일회성 실행을 위해 임시 `fields`를 `process`에 직접 전달할 수도 있습니다.

## 템플릿 목록

저장된 템플릿을 각각의 전체 정렬된 필드 목록과 함께 반환합니다.

`GET /api/v1/templates`

### 매개변수

| 이름 | 위치 | 유형 | 설명 |
| --- | --- | --- | --- |
| limit | 쿼리, 선택 사항 | 정수 | 1–100. 기본값 50. |
| page_token | 쿼리, 선택 사항 | 문자열 | 이전 응답의 next_page_token 에서 가져온 불투명 커서입니다. 페이지네이션 을 참조하세요. |

### 가능한 오류

- `missing_api_key` / `invalid_api_key` / `plan_required` — [오류 처리](/developers/guides/errors) 참조.
- `invalid_parameter` — 잘못된 `limit` 또는 `page_token`.

## 템플릿 생성

한 엔드포인트에서 템플릿을 생성하는 두 가지 방법: 처음부터 생성 또는 `preset_id`를 통해 내장 프리셋에서 생성.

`POST /api/v1/templates`

### 매개변수

| 이름 | 위치 | 유형 | 설명 |
| --- | --- | --- | --- |
| name | body (JSON) | string | preset_id 가 제공되지 않은 경우 필수. |
| preset_id | body (JSON) | string, 선택 사항 | 내장 프리셋에서 템플릿을 빌드 — 유효한 ID는 프리셋 목록 참조. |
| base_template_id | body (JSON) | integer, 선택 사항 | preset_id 가 제공되지 않은 경우에만 사용 — 기존 템플릿의 필드를 새 템플릿으로 복제. |

### 가능한 오류

- `missing_api_key` / `invalid_api_key` / `plan_required` — [오류 처리](/developers/guides/errors) 참조.
- `missing_parameter` (`param: "name"`) — `name` 및 `preset_id` 모두 없음.
- `invalid_parameter` (`param: "name"`) — 해당 이름의 템플릿이 이미 존재함.
- `invalid_parameter` (`param: "preset_id"`) — 알 수 없는 프리셋 ID.
- `internal_error`

## 템플릿 삭제

템플릿과 모든 필드를 삭제합니다. 과거 `process` 호출에서 이 템플릿을 사용한 문서에는 영향을 주지 않으며, 이미 추출된 결과는 그대로 유지됩니다.

`DELETE /api/v1/templates/{id}`

### 매개변수

| 이름 | 위치 | 유형 | 설명 |
| --- | --- | --- | --- |
| id | path | integer | 삭제할 템플릿입니다. |

### 가능한 오류

- `missing_api_key` / `invalid_api_key` / `plan_required` — [오류 처리](/developers/guides/errors)를 참조하세요.
- `template_not_found`
- `internal_error`

## 프리셋 목록

송장, 영수증, 은행 명세서 등 일반적인 문서 유형에 대한 내장 필드 목록입니다. 프리셋의 `id`를 [템플릿 생성](#create-a-template)에 `preset_id`로 전달하면 필드를 직접 나열하지 않고도 작동하는 템플릿을 얻을 수 있습니다. 프리셋은 정적 구성이며 데이터베이스 행이 아니므로 API를 통해 생성, 편집 또는 삭제할 수 없습니다.

`GET /api/v1/presets`

### 매개변수

| 이름 | 위치 | 유형 | 설명 |
| --- | --- | --- | --- |
| category | query, 선택 사항 | string | 하나의 카테고리로 필터링합니다. 생략하면 모든 카테고리를 나열합니다. |
| limit | query, 선택 사항 | integer | 1–100. 기본값 50. |
| page_token | query, 선택 사항 | string | 이전 응답의 next_page_token 에서 가져온 불투명 커서입니다. |

### 가능한 오류

- `missing_api_key` / `invalid_api_key` / `plan_required` — [오류 처리](/developers/guides/errors)를 참조하세요.
- `invalid_parameter` — 잘못된 `limit` 또는 `page_token`.

## 필드 목록 및 생성

`fields`는 제품 UI에서 "일치 규칙"이라고 부르는 것의 v1-public 이름입니다. 각 출력 열당 하나의 필드이며, 추출이 출력하는 순서대로 정렬됩니다. `GET`은 템플릿의 모든 필드를 `sort_order`로 이미 정렬된 상태로 반환합니다. `POST`는 새 필드를 끝에 추가합니다.

`GET POST /api/v1/templates/{id}/fields`

### 매개변수

| 이름 | 위치 | 유형 | 설명 |
| --- | --- | --- | --- |
| id | path | integer | 이 필드들이 속한 템플릿입니다. |
| name | body (JSON), POST 전용 | string | 필수. 이 템플릿 내에서 고유해야 합니다. 아래 오류를 참조하세요. |
| format_requirement | body (JSON), POST 전용 | string, 선택 사항 | 예상 값 형식에 대한 자유 텍스트 힌트입니다. |

### 가능한 오류

- `missing_api_key` / `invalid_api_key` / `plan_required` — [오류 처리](/developers/guides/errors)를 참조하세요.
- `template_not_found`
- `missing_parameter` (`param: "name"`) — POST 전용.
- `duplicate_field_name` — 이 `name`을 가진 필드가 이미 이 템플릿에 존재합니다.
- `internal_error`

## 필드 업데이트 및 삭제

`PUT`은 필드 이름을 변경하고 `format_requirement`를 교체합니다. 전체 교체이므로 부분 패치가 아니며, 하나만 변경되더라도 두 값을 모두 포함해야 합니다. `DELETE`는 필드를 제거합니다.

`PUT DELETE /api/v1/templates/{id}/fields/{field_id}`

### 매개변수

| 이름 | 위치 | 유형 | 설명 |
| --- | --- | --- | --- |
| id | path | integer | 이 필드가 속한 템플릿입니다. |
| field_id | path | integer | 업데이트 또는 삭제할 필드입니다. |
| name | body (JSON), PUT 전용 | string | 필수. 새 이름입니다. |
| format_requirement | body (JSON), PUT 전용 | string, 선택 사항 | 새 형식 힌트입니다. 생략하면 빈 문자열로 설정되며, 변경되지 않은 상태로 남지 않습니다. |

### 가능한 오류

- `missing_api_key` / `invalid_api_key` / `plan_required` — [오류 처리](/developers/guides/errors)를 참조하세요.
- `template_not_found` — 템플릿이 존재하지 않거나 소유하지 않은 경우, 또는 `field_id`가 이 템플릿에 없는 경우입니다.
- `missing_parameter` (`param: "name"`) — PUT 전용입니다.
- `duplicate_field_name` — PUT 전용이며, 이 템플릿의 다른 필드가 이미 사용 중인 이름으로 변경하려는 경우입니다.
- `internal_error`

## 필드 순서 변경

필드 순서를 명시적으로 설정하여 `line_items` 및 Excel/Word 내보내기에서 출력 열 순서를 결정합니다. 목록에 있는 ID 중 이 템플릿에 속하지 않는 ID는 전체 요청을 거부하지 않고 자동으로 무시됩니다.

`PATCH /api/v1/templates/{id}/fields/order`

### 매개변수

| 이름 | 위치 | 유형 | 설명 |
| --- | --- | --- | --- |
| id | path | integer | 순서를 변경할 템플릿입니다. |
| field_ids | body (JSON) | array of integers | 이 템플릿의 모든 필드 ID를 원하는 순서대로 입력합니다. 필수입니다. |

### 가능한 오류

- `missing_api_key` / `invalid_api_key` / `plan_required` — [오류 처리](/developers/guides/errors)를 참조하세요.
- `template_not_found`
- `invalid_parameter` (`param: "field_ids"`) — 정수 목록이 아닙니다.
- `internal_error`

## Code Examples

### 템플릿 목록

GET /api/v1/templates

**cURL**

```bash
curl https://imagetotable.ai/api/v1/templates \
  -H "Authorization: Bearer $API_KEY"
```

**Python**

```python
import os
import requests

response = requests.get(
    "https://imagetotable.ai/api/v1/templates",
    headers={"Authorization": f"Bearer {os.environ['API_KEY']}"},
)
print(response.json())
```

**Javascript**

```javascript
const response = await fetch("https://imagetotable.ai/api/v1/templates", {
  headers: { "Authorization": `Bearer ${process.env.API_KEY}` },
});
console.log(await response.json());
```

### 응답

```json
{
  "data": [
    {
      "id": 42,
      "name": "Invoice Template",
      "created_at": "2026-06-01T10:00:00+00:00",
      "fields": [
        {
          "id": 101,
          "name": "invoice_number",
          "format_requirement": "",
          "sort_order": 1,
          "template_id": 42,
          "created_at": "2026-06-01T10:00:00+00:00"
        },
        {
          "id": 102,
          "name": "invoice_date",
          "format_requirement": "YYYY-MM-DD",
          "sort_order": 2,
          "template_id": 42,
          "created_at": "2026-06-01T10:00:00+00:00"
        }
      ]
    }
  ],
  "has_more": false,
  "next_page_token": null
}
```

### 템플릿 만들기 — 처음부터

POST /api/v1/templates

두 가지 방법 중 첫 번째 — `name`만 필요하며, 아직 필드는 없습니다. 이후 [필드 목록 및 생성](#list-and-create-fields)으로 필드를 추가하거나, 같은 호출에서 `base_template_id`를 통해 다른 템플릿의 필드를 복제할 수 있습니다.

**cURL**

```bash
curl -X POST https://imagetotable.ai/api/v1/templates \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"name": "My Invoice Template"}'
```

**Python**

```python
import os
import requests

response = requests.post(
    "https://imagetotable.ai/api/v1/templates",
    headers={"Authorization": f"Bearer {os.environ['API_KEY']}"},
    json={"name": "My Invoice Template"},
)
print(response.json())
```

**Javascript**

```javascript
const response = await fetch("https://imagetotable.ai/api/v1/templates", {
  method: "POST",
  headers: {
    "Authorization": `Bearer ${process.env.API_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({ name: "My Invoice Template" }),
});
console.log(await response.json());
```

### 응답

```json
{
  "template": {
    "id": 44,
    "name": "My Invoice Template",
    "created_at": "2026-07-16T09:00:00+00:00",
    "fields": []
  }
}
```

### 템플릿 생성 — 프리셋에서

POST /api/v1/templates

**cURL**

```bash
curl -X POST https://imagetotable.ai/api/v1/templates \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"preset_id": "finance_invoice_general"}'
```

**Python**

```python
import os
import requests

response = requests.post(
    "https://imagetotable.ai/api/v1/templates",
    headers={"Authorization": f"Bearer {os.environ['API_KEY']}"},
    json={"preset_id": "finance_invoice_general"},
)
print(response.json())
```

**Javascript**

```javascript
const response = await fetch("https://imagetotable.ai/api/v1/templates", {
  method: "POST",
  headers: {
    "Authorization": `Bearer ${process.env.API_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({ preset_id: "finance_invoice_general" }),
});
console.log(await response.json());
```

### 응답

```json
{
  "template": {
    "id": 43,
    "name": "Invoice",
    "created_at": "2026-07-16T09:00:00+00:00",
    "fields": [
      {
        "id": 201,
        "name": "Merchant Name",
        "format_requirement": "String",
        "sort_order": 1,
        "template_id": 43,
        "created_at": "2026-07-16T09:00:00+00:00"
      }
    ]
  }
}
```

### 템플릿 삭제

DELETE /api/v1/templates/{id}

**cURL**

```bash
curl -X DELETE https://imagetotable.ai/api/v1/templates/43 \
  -H "Authorization: Bearer $API_KEY"
```

**Python**

```python
import os
import requests

response = requests.delete(
    "https://imagetotable.ai/api/v1/templates/43",
    headers={"Authorization": f"Bearer {os.environ['API_KEY']}"},
)
print(response.status_code)
```

**Javascript**

```javascript
const response = await fetch("https://imagetotable.ai/api/v1/templates/43", {
  method: "DELETE",
  headers: { "Authorization": `Bearer ${process.env.API_KEY}` },
});
console.log(response.status);
```

### 응답

204 No Content — 본문 없음.

### 프리셋 목록

GET /api/v1/presets

**cURL**

```bash
curl "https://imagetotable.ai/api/v1/presets?category=Finance%20%26%20Accounting" \
  -H "Authorization: Bearer $API_KEY"
```

**Python**

```python
import os
import requests

response = requests.get(
    "https://imagetotable.ai/api/v1/presets",
    headers={"Authorization": f"Bearer {os.environ['API_KEY']}"},
    params={"category": "Finance & Accounting"},
)
print(response.json())
```

**Javascript**

```javascript
const url = new URL("https://imagetotable.ai/api/v1/presets");
url.searchParams.set("category", "Finance & Accounting");

const response = await fetch(url, {
  headers: { "Authorization": `Bearer ${process.env.API_KEY}` },
});
console.log(await response.json());
```

### 응답

```json
{
  "data": [
    {
      "id": "finance_invoice_general",
      "category": "Finance & Accounting",
      "name": "Invoice",
      "fields": [
        {"name": "Invoice Number", "format_requirement": "DocumentNumber"},
        {"name": "Invoice Date", "format_requirement": "YYYY-MM-DD"},
        {"name": "Total Amount", "format_requirement": "Number"}
      ]
    }
  ],
  "has_more": false,
  "next_page_token": null
}
```

### 필드 목록 / 생성

POST /api/v1/templates/{id}/fields

**cURL**

```bash
curl -X POST https://imagetotable.ai/api/v1/templates/42/fields \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"name": "vendor_name", "format_requirement": "String"}'
```

**Python**

```python
import os
import requests

response = requests.post(
    "https://imagetotable.ai/api/v1/templates/42/fields",
    headers={"Authorization": f"Bearer {os.environ['API_KEY']}"},
    json={"name": "vendor_name", "format_requirement": "String"},
)
print(response.json())
```

**Javascript**

```javascript
const response = await fetch("https://imagetotable.ai/api/v1/templates/42/fields", {
  method: "POST",
  headers: {
    "Authorization": `Bearer ${process.env.API_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({ name: "vendor_name", format_requirement: "String" }),
});
console.log(await response.json());
```

### 응답

```json
{
  "field": {
    "id": 103,
    "name": "vendor_name",
    "format_requirement": "String",
    "sort_order": 103,
    "template_id": 42,
    "created_at": "2026-07-16T09:05:00+00:00"
  }
}
```

### 필드 업데이트

PUT /api/v1/templates/{id}/fields/{field_id}

**cURL**

```bash
curl -X PUT https://imagetotable.ai/api/v1/templates/42/fields/103 \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"name": "vendor_name", "format_requirement": "Company name, no suffix"}'
```

**Python**

```python
import os
import requests

response = requests.put(
    "https://imagetotable.ai/api/v1/templates/42/fields/103",
    headers={"Authorization": f"Bearer {os.environ['API_KEY']}"},
    json={"name": "vendor_name", "format_requirement": "Company name, no suffix"},
)
print(response.json())
```

**Javascript**

```javascript
const response = await fetch("https://imagetotable.ai/api/v1/templates/42/fields/103", {
  method: "PUT",
  headers: {
    "Authorization": `Bearer ${process.env.API_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({ name: "vendor_name", format_requirement: "Company name, no suffix" }),
});
console.log(await response.json());
```

### 응답

```json
{
  "field": {
    "id": 103,
    "name": "vendor_name",
    "format_requirement": "Company name, no suffix",
    "sort_order": 103,
    "template_id": 42,
    "created_at": "2026-07-16T09:05:00+00:00"
  }
}
```

### 필드 삭제

DELETE /api/v1/templates/{id}/fields/{field_id}

**cURL**

```bash
curl -X DELETE https://imagetotable.ai/api/v1/templates/42/fields/103 \
  -H "Authorization: Bearer $API_KEY"
```

**Python**

```python
import os
import requests

response = requests.delete(
    "https://imagetotable.ai/api/v1/templates/42/fields/103",
    headers={"Authorization": f"Bearer {os.environ['API_KEY']}"},
)
print(response.status_code)
```

**Javascript**

```javascript
const response = await fetch("https://imagetotable.ai/api/v1/templates/42/fields/103", {
  method: "DELETE",
  headers: { "Authorization": `Bearer ${process.env.API_KEY}` },
});
console.log(response.status);
```

### 응답

204 No Content — 본문 없음.

### 필드 순서 변경

PATCH /api/v1/templates/{id}/fields/order

**cURL**

```bash
curl -X PATCH https://imagetotable.ai/api/v1/templates/42/fields/order \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"field_ids": [102, 101, 103]}'
```

**Python**

```python
import os
import requests

response = requests.patch(
    "https://imagetotable.ai/api/v1/templates/42/fields/order",
    headers={"Authorization": f"Bearer {os.environ['API_KEY']}"},
    json={"field_ids": [102, 101, 103]},
)
print(response.json())
```

**Javascript**

```javascript
const response = await fetch("https://imagetotable.ai/api/v1/templates/42/fields/order", {
  method: "PATCH",
  headers: {
    "Authorization": `Bearer ${process.env.API_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({ field_ids: [102, 101, 103] }),
});
console.log(await response.json());
```

### 응답

```json
{
  "data": [
    {"id": 102, "name": "invoice_date", "format_requirement": "YYYY-MM-DD", "sort_order": 1, "template_id": 42, "created_at": "2026-06-01T10:00:00+00:00"},
    {"id": 101, "name": "invoice_number", "format_requirement": "", "sort_order": 2, "template_id": 42, "created_at": "2026-06-01T10:00:00+00:00"},
    {"id": 103, "name": "vendor_name", "format_requirement": "Company name, no suffix", "sort_order": 3, "template_id": 42, "created_at": "2026-07-16T09:05:00+00:00"}
  ],
  "has_more": false,
  "next_page_token": null
}
```

---

Source: https://imagetotable.ai/ko/developers/reference/templates-fields
