apick-api 3.2.0 → 3.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,299 +1,405 @@
1
- <div align="center">
2
-
3
- # APICK API for Node.js
4
-
5
- **에이픽 데이터·AI·이미지 API를 API 키 하나로 호출하는 공식 Node.js SDK**
6
-
7
- **Official zero-dependency Node.js SDK for APICK data, AI, and image APIs**
8
-
9
- [![npm](https://img.shields.io/npm/v/apick-api?color=%230a7cff&label=npm%20apick-api)](https://www.npmjs.com/package/apick-api)
10
- [![Node.js](https://img.shields.io/badge/Node.js-18%2B-339933)](https://nodejs.org/)
11
- [![License: MIT](https://img.shields.io/badge/license-MIT-green)](LICENSE)
12
-
13
- [한국어 가이드](docs/guide.ko.md) · [English guide](docs/guide.en.md) · [APICK](https://apick.app) · [API 문서](https://apick.app/dev_guide)
14
-
15
- </div>
16
-
17
- ## 빠른 시작 / Quick start
18
-
19
- ```bash
20
- npm install apick-api
21
- ```
22
-
23
- ES modules:
24
-
25
- ```js
26
- import { ApickClient } from 'apick-api';
27
-
28
- const apick = new ApickClient(process.env.APICK_API_KEY);
29
- const { data, meta } = await apick.businessDetails('439-87-00761');
30
-
31
- console.log(data);
32
- console.log(`사용 포인트: ${meta.cost}`);
33
- ```
34
-
35
- CommonJS:
36
-
37
- ```js
38
- const { ApickClient } = require('apick-api');
39
-
40
- const apick = new ApickClient(process.env.APICK_API_KEY);
41
- const result = await apick.trackParcelAuto('123456789012');
42
- console.log(result.data);
43
- ```
44
-
45
- 인증키는 [apick.app](https://apick.app) 가입 후 마이페이지에서 발급할 수 있습니다.
46
- Get an API key from your account page after signing up at [apick.app](https://apick.app).
47
-
48
- 마이페이지의 허용 IP가 공란이면 제한 없이 호출할 수 있습니다. 제한하려면 APICK에 도착하는 공인 IPv4를 단일 주소 또는 CIDR(`/32` 등)로 등록하세요. 저장 즉시 반영되며 별도 동기화는 필요하지 않습니다.
49
- Leave the allowed-IP list blank for unrestricted access. To restrict access, register the public IPv4 address seen by APICK as an exact address or CIDR such as `/32`. Changes apply immediately with no separate synchronization.
50
-
51
- ## 제공 서비스 / Included services
52
-
53
- | Method | APICK service | Result |
54
- | --- | --- | --- |
55
- | `businessDetails(businessNumber)` | 사업자 정보 조회 / Business details | JSON |
56
- | `ventureBusiness(businessNumber)` | 벤처기업 정보 / Venture business data | JSON |
57
- | `trackParcel(carrier, trackingNumber)` | 택배 배송조회 / Parcel tracking | JSON |
58
- | `trackParcelAuto(trackingNumber)` | 택배사 자동판별 배송조회 / Auto carrier tracking | JSON |
59
- | `validateEmail(email)` | 이메일 유효성 / Email validation | JSON |
60
- | `validatePhone(number)` | 전화번호 유효성 / Phone validation | JSON |
61
- | `holidays(year, month)` | 대한민국 공휴일 / Korean holidays | JSON |
62
- | `searchAddress(query, options)` | 도로명주소 검색 / Road address search | JSON |
63
- | `ocr(image, options)` | 이미지 OCR / Image OCR | JSON |
64
- | `dnsLookup(domain)` | DNS 조회 / DNS lookup | JSON |
65
- | `geolocate(address)` | 도메인·IP 위치 / Domain and IP location | JSON |
66
- | `whois(address)` | WHOIS 조회 / WHOIS lookup | JSON |
67
- | `googleSearch(keyword, options)` | 웹 검색 / Web search | JSON |
68
- | `googleImageSearch(keyword, options)` | 이미지 검색 / Image search | JSON |
69
- | `screenshot(url)` | 웹페이지 화면캡처 / Web screenshot | Binary |
70
- | `createTtsJob(text, options)` | 한국어 내레이션 작업 접수 / Create TTS job | JSON |
71
- | `getTtsJob(jobId)` | TTS 작업 상태 / TTS job status | JSON |
72
- | `cancelTtsJob(jobId)` | 대기·생성 중 TTS 작업 취소 / Cancel waiting or processing TTS job | JSON |
73
- | `downloadTtsResult(jobId)` | TTS 결과 1회 다운로드 / One-time TTS result | MP3 |
74
- | `downloadTtsSubtitles(jobId)` | TTS 자막 1회 다운로드 / One-time TTS subtitles | ASS |
75
- | `getTtsQuality(jobId)` | 발화별 검수·후보 이력 / Utterance quality and candidates | JSON |
76
- | `retryTtsJob(jobId, utteranceIds, idempotencyKey)` | 같은 작업의 국소 복구 / Idempotent local recovery | JSON |
77
- | `downloadTtsCandidate(jobId, candidateId)` | 검수 후보 청취 / Candidate audio | WAV |
78
- | `htmlToPdf(html, options)` | HTML→PDF | Binary |
79
- | `jsonToExcel(data, options)` | JSON→Excel | Binary |
80
- | `summarize(text)` | 텍스트 요약 / Text summarization | JSON |
81
- | `polish(text)` | 텍스트 다듬기 / Text polishing | JSON |
82
- | `generateImages(prompt, options)` | 이미지 생성 / Image generation | JSON |
83
- | `editImages(image, prompt, options)` | 이미지 편집 / Image editing | JSON |
84
- | `createImageGenerationJob(prompt, options)` | 대량 이미지 생성 작업 / Batch generation job | JSON |
85
- | `createImageEditJob(image, prompt, options)` | 대량 이미지 편집 작업 / Batch edit job | JSON |
86
- | `getImageJob(jobId)` | 이미지 작업 상태 조회 / Job status | JSON |
87
- | `downloadImageJobImage(jobId, index)` | 개별 결과 / Individual result | Binary |
88
- | `downloadImageJobArchive(jobId)` | ZIP 결과 / ZIP archive | Binary |
89
-
90
- ## JSON 결과 / JSON results
91
-
92
- JSON API는 실제 응답과 과금 메타데이터를 분리해 반환합니다.
93
- JSON APIs separate the service result from billing metadata.
94
-
95
- ```js
96
- const result = await apick.searchAddress('가산디지털로', { page: 1 });
97
-
98
- console.log(result.data);
99
- console.log(result.meta);
100
- // { cost: number | null, durationMs: number | null }
101
- ```
102
-
103
- ## 파일 입력 / File input
104
-
105
- ## 이미지 생성·편집 / Image generation and editing
106
-
107
- 이미지는 장당 25포인트이며 동기는 1~4장, 작업형 API는 최대 50장까지 지원합니다. 요청이 접수되면 전체 금액을 먼저 차감하고, 생성에 실패한 이미지가 있으면 해당 장수만큼 즉시 환급합니다. 접수된 작업은 취소할 수 없으며 결과는 완료 후 24시간 동안 반복 다운로드할 수 있습니다.
108
-
109
- Images cost 25 points each. Synchronous calls support 1–4 images and job calls support up to 50. The full amount is deducted when a request is accepted, and failed images are refunded immediately. Accepted jobs cannot be cancelled. Completed results remain downloadable for 24 hours.
110
-
111
- ```js
112
- const made = await apick.generateImages("따뜻한 조명의 미니멀 제품 사진", {
113
- imageCount: 2, size: "1024x1024", outputFormat: "webp",
114
- idempotencyKey: "catalog-cover-20260905"
115
- });
116
-
117
- const referenced = await apick.generateImages("구도와 제품 형태는 유지하고 여름 해변 분위기로", {
118
- referenceImage: "./reference.png",
119
- referenceFilename: "reference.png",
120
- referenceContentType: "image/png"
121
- });
122
-
123
- const edited = await apick.editImages("./source.png", "컵 색상을 파란색으로 변경", {
124
- outputFormat: "png"
125
- });
126
-
127
- const queued = await apick.createImageGenerationJob("여행 포스터 시안", { imageCount: 20 });
128
- const job = await apick.getImageJob(queued.data.job_id);
129
- const image = await apick.downloadImageJobImage(job.data.job_id, 0);
130
- await image.save("./result.png");
131
- ```
132
-
133
- PNG·JPEG·WebP 출력, 투명 배경 미리보기(PNG/WebP), 5개 표준 크기(`1024x1024`, `1536x1024`, `1024x1536`, `1152x864`, `864x1152`)를 지원합니다. 입력 프롬프트는 최대 28,000자입니다. `idempotencyKey`는 네트워크 재전송 때 중복 생성과 중복 과금을 막는 8~128자의 요청 식별자이며, 같은 작업을 다시 보낼 때 같은 값을 사용합니다. 자동 재시도는 하지 않습니다.
134
-
135
- PNG, JPEG, and WebP outputs, transparent-background previews for PNG/WebP, and five standard sizes are supported. Prompts are limited to 28,000 characters. `idempotencyKey` identifies the same request during network retransmission to prevent duplicate generation and billing. Requests are never retried automatically.
136
-
137
- OCR은 PNG/JPEG 파일 경로, `Blob`, `ArrayBuffer`, `Uint8Array`를 받습니다. 최대 크기는 50MB입니다.
138
- OCR accepts a PNG/JPEG file path, `Blob`, `ArrayBuffer`, or `Uint8Array`, up to 50MB.
139
-
140
- ```js
141
- const result = await apick.ocr('./receipt.jpg');
142
- console.log(result.data.result.full_text);
143
- ```
144
-
145
- 브라우저 또는 메모리 데이터:
146
-
147
- ```js
148
- const result = await apick.ocr(imageBytes, {
149
- filename: 'receipt.png',
150
- contentType: 'image/png'
151
- });
152
- ```
153
-
154
- ## 파일 결과 / Binary results
155
-
156
- 파일을 반환하는 메서드는 `ApickBinaryResult`를 반환합니다.
157
- Methods producing files return an `ApickBinaryResult`.
158
-
159
- ```js
160
- const pdf = await apick.htmlToPdf('<h1>월간 보고서</h1>', {
161
- pagination: true
162
- });
163
-
164
- console.log(pdf.contentType, pdf.size, pdf.meta.cost);
165
- await pdf.save('./report.pdf');
166
- ```
167
-
1
+ <div align="center">
2
+
3
+ # APICK API for Node.js
4
+
5
+ **에이픽 데이터·AI·이미지 API를 API 키 하나로 호출하는 공식 Node.js SDK**
6
+
7
+ **Official zero-dependency Node.js SDK for APICK data, AI, and image APIs**
8
+
9
+ [![npm](https://img.shields.io/npm/v/apick-api?color=%230a7cff&label=npm%20apick-api)](https://www.npmjs.com/package/apick-api)
10
+ [![Node.js](https://img.shields.io/badge/Node.js-18%2B-339933)](https://nodejs.org/)
11
+ [![License: MIT](https://img.shields.io/badge/license-MIT-green)](LICENSE)
12
+
13
+ [한국어 가이드](docs/guide.ko.md) · [English guide](docs/guide.en.md) · [APICK](https://apick.app) · [API 문서](https://apick.app/dev_guide)
14
+
15
+ </div>
16
+
17
+ ## 빠른 시작 / Quick start
18
+
19
+ 본문이 있는 요청은 `multipart/form-data`로 전송됩니다. 배열·객체도 개별 폼 항목으로 전달하고 SDK가 boundary를 자동 설정합니다. 기존 메서드와 JSON·파일 응답 형식은 유지됩니다.
20
+
21
+ Requests with a body use `multipart/form-data`, including indexed fields for nested values. The SDK sets the boundary automatically; method signatures and JSON/file results remain unchanged.
22
+
23
+ ```bash
24
+ npm install apick-api
25
+ ```
26
+
27
+ ES modules:
28
+
29
+ ```js
30
+ import { ApickClient } from 'apick-api';
31
+
32
+ const apick = new ApickClient(process.env.APICK_API_KEY);
33
+ const { data, meta } = await apick.businessDetails('439-87-00761');
34
+
35
+ console.log(data);
36
+ console.log(`사용 포인트: ${meta.cost}`);
37
+ ```
38
+
39
+ CommonJS:
40
+
41
+ ```js
42
+ const { ApickClient } = require('apick-api');
43
+
44
+ const apick = new ApickClient(process.env.APICK_API_KEY);
45
+ const result = await apick.trackParcelAuto('123456789012');
46
+ console.log(result.data);
47
+ ```
48
+
49
+ 인증키는 [apick.app](https://apick.app) 가입 후 마이페이지에서 발급할 수 있습니다.
50
+ Get an API key from your account page after signing up at [apick.app](https://apick.app).
51
+
52
+ 마이페이지의 허용 IP가 공란이면 제한 없이 호출할 수 있습니다. 제한하려면 APICK에 도착하는 공인 IPv4를 단일 주소 또는 CIDR(`/32` 등)로 등록하세요. 저장 즉시 반영되며 별도 동기화는 필요하지 않습니다.
53
+ Leave the allowed-IP list blank for unrestricted access. To restrict access, register the public IPv4 address seen by APICK as an exact address or CIDR such as `/32`. Changes apply immediately with no separate synchronization.
54
+
55
+ ## 제공 서비스 / Included services
56
+
57
+ | Method | APICK service | Result |
58
+ | --- | --- | --- |
59
+ | `businessDetails(businessNumber)` | 사업자 정보 조회 / Business details | JSON |
60
+ | `ventureBusiness(businessNumber)` | 벤처기업 정보 / Venture business data | JSON |
61
+ | `trackParcel(carrier, trackingNumber)` | 택배 배송조회 / Parcel tracking | JSON |
62
+ | `trackParcelAuto(trackingNumber)` | 택배사 자동판별 배송조회 / Auto carrier tracking | JSON |
63
+ | `validateEmail(email)` | 이메일 유효성 / Email validation | JSON |
64
+ | `validatePhone(number)` | 전화번호 유효성 / Phone validation | JSON |
65
+ | `holidays(year, month)` | 대한민국 공휴일 / Korean holidays | JSON |
66
+ | `searchAddress(query, options)` | 도로명주소 검색 / Road address search | JSON |
67
+ | `ocr(image, options)` | 이미지 OCR / Image OCR | JSON |
68
+ | `dnsLookup(domain)` | DNS 조회 / DNS lookup | JSON |
69
+ | `geolocate(address)` | 도메인·IP 위치 / Domain and IP location | JSON |
70
+ | `whois(address)` | WHOIS 조회 / WHOIS lookup | JSON |
71
+ | `googleSearch(keyword, options)` | 웹 검색 / Web search | JSON |
72
+ | `googleImageSearch(keyword, options)` | 이미지 검색 / Image search | JSON |
73
+ | `screenshot(url)` | 웹페이지 화면캡처 / Web screenshot | Binary |
74
+ | `createTtsJob(text, options)` | 한국어 내레이션 작업 접수 / Create TTS job | JSON |
75
+ | `getTtsJob(jobId)` | TTS 작업 상태 / TTS job status | JSON |
76
+ | `cancelTtsJob(jobId)` | 대기·생성 중 TTS 작업 취소 / Cancel waiting or processing TTS job | JSON |
77
+ | `downloadTtsResult(jobId)` | TTS 결과 1회 다운로드 / One-time TTS result | MP3 |
78
+ | `downloadTtsSubtitles(jobId)` | TTS 자막 1회 다운로드 / One-time TTS subtitles | ASS |
79
+ | `getTtsQuality(jobId)` | 발화별 검수·후보 이력 / Utterance quality and candidates | JSON |
80
+ | `retryTtsJob(jobId, utteranceIds, idempotencyKey)` | 같은 작업의 국소 복구 / Idempotent local recovery | JSON |
81
+ | `downloadTtsCandidate(jobId, candidateId)` | 검수 후보 청취 / Candidate audio | WAV |
82
+ | `htmlToPdf(html, options)` | HTML→PDF | Binary |
83
+ | `jsonToExcel(data, options)` | JSON→Excel | Binary |
84
+ | `summarize(text)` | 텍스트 요약 / Text summarization | JSON |
85
+ | `polish(text)` | 텍스트 다듬기 / Text polishing | JSON |
86
+ | `generateImages(prompt, options)` | 이미지 생성 / Image generation | JSON |
87
+ | `editImages(image, prompt, options)` | 이미지 편집 / Image editing | JSON |
88
+ | `createImageGenerationJob(prompt, options)` | 대량 이미지 생성 작업 / Batch generation job | JSON |
89
+ | `createImageEditJob(image, prompt, options)` | 대량 이미지 편집 작업 / Batch edit job | JSON |
90
+ | `getImageJob(jobId)` | 이미지 작업 상태 조회 / Job status | JSON |
91
+ | `downloadImageJobImage(jobId, index)` | 개별 결과 / Individual result | Binary |
92
+ | `downloadImageJobArchive(jobId)` | ZIP 결과 / ZIP archive | Binary |
93
+ | `requestEmployment(input)` / `getEmployment(transactionId)` | 재직·보험료 확인 / Employment & insurance premium check | JSON |
94
+ | `requestPersonalIncome(input)` / `getPersonalIncome(transactionId)` | 금융소득(이자·배당) 조회 / Financial income (interest/dividend) | JSON |
95
+ | `requestNpsJoinHistory(input)` / `getNpsJoinHistory(transactionId)` | 국민연금 가입내역조회 / National Pension join history | JSON |
96
+ | `requestDrivingLicense(input)` / `getDrivingLicense(transactionId)` | 운전면허 조회 / Driver's license check | JSON |
97
+ | `requestHealthCheckup(input)` / `getHealthCheckup(transactionId)` | 국가 건강검진 결과 조회 / National health checkup results | JSON |
98
+
99
+ ## JSON 결과 / JSON results
100
+
101
+ JSON API는 실제 응답과 과금 메타데이터를 분리해 반환합니다.
102
+ JSON APIs separate the service result from billing metadata.
103
+
104
+ ```js
105
+ const result = await apick.searchAddress('가산디지털로', { page: 1 });
106
+
107
+ console.log(result.data);
108
+ console.log(result.meta);
109
+ // { cost: number | null, durationMs: number | null }
110
+ ```
111
+
112
+ ## 파일 입력 / File input
113
+
114
+ ## 이미지 생성·편집 / Image generation and editing
115
+
116
+ 이미지는 장당 25포인트이며 동기는 1~4장, 작업형 API는 최대 50장까지 지원합니다. 요청이 접수되면 전체 금액을 먼저 차감하고, 생성에 실패한 이미지가 있으면 해당 장수만큼 즉시 환급합니다. 접수된 작업은 취소할 수 없으며 결과는 완료 후 24시간 동안 반복 다운로드할 수 있습니다.
117
+
118
+ Images cost 25 points each. Synchronous calls support 1–4 images and job calls support up to 50. The full amount is deducted when a request is accepted, and failed images are refunded immediately. Accepted jobs cannot be cancelled. Completed results remain downloadable for 24 hours.
119
+
120
+ ```js
121
+ const made = await apick.generateImages("따뜻한 조명의 미니멀 제품 사진", {
122
+ imageCount: 2, size: "1024x1024", outputFormat: "webp",
123
+ idempotencyKey: "catalog-cover-20260905"
124
+ });
125
+
126
+ const referenced = await apick.generateImages("구도와 제품 형태는 유지하고 여름 해변 분위기로", {
127
+ referenceImage: "./reference.png",
128
+ referenceFilename: "reference.png",
129
+ referenceContentType: "image/png"
130
+ });
131
+
132
+ const edited = await apick.editImages("./source.png", "컵 색상을 파란색으로 변경", {
133
+ outputFormat: "png"
134
+ });
135
+
136
+ const queued = await apick.createImageGenerationJob("여행 포스터 시안", { imageCount: 20 });
137
+ const job = await apick.getImageJob(queued.data.job_id);
138
+ const image = await apick.downloadImageJobImage(job.data.job_id, 0);
139
+ await image.save("./result.png");
140
+ ```
141
+
142
+ PNG·JPEG·WebP 출력, 투명 배경 미리보기(PNG/WebP), 5개 표준 크기(`1024x1024`, `1536x1024`, `1024x1536`, `1152x864`, `864x1152`)를 지원합니다. 입력 프롬프트는 최대 28,000자입니다. `idempotencyKey`는 네트워크 재전송 때 중복 생성과 중복 과금을 막는 8~128자의 요청 식별자이며, 같은 작업을 다시 보낼 때 같은 값을 사용합니다. 자동 재시도는 하지 않습니다.
143
+
144
+ PNG, JPEG, and WebP outputs, transparent-background previews for PNG/WebP, and five standard sizes are supported. Prompts are limited to 28,000 characters. `idempotencyKey` identifies the same request during network retransmission to prevent duplicate generation and billing. Requests are never retried automatically.
145
+
146
+ OCR은 PNG/JPEG 파일 경로, `Blob`, `ArrayBuffer`, `Uint8Array`를 받습니다. 최대 크기는 50MB입니다.
147
+ OCR accepts a PNG/JPEG file path, `Blob`, `ArrayBuffer`, or `Uint8Array`, up to 50MB.
148
+
149
+ ```js
150
+ const result = await apick.ocr('./receipt.jpg');
151
+ console.log(result.data.result.full_text);
152
+ ```
153
+
154
+ 브라우저 또는 메모리 데이터:
155
+
156
+ ```js
157
+ const result = await apick.ocr(imageBytes, {
158
+ filename: 'receipt.png',
159
+ contentType: 'image/png'
160
+ });
161
+ ```
162
+
163
+ ## 파일 결과 / Binary results
164
+
165
+ 파일을 반환하는 메서드는 `ApickBinaryResult`를 반환합니다.
166
+ Methods producing files return an `ApickBinaryResult`.
167
+
168
+ ```js
169
+ const pdf = await apick.htmlToPdf('<h1>월간 보고서</h1>', {
170
+ pagination: true
171
+ });
172
+
173
+ console.log(pdf.contentType, pdf.size, pdf.meta.cost);
174
+ await pdf.save('./report.pdf');
175
+ ```
176
+
177
+ ```js
178
+ const excel = await apick.jsonToExcel(
179
+ [{ name: 'Kim', score: 95 }, { name: 'Lee', score: 88 }],
180
+ { sheetName: 'Scores' }
181
+ );
182
+
183
+ await excel.save('./scores.xlsx');
184
+ ```
185
+
186
+ `ApickBinaryResult` provides `bytes`, `size`, `filename`, `contentType`, `meta`, `toArrayBuffer()`, `toBlob()`, and `save(path)`.
187
+
188
+ ## 비동기 TTS Jobs / Asynchronous TTS Jobs
189
+
190
+ 기존 동기 TTS는 종료되었습니다. 한국어 내레이션은 작업을 접수하고 `completed`가 될 때까지 2~5초 간격으로 상태를 확인한 뒤 MP3 결과를 한 번만 내려받습니다.
191
+
192
+ The legacy synchronous TTS API has retired. Create a Korean narration job, poll every 2–5 seconds until it is `completed`, then download the MP3 result once.
193
+
194
+ TTS supports 16 voice IDs. Use `TTS_VOICE_IDS` and the developer guide for the current list.
195
+
196
+ `v2_ann_m_30s_01`, `v2_ann_m_30s_02`, `v2_ann_m_30s_04`, `v2_ann_m_30s_05`, `v2_ann_f_30s_01`, `v2_ann_f_30s_02`, `v2_ann_f_30s_03`, `v2_ann_f_30s_04`, `v2_ann_f_30s_05`, `v2_m_teen_01`, `v2_m_young_01`, `v2_m_mid_01`, `v2_m_senior_01`, `v2_f_teen_01`, `v2_f_young_01`, `v2_f_senior_01`
197
+
198
+ ```js
199
+ const created = await apick.createTtsJob('오늘의 이야기를 시작합니다.', {
200
+ voiceId: 'v2_ann_m_30s_01'
201
+ });
202
+ const jobId = created.data.job_id;
203
+
204
+ let job;
205
+ do {
206
+ await new Promise(resolve => setTimeout(resolve, 3000));
207
+ job = await apick.getTtsJob(jobId);
208
+ } while (job.data.status === 'waiting' || job.data.status === 'processing');
209
+
210
+ if (job.data.status === 'completed') {
211
+ const result = await apick.downloadTtsResult(jobId);
212
+ await result.save(`./${jobId}.mp3`);
213
+ const subtitles = await apick.downloadTtsSubtitles(jobId);
214
+ await subtitles.save(`./${jobId}.ass`);
215
+ }
216
+ ```
217
+
218
+ 접수 성공 시 과금되며 취소해도 환불되지 않습니다. 취소는 `waiting` 또는 `processing` 상태에서 가능하고, MP3와 ASS 자막은 각각 한 번만 내려받을 수 있습니다. 각 다운로드가 시작되면 해당 서버 원본이 즉시 폐기되므로 전송 중단 시에도 다시 받을 수 없습니다.
219
+
220
+ The charge is final when the job is accepted. Cancellation is allowed while `waiting` or `processing`. The MP3 and ASS subtitles can each be downloaded once. Starting either download immediately consumes that server copy, so an interrupted transfer cannot be downloaded again.
221
+
222
+ ## 신분증 마스킹 / Identity masking
223
+
224
+ ```js
225
+ const resident = await apick.maskResidentNumber('./id-card.jpg', { type: 3 });
226
+ await resident.save('./masked.png');
227
+
228
+ const passport = await apick.maskPassport('./passport.jpg');
229
+ console.log(passport.data.result.fields);
230
+ ```
231
+
232
+ `maskResidenceCard`, `maskPassport`, `maskIdCard`, `maskDriverLicense`는 JSON 결과를 반환합니다. `maskResidentNumber`는 PNG 바이너리를 반환하며 `type`은 `1`, `2`, `3`, `4` 중 하나이며 4는 주민등록번호와 주소를 함께 가립니다.
233
+ The four document-specific methods return JSON. `maskResidentNumber` returns PNG bytes and requires `type` 1, 2, 3, or 4 (number and address).
234
+
235
+ `maskResidenceCard`는 외국인등록증·영주증·외국국적동포 국내거소신고증의 앞면 한 장을 지원합니다. 영주증과 외국국적동포 국내거소신고증 지원은 개인정보 마스킹에만 적용되며 외국인등록증 진위확인 범위는 변경되지 않습니다.
236
+ `maskResidenceCard` accepts one front-side image of a residence card, permanent resident card, or overseas Korean resident card. Permanent and overseas Korean card support is limited to PII masking and does not expand the alien registration card authenticity-check scope.
237
+
238
+ ## 간편인증 기반 데이터 조회 / Simple-auth data lookups
239
+
240
+ 본인 간편인증이 필요한 조회 상품(재직·소득·연금·면허·건강검진)은 접수(`request*`)와 결과 조회(`get*`)가 분리되어 있습니다. 접수 응답의 `transactionId`로 결과를 폴링하세요.
241
+
242
+ Products that require the user's own simple-auth verification (employment, income, pension, driver's license, health checkup) split the call into a `request*()` acceptance and a `get*()` poll. Use the `transactionId` from the accepted response to poll for the result.
243
+
244
+ 아래 함수는 5종 모두에 공통으로 사용합니다. 같은 `transactionId`로 순차 조회하며 5→10→20→30초 간격으로 늘린 뒤 30초를 유지합니다. `resultAvailable === true`이면 즉시 결과를 반환합니다. `SUCCESS`는 전체 성공, `PARTIAL_SUCCESS`는 부분 성공이므로 `sources`에서 누락·실패 항목을 확인하세요. `AUTH_REJECTED`·`AUTH_EXPIRED`·`FAILED`는 실패 종료이며, `errorCode: 'RESULT_EXPIRED'`는 결과 보관 기간 만료입니다. 실패·만료 시 자동으로 재접수하지 않습니다.
245
+
246
+ Use this helper for all five products. Poll sequentially with the same `transactionId`, waiting 5→10→20→30 seconds and then keeping the 30-second interval. Return the result immediately when `resultAvailable === true`. `SUCCESS` means full success; `PARTIAL_SUCCESS` means partial success, so inspect `sources` for missing or failed items. `AUTH_REJECTED`, `AUTH_EXPIRED`, and `FAILED` are terminal failures; `errorCode: 'RESULT_EXPIRED'` means the retained result has expired. Never resubmit automatically after failure or expiry.
247
+
248
+ <!-- simple-auth-polling:start -->
168
249
  ```js
169
- const excel = await apick.jsonToExcel(
170
- [{ name: 'Kim', score: 95 }, { name: 'Lee', score: 88 }],
171
- { sheetName: 'Scores' }
172
- );
173
-
174
- await excel.save('./scores.xlsx');
175
- ```
176
-
177
- `ApickBinaryResult` provides `bytes`, `size`, `filename`, `contentType`, `meta`, `toArrayBuffer()`, `toBlob()`, and `save(path)`.
178
-
179
- ## 비동기 TTS Jobs / Asynchronous TTS Jobs
180
-
181
- 기존 동기 TTS는 종료되었습니다. 한국어 내레이션은 작업을 접수하고 `completed`가 될 때까지 2~5초 간격으로 상태를 확인한 뒤 MP3 결과를 한 번만 내려받습니다.
182
-
183
- The legacy synchronous TTS API has retired. Create a Korean narration job, poll every 2–5 seconds until it is `completed`, then download the MP3 result once.
184
-
185
- 17 neutral narration voices are supported: the five original `narrator_m_01`–`narrator_m_05` voices plus `narrator_f_10s_01`–`03`, `narrator_m_20s_01`, `narrator_f_20s_01`–`04`, `narrator_m_30s_01`–`02`, `narrator_m_40s_01`, and `narrator_m_80s_01`. Import `TTS_VOICE_IDS` for the exact list.
186
-
187
- 표시 이름 / voice labels: `narrator_m_01` 태준, `narrator_m_02` 민석, `narrator_m_03` 도현, `narrator_m_04` 강우, `narrator_m_05` 성훈, `narrator_f_10s_01` 서아, `narrator_f_10s_02` 하린, `narrator_f_10s_03` 예린, `narrator_m_20s_01` 도윤, `narrator_f_20s_01` 지안, `narrator_f_20s_02` 서윤, `narrator_f_20s_03` 소연, `narrator_f_20s_04` 유나, `narrator_m_30s_01` 현우, `narrator_m_30s_02` 준혁, `narrator_m_40s_01` 정우, `narrator_m_80s_01` 영수.
188
-
189
- ```js
190
- const created = await apick.createTtsJob('오늘의 이야기를 시작합니다.', {
191
- voiceId: 'narrator_m_03'
192
- });
193
- const jobId = created.data.job_id;
194
-
195
- let job;
196
- do {
197
- await new Promise(resolve => setTimeout(resolve, 3000));
198
- job = await apick.getTtsJob(jobId);
199
- } while (job.data.status === 'waiting' || job.data.status === 'processing');
200
-
201
- if (job.data.status === 'completed') {
202
- const result = await apick.downloadTtsResult(jobId);
203
- await result.save(`./${jobId}.mp3`);
204
- const subtitles = await apick.downloadTtsSubtitles(jobId);
205
- await subtitles.save(`./${jobId}.ass`);
250
+ async function pollDataResult(getResult, accepted, { timeoutMs = 600_000 } = {}) {
251
+ const pending = new Set([
252
+ 'AUTH_REQUESTED', 'AUTH_WAITING', 'AUTH_COMPLETED', 'COLLECTING', 'COLLECTED'
253
+ ]);
254
+ const failed = new Set(['AUTH_REJECTED', 'AUTH_EXPIRED', 'FAILED']);
255
+ const completed = new Set(['SUCCESS', 'PARTIAL_SUCCESS']);
256
+ const delays = [5_000, 10_000, 20_000, 30_000];
257
+ const deadline = Date.now() + timeoutMs;
258
+ const transactionId = accepted.data.transactionId;
259
+ const stop = code => { throw Object.assign(new Error(code), { code }); };
260
+ let response = accepted;
261
+ let attempt = 0;
262
+
263
+ for (;;) {
264
+ const data = response.data;
265
+ if (data.errorCode === 'RESULT_EXPIRED') stop('RESULT_EXPIRED');
266
+ if (failed.has(data.status)) stop(data.errorCode || data.status);
267
+ if (data.resultAvailable === true) {
268
+ if (data.result == null) stop('INVALID_RESULT');
269
+ return response;
270
+ }
271
+ if (completed.has(data.status)) stop('RESULT_NOT_AVAILABLE');
272
+ if (!pending.has(data.status)) stop('UNKNOWN_STATUS');
273
+
274
+ const awaitingApproval = ['AUTH_REQUESTED', 'AUTH_WAITING'].includes(data.status);
275
+ const authDeadline = Date.parse(data.expiresAt || accepted.data.expiresAt);
276
+ const limit = awaitingApproval && Number.isFinite(authDeadline)
277
+ ? Math.min(deadline, authDeadline) : deadline;
278
+ const timeoutCode = awaitingApproval && limit === authDeadline
279
+ ? 'AUTH_WAIT_TIMEOUT' : 'CLIENT_POLL_TIMEOUT';
280
+ const remaining = limit - Date.now();
281
+ if (remaining <= 0) stop(timeoutCode);
282
+ await new Promise(resolve => setTimeout(resolve,
283
+ Math.min(delays[Math.min(attempt++, delays.length - 1)], remaining)));
284
+ if (Date.now() >= limit) stop(timeoutCode);
285
+ response = await getResult(transactionId);
286
+ }
206
287
  }
207
288
  ```
289
+ <!-- simple-auth-polling:end -->
208
290
 
209
- 접수 성공 시 과금되며 취소해도 환불되지 않습니다. 취소는 `waiting` 또는 `processing` 상태에서 가능하고, MP3와 ASS 자막은 각각 한 번만 내려받을 수 있습니다. 각 다운로드가 시작되면 해당 서버 원본이 즉시 폐기되므로 전송 중단 시에도 다시 받을 수 없습니다.
210
-
211
- The charge is final when the job is accepted. Cancellation is allowed while `waiting` or `processing`. The MP3 and ASS subtitles can each be downloaded once. Starting either download immediately consumes that server copy, so an interrupted transfer cannot be downloaded again.
291
+ `AUTH_REQUESTED`·`AUTH_WAITING`은 사용자 승인을 기다리고, `AUTH_COMPLETED`·`COLLECTING`·`COLLECTED`는 결과가 준비될 때까지 계속 조회합니다. 과금 여부(`charged`, `success`)는 완료 기준이 아닙니다. 인증 대기에만 `expiresAt`을 적용하고 승인 후에는 전체 대기 한도를 적용합니다. 예제의 10분 한도는 클라이언트 정책이며, 진행 중인 호출의 제한 시간은 SDK의 `timeoutMs`로 별도 설정하세요. `AUTH_WAIT_TIMEOUT`·`CLIENT_POLL_TIMEOUT`·`RESULT_NOT_AVAILABLE`·`INVALID_RESULT`·`UNKNOWN_STATUS`는 예제에서 만드는 로컬 오류로, 응답 모순이나 알 수 없는 상태에서 무한 반복하지 않습니다. 통신 오류도 재시도 없이 호출자에게 전달합니다.
212
292
 
213
- ## 신분증 마스킹 / Identity masking
293
+ `AUTH_REQUESTED` and `AUTH_WAITING` wait for the user's approval; `AUTH_COMPLETED`, `COLLECTING`, and `COLLECTED` keep polling until a result is available. Billing fields (`charged`, `success`) do not indicate completion. Apply `expiresAt` only while awaiting approval, then use the overall waiting limit. The example's 10-minute limit is a client policy; configure the SDK's `timeoutMs` separately to bound each in-flight call. `AUTH_WAIT_TIMEOUT`, `CLIENT_POLL_TIMEOUT`, `RESULT_NOT_AVAILABLE`, `INVALID_RESULT`, and `UNKNOWN_STATUS` are local example errors that prevent endless polling on inconsistent responses or unknown states. Transport errors propagate without retries.
214
294
 
295
+ <!-- simple-auth-usage:start -->
215
296
  ```js
216
- const resident = await apick.maskResidentNumber('./id-card.jpg', { type: 3 });
217
- await resident.save('./masked.png');
218
-
219
- const passport = await apick.maskPassport('./passport.jpg');
220
- console.log(passport.data.result.fields);
221
- ```
222
-
223
- `maskResidenceCard`, `maskPassport`, `maskIdCard`, `maskDriverLicense`는 JSON 결과를 반환합니다. `maskResidentNumber`는 PNG 바이너리를 반환하며 `type`은 `1`, `2`, `3` 중 하나입니다.
224
- The four document-specific methods return JSON. `maskResidentNumber` returns PNG bytes and requires `type` 1, 2, or 3.
225
-
226
- `maskResidenceCard`는 외국인등록증·영주증·외국국적동포 국내거소신고증의 앞면 한 장을 지원합니다. 영주증과 외국국적동포 국내거소신고증 지원은 개인정보 마스킹에만 적용되며 외국인등록증 진위확인 범위는 변경되지 않습니다.
227
- `maskResidenceCard` accepts one front-side image of a residence card, permanent resident card, or overseas Korean resident card. Permanent and overseas Korean card support is limited to PII masking and does not expand the alien registration card authenticity-check scope.
228
-
229
- ## 오류 처리 / Error handling
230
-
231
- ```js
232
- import { ApickApiError } from 'apick-api';
297
+ const accepted = await apick.requestEmployment({
298
+ name: '홍길동',
299
+ birthDate: '19900101',
300
+ phone: '01011112222',
301
+ authProvider: 'kakao',
302
+ insuranceYears: 3
303
+ });
233
304
 
234
305
  try {
235
- await apick.whois('invalid value');
306
+ const result = await pollDataResult(id => apick.getEmployment(id), accepted);
307
+ if (result.data.status === 'PARTIAL_SUCCESS') console.warn(result.data.sources);
308
+ console.log(result.data.result);
236
309
  } catch (error) {
237
- if (error instanceof ApickApiError) {
238
- console.error(error.code, error.serviceCode, error.status, error.message);
310
+ if ((error.serviceCode || error.code) === 'RESULT_EXPIRED') {
311
+ console.error('결과 보관 기간 만료: 사용자 확인 후 새 인증을 요청하세요.');
312
+ } else {
313
+ throw error;
239
314
  }
240
315
  }
241
316
  ```
242
-
243
- 오류 코드는 `APICK_AUTH_ERROR`, `APICK_TIMEOUT`, `APICK_NETWORK_ERROR`, `APICK_INVALID_RESPONSE`, `APICK_API_ERROR` 중 하나입니다.
244
- Error codes are one of `APICK_AUTH_ERROR`, `APICK_TIMEOUT`, `APICK_NETWORK_ERROR`, `APICK_INVALID_RESPONSE`, and `APICK_API_ERROR`.
245
- 신분증 서비스의 상세 오류 코드는 선택적 `serviceCode`에 보존됩니다. Identity-specific service errors are exposed through optional `serviceCode`.
246
-
247
- ## 보안과 과금 / Security and billing
248
-
249
- - 인증키는 비밀번호처럼 취급하고 소스 코드, 공개 저장소, 브라우저 번들에 넣지 마세요.
250
- - 서버 환경변수 `APICK_API_KEY` 사용을 권장합니다.
251
- - SDK는 인증키를 로그나 오류 메시지에 출력하지 않습니다.
252
- - 실제 API 호출은 에이픽 포인트를 사용할 수 있습니다. 현재 요금은 [API 문서](https://apick.app/dev_guide)에서 확인하세요.
253
- - 중복 과금을 방지하기 위해 SDK는 실패한 요청을 자동 재시도하지 않습니다.
254
- - Treat the key like a password. Keep it in a server-side environment variable and never ship it in a browser bundle.
255
- - API calls may consume APICK points. The SDK deliberately performs no automatic retries.
256
-
257
- ## Requirements
258
-
259
- - Node.js 18 or newer
260
- - No runtime dependencies
261
- - ESM and CommonJS support
262
- - TypeScript declarations included
263
-
264
- ## License
265
-
266
- MIT — see [LICENSE](LICENSE). Use of the APICK service is governed by the [APICK terms](https://apick.app/terms).
267
-
268
- ## Video model versions
269
-
270
- Omitting `version` preserves Seedance 2.5, Veo 3.1 and Kling 3.0. Set `version` and `tier` explicitly to select a generation; jobs are never silently switched to another version. Submission and status responses include `version`.
271
-
272
- Available generations: Seedance 1.0/1.5/2.0/2.5, including Seedance 2.0 Standard/Fast/Mini; Veo 3.1 (Standard/Fast/Lite); Kling 1.6/2.0/2.1/2.5/2.6/3.0/O1/O3. Veo 3.0 is unavailable. Modes, tiers, resolutions, durations, audio, file limits and prices vary by combination. See the [Seedance](https://apick.app/dev_guide/seedancejobs), [Veo](https://apick.app/dev_guide/veojobs) and [Kling](https://apick.app/dev_guide/klingjobs) version tables. Unsupported combinations are rejected before submission.
273
-
274
- Seedance reference mode accepts `referenceImages`, `referenceVideos`, and `referenceAudios` (MP3/WAV) when supported by the selected version.
275
-
276
- ## 영상 모델 버전 선택
277
-
278
- `version`을 생략하면 Seedance 2.5, Veo 3.1, Kling 3.0을 사용합니다. 버전과 등급을 명시하면 해당 조합으로 생성하며 다른 모델로 자동 대체하지 않습니다. 생성과 상태 응답의 `version`으로 확인할 수 있습니다.
279
-
280
- | 제품 | 제공 버전 | 제약과 요금 |
281
- |---|---|---|
282
- | Seedance | 2.5, 2.0(Standard·Fast·Mini), 1.5, 1.0 | [버전별 지원표](https://apick.app/dev_guide/seedancejobs) |
283
- | Veo | 3.1 (Standard, Fast, Lite) | [버전별 지원표](https://apick.app/dev_guide/veojobs) |
284
- | Kling | 3.0, O3, O1, 2.6, 2.5, 2.1, 2.0, 1.6 | [버전별 지원표](https://apick.app/dev_guide/klingjobs) |
285
-
286
- 등급·해상도·길이·오디오·파일 개수와 초당 포인트는 선택 조합별로 다릅니다. Seedance 2.0은 Standard·Fast·Mini를 제공하며 Mini는 480p·720p와 4~15초를 지원합니다. 무음 전용 모델은 `audio=false`, 오디오 필수 모델은 `audio=true`만 허용합니다. Veo 3.0은 현재 제공하지 않습니다. 지원하지 않는 조합은 접수 전에 거절됩니다.
287
-
288
- Seedance 참조 소재 모드는 지원 버전에서 `referenceImages`, `referenceVideos`, `referenceAudios`(MP3·WAV)를 함께 사용할 수 있습니다.
289
-
290
- ```js
291
- const job = await client.createVideoJob("kling", "A boat crossing the sea", {
292
- version: "1.6", tier: "std", mode: "text", duration: 5, audio: false,
293
- idempotencyKey: "boat-video-0001"
294
- });
295
- const status = await client.getVideoJob("kling", job.data.job_id);
296
- if (status.data.status === "completed") {
297
- await (await client.downloadVideoResult("kling", job.data.job_id)).save("boat.mp4");
298
- }
299
- ```
317
+ <!-- simple-auth-usage:end -->
318
+
319
+ 근거: [APICK 개발가이드](https://apick.app/dev_guide/data_health_checkup) · [MCP 3.5.0 상태 계약](https://github.com/lead788/apick-mcp/blob/a803abcb81d07377c85f49bb0b670baf0c17ed04/TOOLS.md)
320
+
321
+ 지원 간편인증 방식(`authProvider`) 13종은 `AUTH_PROVIDERS`로 제공됩니다: `kakao`, `naver`, `toss`, `pass`, `samsung`, `kb`, `shinhan`, `hana`, `woori`, `ibk`, `nh`, `kakaobank`, `banksalad`.
322
+ The 13 supported `authProvider` values are exported as `AUTH_PROVIDERS`: `kakao`, `naver`, `toss`, `pass`, `samsung`, `kb`, `shinhan`, `hana`, `woori`, `ibk`, `nh`, `kakaobank`, `banksalad`.
323
+
324
+ 접수 시 정액 과금되고, 결과는 최초 반환에서만 과금되며 재조회는 무료입니다. 결과는 `resultExpiresAt`까지만 재조회할 수 있고, 그 이후에는 `errorCode: 'RESULT_EXPIRED'`가 오며 접수부터 다시 시작해야 합니다.
325
+ Acceptance is billed at a flat rate; the result is billed only on its first successful return and free to re-poll afterward. The result can be re-fetched until `resultExpiresAt`; after that `errorCode` is `'RESULT_EXPIRED'` and you must request again from the start.
326
+
327
+ | 상품 / Product | Request / Get | 선택 입력 / Optional input |
328
+ | --- | --- | --- |
329
+ | 재직·보험료 확인 / Employment & insurance premium | `requestEmployment` / `getEmployment` | `insuranceYears` (1–3) |
330
+ | 금융소득 조회 / Financial income | `requestPersonalIncome` / `getPersonalIncome` | `incomeYears` (1–5) |
331
+ | 국민연금 가입내역 / NPS join history | `requestNpsJoinHistory` / `getNpsJoinHistory` | `from`, `to` (`YYYY-MM`) |
332
+ | 운전면허 조회 / Driver's license | `requestDrivingLicense` / `getDrivingLicense` | — |
333
+ | 국가 건강검진 결과 / Health checkup | `requestHealthCheckup` / `getHealthCheckup` | — |
334
+
335
+ ## 오류 처리 / Error handling
336
+
337
+ ```js
338
+ import { ApickApiError } from 'apick-api';
339
+
340
+ try {
341
+ await apick.whois('invalid value');
342
+ } catch (error) {
343
+ if (error instanceof ApickApiError) {
344
+ console.error(error.code, error.serviceCode, error.status, error.message);
345
+ }
346
+ }
347
+ ```
348
+
349
+ 오류 코드는 `APICK_AUTH_ERROR`, `APICK_TIMEOUT`, `APICK_NETWORK_ERROR`, `APICK_INVALID_RESPONSE`, `APICK_API_ERROR` 중 하나입니다.
350
+ Error codes are one of `APICK_AUTH_ERROR`, `APICK_TIMEOUT`, `APICK_NETWORK_ERROR`, `APICK_INVALID_RESPONSE`, and `APICK_API_ERROR`.
351
+ 신분증 서비스의 상세 오류 코드는 선택적 `serviceCode`에 보존됩니다. Identity-specific service errors are exposed through optional `serviceCode`.
352
+
353
+ ## 보안과 과금 / Security and billing
354
+
355
+ - 인증키는 비밀번호처럼 취급하고 소스 코드, 공개 저장소, 브라우저 번들에 넣지 마세요.
356
+ - 서버 환경변수 `APICK_API_KEY` 사용을 권장합니다.
357
+ - SDK는 인증키를 로그나 오류 메시지에 출력하지 않습니다.
358
+ - 실제 API 호출은 에이픽 포인트를 사용할 수 있습니다. 현재 요금은 [API 문서](https://apick.app/dev_guide)에서 확인하세요.
359
+ - 중복 과금을 방지하기 위해 SDK는 실패한 요청을 자동 재시도하지 않습니다.
360
+ - Treat the key like a password. Keep it in a server-side environment variable and never ship it in a browser bundle.
361
+ - API calls may consume APICK points. The SDK deliberately performs no automatic retries.
362
+
363
+ ## Requirements
364
+
365
+ - Node.js 18 or newer
366
+ - No runtime dependencies
367
+ - ESM and CommonJS support
368
+ - TypeScript declarations included
369
+
370
+ ## License
371
+
372
+ MIT — see [LICENSE](LICENSE). Use of the APICK service is governed by the [APICK terms](https://apick.app/terms).
373
+
374
+ ## Video model versions
375
+
376
+ Omitting `version` preserves Seedance 2.5, Veo 3.1 and Kling 3.0. Set `version` and `tier` explicitly to select a generation; jobs are never silently switched to another version. Submission and status responses include `version`.
377
+
378
+ Available generations: Seedance 1.0/1.5/2.0/2.5, including Seedance 2.0 Standard/Fast/Mini; Veo 3.1 (Standard/Fast/Lite); Kling 1.6/2.0/2.1/2.5/2.6/3.0/O1/O3. Veo 3.0 is unavailable. Modes, tiers, resolutions, durations, audio, file limits and prices vary by combination. See the [Seedance](https://apick.app/dev_guide/seedancejobs), [Veo](https://apick.app/dev_guide/veojobs) and [Kling](https://apick.app/dev_guide/klingjobs) version tables. Unsupported combinations are rejected before submission.
379
+
380
+ Seedance reference mode accepts `referenceImages`, `referenceVideos`, and `referenceAudios` (MP3/WAV) when supported by the selected version.
381
+
382
+ ## 영상 모델 버전 선택
383
+
384
+ `version`을 생략하면 Seedance 2.5, Veo 3.1, Kling 3.0을 사용합니다. 버전과 등급을 명시하면 해당 조합으로 생성하며 다른 모델로 자동 대체하지 않습니다. 생성과 상태 응답의 `version`으로 확인할 수 있습니다.
385
+
386
+ | 제품 | 제공 버전 | 제약과 요금 |
387
+ |---|---|---|
388
+ | Seedance | 2.5, 2.0(Standard·Fast·Mini), 1.5, 1.0 | [버전별 지원표](https://apick.app/dev_guide/seedancejobs) |
389
+ | Veo | 3.1 (Standard, Fast, Lite) | [버전별 지원표](https://apick.app/dev_guide/veojobs) |
390
+ | Kling | 3.0, O3, O1, 2.6, 2.5, 2.1, 2.0, 1.6 | [버전별 지원표](https://apick.app/dev_guide/klingjobs) |
391
+
392
+ 등급·해상도·길이·오디오·파일 개수와 초당 포인트는 선택 조합별로 다릅니다. Seedance 2.0은 Standard·Fast·Mini를 제공하며 Mini는 480p·720p와 4~15초를 지원합니다. 무음 전용 모델은 `audio=false`, 오디오 필수 모델은 `audio=true`만 허용합니다. Veo 3.0은 현재 제공하지 않습니다. 지원하지 않는 조합은 접수 전에 거절됩니다.
393
+
394
+ Seedance 참조 소재 모드는 지원 버전에서 `referenceImages`, `referenceVideos`, `referenceAudios`(MP3·WAV)를 함께 사용할 수 있습니다.
395
+
396
+ ```js
397
+ const job = await client.createVideoJob("kling", "A boat crossing the sea", {
398
+ version: "1.6", tier: "std", mode: "text", duration: 5, audio: false,
399
+ idempotencyKey: "boat-video-0001"
400
+ });
401
+ const status = await client.getVideoJob("kling", job.data.job_id);
402
+ if (status.data.status === "completed") {
403
+ await (await client.downloadVideoResult("kling", job.data.job_id)).save("boat.mp4");
404
+ }
405
+ ```