API 요청
/rest/youtube_subtitle요청 파라미터 4개 · 필수 2
url- 예시
https://www.youtube.com/watch?v=dQw4w9WgXcQ
lang- 예시
en
format- 예시
vtt
type응답 필드 파일
정상 응답은 파일 본문입니다. 실패 시 JSON 오류가 올 수 있으므로 HTTP 상태와 Content-Type을 먼저 확인하세요.
공개 영상의 자막 한 언어를 VTT·SRT·텍스트 파일로 받습니다. 성공하면 응답 본문이 UTF-8 자막 파일 자체입니다.
https://apick.app/rest/youtube_subtitle왜 유튜브 자막 다운로드인가
영상 내용을 받아 적거나 따로 음성 인식을 돌리던 수고를 줄이세요. 공개 영상의 자막을 언어별로 VTT·SRT·텍스트 파일로 받아 요약·검색·번역에 바로 투입합니다.
성공한 다운로드 한 건당 30P가 차감됩니다. 파일 응답에는 form-data 본문이 없으므로 차감액은 응답 헤더 cost에서 확인하세요. 입력 오류·영상 없음·요청한 언어 자막 없음·시간 초과처럼 실패한 호출은 자막 대신 JSON 오류(data.error)가 오고 과금되지 않습니다(api.cost 0).
먼저 유튜브 자막 목록 조회로 제공 언어를 확인하고, 응답의 lang 값을 그대로 보내세요. 자동 번역 자막(자막 목록의 translated가 true)은 받지 못할 수 있으니 원어 자막을 받은 뒤 직접 번역하는 편이 안정적입니다.
성공과 실패의 본문 형식이 다르므로, 저장하기 전에 HTTP 상태가 200이고 Content-Type이 자막 형식인지 먼저 확인하세요.
응답 시간은 보통 8초 이내이고 최대 약 60초입니다. 요청 시간 제한을 90초 이상으로 잡으세요.
인증키는 서버 환경변수에 보관하고 공개 저장소·웹페이지에 넣지 마세요.
/rest/youtube_subtitleurlhttps://www.youtube.com/watch?v=dQw4w9WgXcQlangenformatvtttype정상 응답은 파일 본문입니다. 실패 시 JSON 오류가 올 수 있으므로 HTTP 상태와 Content-Type을 먼저 확인하세요.
POST https://apick.app/rest/youtube_subtitleAuthorization: Bearer — 내 계정의 API 인증키multipart/form-datavtttext/vtt; charset=utf-8srtapplication/x-subrip; charset=utf-8txttext/plain; charset=utf-8anymanualauto영어 자막을 VTT 파일로 저장하는 예입니다. 성공 시 과금되는 실제 요청입니다. --fail을 붙이면 실패 응답(JSON)을 자막 파일로 저장하지 않습니다.
상황별로 보내는 값과 응답에서 확인할 값을 모았습니다. 언어 탭에서 그대로 복사해 쓸 수 있습니다.
웹 플레이어에 바로 붙일 자막을 받습니다. format·type을 생략하면 VTT, 수동 자막 우선입니다.
/rest/youtube_subtitlecurl --fail-with-body --request POST 'https://apick.app/rest/youtube_subtitle' \
--header "Authorization: Bearer $APICK_API_KEY" \
--form-string 'url=https://www.youtube.com/watch?v=dQw4w9WgXcQ' \
--form-string 'lang=ko' \
--dump-header response.headers --output result.bin
# response.headers의 Content-Type을 확인한 뒤 파일을 사용하세요.const form = new FormData();
form.append("url", "https://www.youtube.com/watch?v=dQw4w9WgXcQ");
form.append("lang", "ko");
const response = await fetch("https://apick.app/rest/youtube_subtitle", {
method: "POST",
headers: { Authorization: "Bearer " + process.env.APICK_API_KEY },
body: form,
signal: AbortSignal.timeout(120_000),
});
if (!response.ok) throw new Error(`HTTP ${response.status}: ${await response.text()}`);
if ((response.headers.get("content-type") || "").includes("json")) {
throw new Error(JSON.stringify(await response.json()));
}
const { writeFile } = await import("node:fs/promises");
await writeFile("result.bin", new Uint8Array(await response.arrayBuffer()));import os
import requests
parts = [
("url", (None, "https://www.youtube.com/watch?v=dQw4w9WgXcQ")),
("lang", (None, "ko")),
]
response = requests.request("POST", "https://apick.app/rest/youtube_subtitle",
headers={"Authorization": "Bearer " + os.environ["APICK_API_KEY"]},
files=parts,
timeout=(10, 120), stream=True)
response.raise_for_status()
if "json" in response.headers.get("Content-Type", ""):
raise RuntimeError(response.json())
with open("result.bin", "wb") as output:
for chunk in response.iter_content(65536):
output.write(chunk)<?php
$headers = ["Authorization: Bearer " . getenv("APICK_API_KEY")];
$form = [
'url' => 'https://www.youtube.com/watch?v=dQw4w9WgXcQ',
'lang' => 'ko',
];
$curl = curl_init('https://apick.app/rest/youtube_subtitle');
curl_setopt_array($curl, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_HTTPHEADER => $headers,
CURLOPT_POSTFIELDS => $form,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CONNECTTIMEOUT => 10, CURLOPT_TIMEOUT => 120,
]);
$body = curl_exec($curl);
if ($body === false) { throw new RuntimeException(curl_error($curl)); }
$status = curl_getinfo($curl, CURLINFO_HTTP_CODE);
$type = curl_getinfo($curl, CURLINFO_CONTENT_TYPE) ?: "";
curl_close($curl);
if ($status >= 400) { throw new RuntimeException($body); }
if (strpos($type, "json") !== false) { throw new RuntimeException($body); }
file_put_contents('result.bin', $body);영상ID.ko.vtt입니다.lang 값을 먼저 확인하세요.편집 프로그램에 불러올 자막은 format=srt로 받습니다.
/rest/youtube_subtitlecurl --fail-with-body --request POST 'https://apick.app/rest/youtube_subtitle' \
--header "Authorization: Bearer $APICK_API_KEY" \
--form-string 'url=dQw4w9WgXcQ' \
--form-string 'lang=en' \
--form-string 'format=srt' \
--dump-header response.headers --output result.bin
# response.headers의 Content-Type을 확인한 뒤 파일을 사용하세요.const form = new FormData();
form.append("url", "dQw4w9WgXcQ");
form.append("lang", "en");
form.append("format", "srt");
const response = await fetch("https://apick.app/rest/youtube_subtitle", {
method: "POST",
headers: { Authorization: "Bearer " + process.env.APICK_API_KEY },
body: form,
signal: AbortSignal.timeout(120_000),
});
if (!response.ok) throw new Error(`HTTP ${response.status}: ${await response.text()}`);
if ((response.headers.get("content-type") || "").includes("json")) {
throw new Error(JSON.stringify(await response.json()));
}
const { writeFile } = await import("node:fs/promises");
await writeFile("result.bin", new Uint8Array(await response.arrayBuffer()));import os
import requests
parts = [
("url", (None, "dQw4w9WgXcQ")),
("lang", (None, "en")),
("format", (None, "srt")),
]
response = requests.request("POST", "https://apick.app/rest/youtube_subtitle",
headers={"Authorization": "Bearer " + os.environ["APICK_API_KEY"]},
files=parts,
timeout=(10, 120), stream=True)
response.raise_for_status()
if "json" in response.headers.get("Content-Type", ""):
raise RuntimeError(response.json())
with open("result.bin", "wb") as output:
for chunk in response.iter_content(65536):
output.write(chunk)<?php
$headers = ["Authorization: Bearer " . getenv("APICK_API_KEY")];
$form = [
'url' => 'dQw4w9WgXcQ',
'lang' => 'en',
'format' => 'srt',
];
$curl = curl_init('https://apick.app/rest/youtube_subtitle');
curl_setopt_array($curl, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_HTTPHEADER => $headers,
CURLOPT_POSTFIELDS => $form,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CONNECTTIMEOUT => 10, CURLOPT_TIMEOUT => 120,
]);
$body = curl_exec($curl);
if ($body === false) { throw new RuntimeException(curl_error($curl)); }
$status = curl_getinfo($curl, CURLINFO_HTTP_CODE);
$type = curl_getinfo($curl, CURLINFO_CONTENT_TYPE) ?: "";
curl_close($curl);
if ($status >= 400) { throw new RuntimeException($body); }
if (strpos($type, "json") !== false) { throw new RuntimeException($body); }
file_put_contents('result.bin', $body);영상ID.en.srt로 옵니다. 저장할 때 확장자를 그대로 쓰세요.요약·검색에 쓸 대본이 필요하면 format=txt로 시간 정보를 뺀 본문만 받습니다.
/rest/youtube_subtitlecurl --fail-with-body --request POST 'https://apick.app/rest/youtube_subtitle' \
--header "Authorization: Bearer $APICK_API_KEY" \
--form-string 'url=dQw4w9WgXcQ' \
--form-string 'lang=en' \
--form-string 'format=txt' \
--dump-header response.headers --output result.bin
# response.headers의 Content-Type을 확인한 뒤 파일을 사용하세요.const form = new FormData();
form.append("url", "dQw4w9WgXcQ");
form.append("lang", "en");
form.append("format", "txt");
const response = await fetch("https://apick.app/rest/youtube_subtitle", {
method: "POST",
headers: { Authorization: "Bearer " + process.env.APICK_API_KEY },
body: form,
signal: AbortSignal.timeout(120_000),
});
if (!response.ok) throw new Error(`HTTP ${response.status}: ${await response.text()}`);
if ((response.headers.get("content-type") || "").includes("json")) {
throw new Error(JSON.stringify(await response.json()));
}
const { writeFile } = await import("node:fs/promises");
await writeFile("result.bin", new Uint8Array(await response.arrayBuffer()));import os
import requests
parts = [
("url", (None, "dQw4w9WgXcQ")),
("lang", (None, "en")),
("format", (None, "txt")),
]
response = requests.request("POST", "https://apick.app/rest/youtube_subtitle",
headers={"Authorization": "Bearer " + os.environ["APICK_API_KEY"]},
files=parts,
timeout=(10, 120), stream=True)
response.raise_for_status()
if "json" in response.headers.get("Content-Type", ""):
raise RuntimeError(response.json())
with open("result.bin", "wb") as output:
for chunk in response.iter_content(65536):
output.write(chunk)<?php
$headers = ["Authorization: Bearer " . getenv("APICK_API_KEY")];
$form = [
'url' => 'dQw4w9WgXcQ',
'lang' => 'en',
'format' => 'txt',
];
$curl = curl_init('https://apick.app/rest/youtube_subtitle');
curl_setopt_array($curl, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_HTTPHEADER => $headers,
CURLOPT_POSTFIELDS => $form,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CONNECTTIMEOUT => 10, CURLOPT_TIMEOUT => 120,
]);
$body = curl_exec($curl);
if ($body === false) { throw new RuntimeException(curl_error($curl)); }
$status = curl_getinfo($curl, CURLINFO_HTTP_CODE);
$type = curl_getinfo($curl, CURLINFO_CONTENT_TYPE) ?: "";
curl_close($curl);
if ($status >= 400) { throw new RuntimeException($body); }
if (strpos($type, "json") !== false) { throw new RuntimeException($body); }
file_put_contents('result.bin', $body);수동 자막이 있어도 음성 인식 자막을 원할 때 type=auto로 지정합니다. 수동 자막만 원하면 type=manual입니다.
/rest/youtube_subtitlecurl --fail-with-body --request POST 'https://apick.app/rest/youtube_subtitle' \
--header "Authorization: Bearer $APICK_API_KEY" \
--form-string 'url=dQw4w9WgXcQ' \
--form-string 'lang=en' \
--form-string 'type=auto' \
--dump-header response.headers --output result.bin
# response.headers의 Content-Type을 확인한 뒤 파일을 사용하세요.const form = new FormData();
form.append("url", "dQw4w9WgXcQ");
form.append("lang", "en");
form.append("type", "auto");
const response = await fetch("https://apick.app/rest/youtube_subtitle", {
method: "POST",
headers: { Authorization: "Bearer " + process.env.APICK_API_KEY },
body: form,
signal: AbortSignal.timeout(120_000),
});
if (!response.ok) throw new Error(`HTTP ${response.status}: ${await response.text()}`);
if ((response.headers.get("content-type") || "").includes("json")) {
throw new Error(JSON.stringify(await response.json()));
}
const { writeFile } = await import("node:fs/promises");
await writeFile("result.bin", new Uint8Array(await response.arrayBuffer()));import os
import requests
parts = [
("url", (None, "dQw4w9WgXcQ")),
("lang", (None, "en")),
("type", (None, "auto")),
]
response = requests.request("POST", "https://apick.app/rest/youtube_subtitle",
headers={"Authorization": "Bearer " + os.environ["APICK_API_KEY"]},
files=parts,
timeout=(10, 120), stream=True)
response.raise_for_status()
if "json" in response.headers.get("Content-Type", ""):
raise RuntimeError(response.json())
with open("result.bin", "wb") as output:
for chunk in response.iter_content(65536):
output.write(chunk)<?php
$headers = ["Authorization: Bearer " . getenv("APICK_API_KEY")];
$form = [
'url' => 'dQw4w9WgXcQ',
'lang' => 'en',
'type' => 'auto',
];
$curl = curl_init('https://apick.app/rest/youtube_subtitle');
curl_setopt_array($curl, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_HTTPHEADER => $headers,
CURLOPT_POSTFIELDS => $form,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CONNECTTIMEOUT => 10, CURLOPT_TIMEOUT => 120,
]);
$body = curl_exec($curl);
if ($body === false) { throw new RuntimeException(curl_error($curl)); }
$status = curl_getinfo($curl, CURLINFO_HTTP_CODE);
$type = curl_getinfo($curl, CURLINFO_CONTENT_TYPE) ?: "";
curl_close($curl);
if ($status >= 400) { throw new RuntimeException($body); }
if (strpos($type, "json") !== false) { throw new RuntimeException($body); }
file_put_contents('result.bin', $body);translated=true)는 HTTP 424로 실패할 수 있으며 과금되지 않습니다. 원어 언어로 다시 요청하세요.HTTP 성공과 업무 결과를 구분하세요. 경로별 응답 필드와 예시는 위 요청과 응답에 함께 있습니다.
성공하면 HTTP 200과 함께 UTF-8 자막 파일이 본문으로 옵니다.
format에 맞는 형식입니다.attachment; filename=영상ID.언어.형식dQw4w9WgXcQ.en.vtt, dQw4w9WgXcQ.ko.srt1WEBVTT
Kind: captions
Language: en
00:00:01.000 --> 00:00:03.500
This is the first caption line.
00:00:03.500 --> 00:00:06.000
This is the second caption line.
예시 본문은 설명을 위한 가상 값입니다.
실패하면 자막 대신 아래 형식의 JSON이 옵니다. 이 응답을 자막 파일로 저장하지 마세요.
{
"data": { "error": "요청한 언어의 자막을 찾을 수 없습니다. 자막 목록 조회로 제공 언어를 확인해 주세요.", "success": 0 },
"api": { "cost": 0, "success": true, "ms": 2600 }
}
응답을 아래 순서로 확인하세요. 결과 유무와 과금 여부는 서로 다릅니다.
아래 경우는 JSON의 data.error로 응답하며 과금되지 않습니다(api.cost 0). 실패 응답은 표의 HTTP 상태 코드와 함께 옵니다. 화면에 보여 줄 안내는 본문의 data.error를 쓰세요.
입력 항목이 잘못됐습니다. 유튜브 영상 주소 또는 11자리 영상 ID를 입력해 주세요.입력 항목이 잘못됐습니다. lang(언어 코드), format(vtt·srt·txt), type(any·manual·auto)을 확인해 주세요.lang을 빠뜨리지 않았는지, format·type이 허용값인지 확인합니다.영상을 찾을 수 없습니다. 삭제·비공개 영상이거나 잘못된 주소입니다.요청한 언어의 자막을 찾을 수 없습니다. 자막 목록 조회로 제공 언어를 확인해 주세요.lang 값을 그대로 보냅니다. type=manual로 요청했다면 any로 바꿔 봅니다.자막을 가져오지 못했습니다. 자동 번역 자막(자막 목록의 translated=true)은 유튜브 제한으로 받지 못할 수 있으니 원어 자막을 이용하거나 잠시 후 다시 시도해 주세요.translated가 false인 언어)으로 다시 요청합니다.연령 제한 영상은 조회할 수 없습니다.채널 회원 전용 영상은 조회할 수 없습니다.처리 시간 초과로 실패했습니다. 잠시 후 다시 시도해 주세요.일시적으로 영상 정보를 가져오지 못했습니다. 잠시 후 다시 시도해 주세요.FORM_DATA_INVALIDFORM_DATA_FIELD_CONFLICTMULTIPART_LIMIT_OR_PARSE_ERROR실제 차감 금액은 응답의 api.cost로 확인하세요. 상세 요금은 요금정책에서 볼 수 있습니다.
같은 요청을 JavaScript(Node.js 18 이상)와 Python으로 옮긴 예시입니다. 키는 환경변수 APICK_API_KEY 에서 읽고, 성공 응답만 파일로 저장합니다.