Listing videos
GET /v1/videos accepts a YouTube channel or playlist URL in url. Channel listings accept contents=all, videos, or shorts. Each response includes at most 500 rows and an offset for continuation. offset must be 0 or a multiple of 500 and no larger than 20,000; pass the next_offset from the previous page. Other values return 400 InvalidInput with code: invalid_offset.
curl --get https://api.scripthaul.com/v1/videos \
-H "Authorization: Bearer $SCRIPTHAUL_API_KEY" \
--data-urlencode "url=https://www.youtube.com/@YouTube" \
--data-urlencode "contents=videos" \
--data-urlencode "offset=0"
Each row labels cached and is_short. counts.cold tells you how many listed videos would need a cold transcript fetch before you choose work.
Warm shared snapshots spend no Data API units and do not consume the cold-enumeration allowance. A cold enumeration counts once per input; individual upstream calls are guarded by the global Data API unit cap.
| Limit | Free | Paid |
|---|---|---|
| Rows per response | 500 | 500 |
| Cold enumerations per key/day | 25 | 25 |
Enumeration is a capacity feature, not a paid data product. ScriptHaul deliberately has no search endpoint and never calls YouTube search.list.
List a channel in four languages
All variants request the first page of regular uploads. Maintained runnable versions are in the examples directory.
curl --get https://api.scripthaul.com/v1/videos \
-H "Authorization: Bearer $SCRIPTHAUL_API_KEY" \
--data-urlencode "url=https://www.youtube.com/@YouTube" \
--data-urlencode "contents=videos" --data-urlencode "offset=0"
import os, urllib.parse, urllib.request
query = urllib.parse.urlencode({"url": "https://www.youtube.com/@YouTube", "contents": "videos", "offset": 0})
request = urllib.request.Request(f"https://api.scripthaul.com/v1/videos?{query}")
request.add_header("Authorization", f"Bearer {os.environ['SCRIPTHAUL_API_KEY']}")
print(urllib.request.urlopen(request).read().decode())
const url = new URL("https://api.scripthaul.com/v1/videos");
url.search = new URLSearchParams({ url: "https://www.youtube.com/@YouTube", contents: "videos", offset: "0" });
const response = await fetch(url, { headers: { Authorization: `Bearer ${process.env.SCRIPTHAUL_API_KEY}` } });
console.log(await response.json());
url := "https://api.scripthaul.com/v1/videos?url="+url.QueryEscape("https://www.youtube.com/@YouTube")+"&contents=videos&offset=0"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Set("Authorization", "Bearer "+os.Getenv("SCRIPTHAUL_API_KEY"))
response, err := http.DefaultClient.Do(req)
if err != nil { log.Fatal(err) }
defer response.Body.Close()
io.Copy(os.Stdout, response.Body)