Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Fetch YouTube transcripts through DeepAPI or local fallback tooling and save clean text output.
.claude/skills/lingxling-youtube-transcript/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-16 | ✗→✓ | ▲ Improved | 68% | 0% |
| case-04 | ✗→✓ | ▲ Improved | 42% | 0% |
| case-05 | ✗→✓ | ▲ Improved | 5% | 0% |
| case-06 | ✗→✓ | ▲ Improved | 19% | 0% |
| case-08 | ✗→✓ | ▲ Improved | -48% | 0% |
Fetch a YouTube video's transcript and save a clean raw .txt file. Primary path is DeepAPI POST /v1/scrape/youtube/transcript. It runs server-side, so it avoids the local-IP bot flagging that plagues yt-dlp.
~/Downloads.Channel_Title with spaces replaced by _ (e.g. David_Ondrej_title_of_video.txt). If metadata is unavailable, fall back to the video ID.DEEPAPI_API_KEY must already be present in the environment. Do not read shell startup files or print secrets:
bashtest -n "$DEEPAPI_API_KEY" || { echo "DEEPAPI_API_KEY is not set"; exit 1; } BASE=${DEEPAPI_API_BASE_URL:-https://deepapi.co}
Run the scrape (keep the Idempotency-Key; retries must reuse the SAME one):
bashIDK=$(uuidgen) curl -s --max-time 120 "$BASE/v1/scrape/youtube/transcript" \ -H "Authorization: Bearer $DEEPAPI_API_KEY" \ -H "Content-Type: application/json" \ -H "Idempotency-Key: $IDK" \ -d '{"url": "VIDEO_URL", "maxCostUsd": "0.05", "waitForFinishSecs": 60}' \ > /tmp/yt_transcript.json
"language": "de" (etc.) to the body.status: running → wait next.afterSecs, then curl "$BASE$(jq -r '.next.path' /tmp/yt_transcript.json)" -H "Authorization: Bearer $KEY" until succeeded or failed.Extract the text and save it:
bashjq -r '.status' /tmp/yt_transcript.json # succeeded | running | failed jq -r '.output[0].text' /tmp/yt_transcript.json > "$OUT/$NAME.txt" jq -r '.debitMicrousd' /tmp/yt_transcript.json # cost (50000 = $0.05)
.output[0].segments also has timed segments (startSecs, durationSecs, text) if the user wants timestamps. Empty output = video has no captions; report it, don't retry.
For the Channel_Title filename, get metadata with a quick yt-dlp --print "%(channel)s|%(title)s" --skip-download "URL"; if that fails, use the video ID.
DEEPAPI_API_KEY missing from the environment.insufficient_credits (tell the user to top up at deepapi.co/credits first; fall back only if they're unavailable).failed twice.Tell the user whenever you fall back — a fallback means the product missed a real use case.
bashOUT="$(pwd)" # or ~/Downloads if cwd makes no sense META=$(yt-dlp --print "%(channel)s|%(title)s" --skip-download "URL") NAME=$(echo "$META" | tr '| ' '__' | tr -cd '[:alnum:]_.-') # "Channel_Title", spaces -> _, strip unsafe chars yt-dlp --skip-download --write-subs --write-auto-subs \ --sub-langs "en.*" --sub-format json3 \ -o "$OUT/$NAME.%(ext)s" "URL"
channel → uploader → uploader_id if channel is null.--skip-download = captions only. --write-subs + --write-auto-subs = manual first, auto as fallback.json3, never VTT/SRT — auto VTT repeats every line twice (rolling captions).Flatten json3 → raw text:
bashpython3 - "$OUT" <<'PY' import json, html, re, glob, sys, pathlib f = glob.glob(sys.argv[1] + "/*.json3") if not f: sys.exit("no json3 file") data = json.load(open(f[0], encoding="utf-8")) parts = ["".join(s.get("utf8","") for s in e.get("segs") or []) for e in data.get("events", [])] txt = re.sub(r"\s+", " ", html.unescape(" ".join(p.strip() for p in parts if p.strip()))).strip() out = pathlib.Path(f[0]).with_suffix(".txt") out.write_text(txt, encoding="utf-8"); print(out) PY
yt-dlp --list-subs "URL" first, then set --sub-langs.deno on PATH for YouTube extraction.yt-dlp -U once, retry once, then stop.Report the saved path; print the text if short. If DeepAPI was used, also report the cost in dollars.
davidondrej/skills; verify local paths, tools, credentials, and agent features before acting.| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-16 | fail→pass | 14,459 | 4,038 | -72% | 1 | 1 | 0% | 1,226 | 2,056 | +68% | 0 | 0 | — |
case-01 | fail→fail | 16,047 | 36,276 | +126% | 1 | 1 | 0% | 2,393 | 1,908 | -20% | 0 | 0 | — |
case-02 | pass→fail | 9,721 | 9,148 | -6% | 1 | 1 | 0% | 1,820 | 1,962 | +8% | 0 | 0 | — |
case-03 | fail→fail | 27,897 | 8,104 | -71% | 1 | 1 | 0% | 2,819 | 1,823 | -35% | 0 | 0 | — |
case-04 | fail→pass | 10,078 | 9,140 | -9% | 1 | 1 | 0% | 1,867 | 2,648 | +42% | 0 | 0 | — |
case-05 | fail→pass | 16,743 | 7,303 | -56% | 1 | 1 | 0% | 2,360 | 2,472 | +5% | 0 | 0 | — |
case-06 | fail→pass | 10,255 | 5,248 | -49% | 1 | 1 | 0% | 1,751 | 2,084 | +19% | 0 | 0 | — |
case-07 | fail→fail | 11,158 | 2,794 | -75% | 1 | 1 | 0% | 1,831 | 1,861 | +2% | 0 | 0 | — |
case-08 | fail→pass | 27,335 | 3,468 | -87% | 1 | 1 | 0% | 3,794 | 1,970 | -48% | 0 | 0 | — |
case-09 | fail→pass | 19,557 | 4,975 | -75% | 1 | 1 | 0% | 2,329 | 2,048 | -12% | 0 | 0 | — |
case-14 | fail→pass | 13,282 | 4,474 | -66% | 1 | 1 | 0% | 2,038 | 2,051 | +1% | 0 | 0 | — |
case-10 | pass→pass | 14,669 | 6,155 | -58% | 1 | 1 | 0% | 2,392 | 2,421 | +1% | 0 | 0 | — |
case-11 | fail→pass | 13,087 | 6,617 | -49% | 1 | 1 | 0% | 2,230 | 2,424 | +9% | 0 | 0 | — |
case-12 | pass→pass | 6,172 | 3,655 | -41% | 1 | 1 | 0% | 870 | 1,875 | +116% | 0 | 0 | — |
case-13 | pass→pass | 13,255 | 4,582 | -65% | 1 | 1 | 0% | 1,831 | 1,877 | +3% | 0 | 0 | — |
case-15 | pass→pass | 17,688 | 12,080 | -32% | 1 | 1 | 0% | 3,108 | 3,158 | +2% | 0 | 0 | — |
case-17 | fail→pass | 13,640 | 3,108 | -77% | 1 | 1 | 0% | 2,317 | 1,879 | -19% | 0 | 0 | — |
case-18 | pass→pass | 8,125 | 3,394 | -58% | 1 | 1 | 0% | 1,225 | 2,010 | +64% | 0 | 0 | — |
case-19 | pass→fail | 11,878 | 2,827 | -76% | 1 | 1 | 0% | 1,846 | 1,940 | +5% | 0 | 0 | — |
case-20 | pass→pass | 16,647 | 9,994 | -40% | 1 | 1 | 0% | 2,414 | 2,984 | +24% | 0 | 0 | — |
case-21 | pass→pass | 19,740 | 6,280 | -68% | 1 | 1 | 0% | 2,024 | 2,689 | +33% | 0 | 0 | — |
case-22 | pass→fail | 8,011 | 7,066 | -12% | 1 | 1 | 0% | 1,185 | 2,741 | +131% | 0 | 0 | — |
case-23 | pass→pass | 7,685 | 8,331 | +8% | 1 | 1 | 0% | 1,312 | 2,755 | +110% | 0 | 0 | — |
case-24 | pass→fail | 11,488 | 9,876 | -14% | 1 | 1 | 0% | 1,505 | 2,072 | +38% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 24 cases were attempted, and 20 counted toward the lift figure. The other 4 produced results that are not comparable between the two arms, so they are excluded from the headline rather than averaged into it. The headline lift of +21 percentage points is the difference between those two pass rates over the 20 comparable cases. 5 cases got worse with the skill loaded, and they are included in that figure.
Without the skill loaded, the model failed this case. With it loaded, the same prompt on the same model passed. This is one improved case from the latest verified run; every case, including any that regressed, is in the table above.
Other measured skills in the registry, with their headline benchmark lift.