# movies Searchable index of movie and TV download links (HubCloud, GDFlix mirrors) with on-demand direct-link resolution. Built for AI agents: plain HTTPS, JSON in and out, no browser, no captchas. Base URL: https://movies.ssrizz.workers.dev ## When to use this - An agent needs a direct download link for a named movie or TV episode. - One shot: fetch the script and run it. That is the whole flow. ```sh curl -sO https://movies.ssrizz.workers.dev/scripts/get-movie.ts bun get-movie.ts "" --out /tmp/opencode ``` No clone, no install, no npm. `GET /scripts` lists what is served. Bun or Node 22+ with `--experimental-strip-types`; curl and aria2c are used for the download itself (file hosts serve curl's TLS fingerprint but block datacenter ones, which is why resolution happens locally and not in the worker). - Manual flow: `GET /api/get?q=<title>` returns candidate page URLs. Resolve each LOCALLY (below). Do not expect the worker to resolve for you: upstream file hosts block Cloudflare egress IPs, so server-side resolution fails. Your own machine's curl works fine. ## Endpoints - `GET /api/get?q=<title>&n=10` — search the index. Returns page URLs (up to `n`, default 10, max 50) as `{query, results, hasMore, nextCursor, truncated, searchWindow, resolve}`. Results are newest first, not ranked: the search is a LIKE scan, so sort client-side if order matters. `hasMore` means another page exists and `nextCursor` is the opaque token that fetches it: pass it back as `&cursor=`. A cursor is bound to its `q` and `host`, so reusing one with a different query answers 400 rather than returning rows that do not match. `truncated` means paging stopped at the 2000-row offset ceiling; a cursor walks past that ceiling, because it seeks on the last id instead of counting rows. `searchWindow` is how far back the search looked, in rows, and is now always **0**, meaning the whole active index is scanned rather than only the newest N links. That is why an old title resolves: there is no window to fall out of. A query with no searchable token (all non-ASCII, or every word under 2 characters) returns zero rows rather than the whole index. The script tries gdflix mirrors first, since those direct links live longest. - `GET /api/resolve?url=<drive-page-url>` — best-effort server-side resolve. Works only for hosts that accept Cloudflare egress; usually 502s. - `GET /api/links?q=<text>&host=<host>&page=<n>&limit=<n>` — raw index search. Same body as `/api/get` minus `query` and `resolve`. `&cursor=` works here too and is the only way past the offset ceiling. - `GET /api/hosts` — mirror host counts, top 50. - `GET /api/domains` — upstream provider domain map. - `GET /api/stats` — index coverage: link totals, posts per provider, backfill pages, watchdog queue (in-flight plus stuck claims), and today's ingest write and read row counts. The read count is the ingest fire's own reads, not all traffic: it exists to show what running the index costs, and it stays under the free-plan caps by design. Search traffic is budgeted per isolate instead, and a spent isolate answers 503 on search while this endpoint keeps working so you can still see the state. - `GET /scripts` — agent scripts served as source, runnable anywhere. - `GET /health` — liveness probe. - `GET /llms.txt` — this file. - `GET /sitemap.xml` — endpoint list. - `GET /openapi.json` — machine-readable API description. ## Local resolve how-to (what the script does) For each page URL, repeat (max 6 hops), preferring in order. This list is the ACTUAL priority in `nextResolveStep` in src/resolve.ts, in order: 1. pixeldrain (prefer the JS-assigned `var pxl` over the static anchor: the static one is the DMCA decoy) → DIRECT as `https://pixeldrain.dev/api/file/<id>`. Stable, resumable, no expiry. 2. `workers.dev` href → DIRECT, download it (lives minutes). 3. `googleusercontent.com` href → DIRECT (lives 3h, stated on provider page). 4. FSL server href (`cdn.fsl-buckets.*`, or any `id="fsl"` anchor) → DIRECT (short TTL). 5. Labeled CDN button ("FSL Server", "FSLv2", "S3 Server") whose href is a known terminal host → DIRECT. 6. pages.dev watch links → base64-decode the `u` param → DIRECT. 7. `var url = '...gamerxyt...'` → fetch it next. 8. hubcloud `/drive/<id>` href → fetch it next. 9. hubcloud `/re/<id>` href → fetch it next. 10. `hubcloud.php` generator href → fetch it next. 11. `#download` anchor → fetch it next. 12. greenmotors → unpack `s('o','<payload>',...)` (base64, base64, rot13, base64, JSON, base64 of the `o` field) to the hubcloud URL underneath → fetch it next. 13. foxcloud `quick.` href → fetch it next. 14. BuzzServer anchor → fetch it plus `/download`. 15. "Instant DL" button → fetch it next. 16. JS `window.location.href` → fetch the absolute URL next. 17. `<meta http-equiv="refresh">` → fetch its URL next. Two rules that are not in that list because they are checked before it, on every hop: an embedded `url=` param pointing at googleusercontent, and an `hx-redirect` response header. HTTP 3xx → follow Location. Anything else → dead end, try the next mirror. Hubcloud search-session pages (`search-recover.php` carrying `Q_INITIAL` and `FROM_AC_TOKEN`) are a separate branch, not a priority: call its `?api=search` with a SHORT query (the first 3 distinctive words, never the full locked phrase), pool pages 1-3 across 2-3 query windows, and fuzzy-pick the best filename. Every DIRECT above has its host checked against a known-CDN allowlist, so a terminal host in a page's PATH does not become a download link. The one exception is rule 6: a pages.dev watch link decodes to an arbitrary https URL by design, so treat that direct as unverified and check the bytes before trusting it. Download with single-connection curl plus the file-host headers (follow redirects: signed URLs 302 to the CDN): ```sh curl -L -A "Mozilla/5.0" -H "Referer: https://gamerxyt.com/" -H "Cookie: xyt=1" -o movie.mkv "<direct>" ``` Verify the first bytes are Matroska (`1a 45 df a3`), not JSON (an error page means the signed URL expired: resolve again). Docs: https://movies.ssrizz.workers.dev/llms.txt · Spec: https://movies.ssrizz.workers.dev/openapi.json