Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Search FREE image / video / GIF APIs (stock + historical/archival + GIF engines) and download results with attribution. Use when a task needs a REAL or ARCHIVAL photo/clip (hero, texture, reference, historical footage) or a reaction/animated GIF, rather than a generated one. The retrieval peer to muser (local) and fal (generate).
.claude/skills/bilal140202-web-media-getter/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-09 | ✗→✓ | ▲ Improved | -8% | 0% |
| case-04 | ✗→✓ | ▲ Improved | -6% | 0% |
| case-05 | ✗→✓ | ▲ Improved | 0% | 0% |
| case-06 | ✗→✓ | ▲ Improved | 40% | 0% |
| case-07 | ✗→✓ | ▲ Improved | 27% | 0% |
Query many free image/video sources in one fan-out, get a normalized result list, optionally download top-K with an attribution sidecar. Zero-dep stdlib script.
Script: webmedia.py (in this dir). Keys: PEXELS_API_KEY, PIXABAY_API_KEY in central/.env (optional — the 5 no-key sources work without them).
| Source | Key? | Best for | Media | |--------|------|----------|-------| | openverse | none | CC web images (Flickr, museums) | image | | wikimedia | none | factual / historical / landmark photos | image | | internetarchive | none | historical/archival images + films | image, video | | loc | none | historical US prints/photos | image | | nasa | none | space imagery + video | image, video | | pexels | free key | modern stock photos + short video clips | image, video | | pixabay | free key | modern photos/illustrations + short clips | image, video | | klipy | free key | GIFs — recommended (free, unlimited, Tenor drop-in) | gif | | giphy | free key | GIFs — biggest library (prod key needs approval) | gif |
GIF sources fire only with --type gif. Keys: KLIPY_API_KEY, GIPHY_API_KEY in central/.env. (tenor adapter removed — Google EOL'd the API 2026-06-30.) klipy is the one to get (free + unlimited); its adapter is unverified — assumes Tenor-compatible request/response; verify against docs.klipy.com when you key it. webmedia.py "shrug" --type gif --count 6 --json
bashwebmedia.py "1950s street scene" --type image --count 8 --json webmedia.py "rocket launch" --type video --source nasa,internetarchive webmedia.py "car factory 1930s" --source all --download --out /tmp/cars
--source all (default) | nokey (no-key only) | comma list (wikimedia,pexels)--type image|video · --count N · --json · --download --out DIR--download fetches each result's direct media URL and writes attribution.json(source, author, license, url, page_url) alongside the files.
{source, title, url, thumb, dl, page_url, author, license, w, h, type} — dl is the directly-downloadable media URL (None when only a page exists).
Archival sources (Internet Archive, Europeana, LoC) host whole films/documentaries, not single shots. So:
pexels / pixabay (born as short clips, direct MP4). Done.timestamped moment for "car on assembly line", clip with ffmpeg. Semantic, cheap.
with CLIP via the muser skill. Fully offline.
webmedia.py is image/video. For sound effects (real, CC-licensed) and for judging audio (since Claude can't hear), two sibling scripts live in central/scripts/:
freesound-fetch.py "<query>" [count] [max_sec] [out_dir] — searches freesound.organd downloads short hq-mp3 previews. Prints one JSON line per file with license/user for attribution. Key: FREESOUND_API_KEY in central/.env (token-based read; full originals would need OAuth — previews suffice for SFX).
audio-judge.py <file> "<target>" — sends the clip to OpenAI gpt-audio(audio-native) and returns JSON {heard, score, matches, suggestion}, enabling a generate/fetch → judge → iterate loop. Auto-sources a real sk- OPENAI_API_KEY from .env (ignores a local lm-studio stub env var). Pads sub-2s clips so the speech-tuned model doesn't refuse. Caveat: it reliably describes audio and filters obvious mismatches, but it is NOT a trustworthy judge of subjective qualities like "grating" — it labels nearly any beep "sharp/high-pitched". Use it to cull, not to make the final aesthetic call; confirm by ear.
This is the internet-retrieval capability — peer to muser (local semantic search) and fal (generate). A future media router would fan out across all three and rank candidates by relevance (CLIP), handing aesthetic spreads to lookdev. Don't build that router until the model demonstrably mis-routes without it.
| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-14 | pass→pass | 12,080 | 2,129 | -82% | 1 | 1 | 0% | 2,109 | 1,583 | -25% | 0 | 0 | — |
case-01 | fail→fail | 13,498 | 6,344 | -53% | 1 | 1 | 0% | 2,914 | 1,633 | -44% | 0 | 0 | — |
case-02 | fail→fail | 10,800 | 4,489 | -58% | 1 | 1 | 0% | 2,425 | 1,655 | -32% | 0 | 0 | — |
case-03 | fail→fail | 14,492 | 10,041 | -31% | 1 | 1 | 0% | 2,871 | 2,936 | +2% | 0 | 0 | — |
case-09 | fail→pass | 9,602 | 2,173 | -77% | 1 | 1 | 0% | 1,788 | 1,641 | -8% | 0 | 0 | — |
case-04 | fail→pass | 9,301 | 2,243 | -76% | 1 | 1 | 0% | 1,757 | 1,651 | -6% | 0 | 0 | — |
case-05 | fail→pass | 10,349 | 2,330 | -77% | 1 | 1 | 0% | 1,657 | 1,664 | +0% | 0 | 0 | — |
case-06 | fail→pass | 6,730 | 2,310 | -66% | 1 | 1 | 0% | 1,177 | 1,643 | +40% | 0 | 0 | — |
case-07 | fail→pass | 13,389 | 8,419 | -37% | 1 | 1 | 0% | 2,277 | 2,887 | +27% | 0 | 0 | — |
case-08 | pass→pass | 17,358 | 12,307 | -29% | 1 | 1 | 0% | 3,432 | 3,717 | +8% | 0 | 0 | — |
case-10 | fail→pass | 9,188 | 5,526 | -40% | 1 | 1 | 0% | 1,854 | 1,566 | -16% | 0 | 0 | — |
case-11 | fail→pass | 11,240 | 2,712 | -76% | 1 | 1 | 0% | 2,081 | 1,777 | -15% | 0 | 0 | — |
case-12 | pass→pass | 5,834 | 2,031 | -65% | 1 | 1 | 0% | 1,018 | 1,685 | +66% | 0 | 0 | — |
case-13 | fail→pass | 9,849 | 3,123 | -68% | 1 | 1 | 0% | 2,020 | 1,893 | -6% | 0 | 0 | — |
case-15 | fail→pass | 12,754 | 2,823 | -78% | 1 | 1 | 0% | 2,083 | 1,686 | -19% | 0 | 0 | — |
case-16 | pass→pass | 3,393 | 2,167 | -36% | 1 | 1 | 0% | 558 | 1,662 | +198% | 0 | 0 | — |
case-17 | fail→pass | 8,390 | 1,683 | -80% | 1 | 1 | 0% | 1,268 | 1,493 | +18% | 0 | 0 | — |
case-18 | fail→pass | 11,701 | 3,359 | -71% | 1 | 1 | 0% | 2,107 | 1,832 | -13% | 0 | 0 | — |
case-19 | fail→pass | 12,089 | 2,417 | -80% | 1 | 1 | 0% | 2,344 | 1,626 | -31% | 0 | 0 | — |
case-20 | pass→pass | 2,564 | 2,225 | -13% | 1 | 1 | 0% | 453 | 1,651 | +264% | 0 | 0 | — |
case-21 | pass→pass | 3,731 | 2,643 | -29% | 1 | 1 | 0% | 713 | 1,667 | +134% | 0 | 0 | — |
case-22 | fail→pass | 5,912 | 5,245 | -11% | 1 | 1 | 0% | 1,155 | 2,238 | +94% | 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. 22 cases were attempted, and 20 counted toward the lift figure. The other 2 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 +59 percentage points is the difference between those two pass rates over the 20 comparable cases.
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.