# Provider And Proxy Catalog This is the current implementation inventory as of this snapshot of the repo. Use it to find the nearest existing pattern before adding a new channel. ## Providers | Provider | Group | `/api/uploaders` | Uses local `/proxy` | Notes | | --- | --- | --- | --- | --- | | `all` | `meta-search` | no | no | Aggregates all compiled providers. | | `allpornstream` | `mainstream-tube` | no | yes | Next.js App Router scraper; extracts cards via `data-thumb-id/href/title/images` attributes; redirect proxy lazy-resolves VOE/DoodStream/StreamTape/FileMoon embeds. | | `animeidhentai` | `hentai-animation` | no | yes | Next.js hentai site (animeidhentai.com) backed by a clean JSON API: latest feed `GET /api/browse?page=N` (`{videos:[28],total,pages}`, real pagination, ignores sort/genre params) and search `GET /api/search?q=Q&page=N` (`{videos:[8]}`, matches titles AND tags). Each episode JSON carries `slug`/`titleSlug`/`ep`, `title`, `tags[]`, `views`, `rating` (0-10 → ×10 for the 0-100 scale), `duration` ("MM:SS"), `brand` (studio → `uploader`), `releasedAt` (RFC3339 → `uploadedAt`), relative `thumb`/`backdrop` images (served from `animeidhentai.com/uploads/...`, no referer), and an `embedUrl` of the form `https://nhplayer.com/v/{embedId}/`. `video.url` is the reachable series page `https://animeidhentai.com/series/{titleSlug}` (the per-episode watch route 307-redirects to `/`; episodes are watched on the series page). `genre:`/`tag:`/`cat:`/`category:` query prefixes and the `categories` filter (curated genre list, sanitized out of `/api/status` but honored in `/api/videos`) route to `/api/search` since browse can't filter by genre. Playback: yt-dlp cannot resolve nhplayer, whose real MP4 sits on a Cloudflare-fronted R2 bucket (`r2.1hanime.com`) behind a signed `?verify=-` token minted by an obfuscated JS challenge (`player.php` → `player-core-v2.php` → `get-video-url-v2.php`): a SHA-256 proof-of-work over five DOM-embedded parts + a fixed fingerprint + a ≥700ms server-enforced dwell time, all replicated in `src/proxies/animeidhentai.rs`. The signed URL further needs a *browser* TLS JA3 to clear Cloudflare — curl_cffi/AVFoundation pass but our `wreq` stack is JA3-blocked on every emulation profile — so the proxy cannot stream server-side. `/proxy/animeidhentai/{embedId}.mp4` is therefore a **redirect** proxy (like `jable`): HEAD→200 (so health checks/yt-dlp media detection pass on the `.mp4` extension), GET→302 to the freshly-resolved CDN URL, which the client fetches directly (yt-dlp resolves it with `--impersonate chrome`). Resolved URLs are cached 150s. No `/api/uploaders` (no stable uploader identity; `brand` is studio-only). | | `archivebate` | `live-cams` | no | no | Livewire-backed cam archive listings with platform/gender/profile shortcuts. | | `beeg` | `mainstream-tube` | no | no | Basic mainstream tube pattern. | | `blowjobspro` | `mainstream-tube` | no | no | KVS-style HTML provider with async search pagination and category shortcut routing. | | `chaturbate` | `live-cams` | no | no | Live cam channel. | | `clapdat` | `amateur-homemade` | no | yes | Svelte/JSON-hydrated provider using home/recent/trending routes, Meilisearch keyword search, and `/proxy/clapdat/...` redirect playback resolution. | | `erome` | `amateur-homemade` | no | no | HTML album scraper with hot/new feeds, keyword search, and uploader-slug shortcuts (`uploader:`). | | `fikfap` | `tiktok` | yes | yes (thumbs only) | JSON-API provider for fikfap.com (TikTok-style swipe short clips); anonymous auth via a client-generated `Authorization-Anonymous` UUID header (no real login needed); listing via `GET api.fikfap.com/posts?sort=new\|trending\|random&amount=N&afterId=` (cursor pagination — page N costs N sequential requests); search via `GET search?q=` (single fixed-size batch, no pagination — page 2+ returns empty); hashtag feeds via `GET hashtags/label/{label}/posts` and creator feeds via `GET profile/username/{user}/posts`, both also cursor-paginated; `tag:`/`hashtag:`/`#` and `user:`/`uploader:` query prefixes route directly; `categories` option exposes a small curated static hashtag list (no full catalog endpoint exists anonymously); `video.url` is the `fikfap.com/post/{id}` page (a client-rendered SPA, not yt-dlp-resolvable on its own); `videoStreamUrl` from the JSON response is sent directly as `formats[0].url` (signed Bunny CDN HLS `.m3u8`, ~24h token expiry) with `httpHeaders: {Referer: https://fikfap.com/}` — Hot Tub clients apply a format's `http_headers` across the whole HLS playback session (manifest, sub-playlists, and segments), so no proxying of the media itself is needed; thumbnails have no per-field header mechanism, so they're proxied via `/proxy/fikfap-thumb/...` to inject the same Referer; `get_uploader` implemented (`fikfap:` IDs) using `GET profile/username/{user}`. | | `freepornvideosxxx` | `studio-network` | no | no | Studio-style scraper. | | `fyptt` | `tiktok` | no | no | HTML scraper for fyptt.to (Beaver Builder/WordPress short-form TikTok-style vertical porn); card selector `.fl-post-grid-post[class*="post-ID"]` with `category-{slug}` CSS class doubling as both listing tag and category-archive route; latest feed `/` (page N: `/page/N/`), search `/?s=query` (page N: `/page/N/?s=query`), category archives at bare top-level slugs like `/tiktok-ass/` (12 hardcoded categories exposed via the `categories` filter option, or via an explicit `cat:`/`category:` query prefix — bare keyword queries always go to WordPress search, never a category archive, because the category names ("sexy", "ass", "tiktok", "live", ...) are also the most common search terms); per-item enrichment fetches the detail page for the JSON-LD `embedURL` (one of three on-site player endpoints: `fypttstr.php`, `fypttjwstr.php`, or `fypttjwstrhls.php`) and `datePublished`, then fetches that embed URL to extract the actual signed `stream.fyptt.to` mp4 or `/hls/*.m3u8` URL (token expires ~2h, no Referer required) for `formats`; thumbnails (`fyptt.to/wp-content/uploads/...webp`) need no proxy; no duration metadata available on listing or detail pages (set to 0); no real uploader/model identity (the `girl-{slug}` CSS class is cosmetic only, not a linkable archive) so `/api/uploaders` is not implemented; `video.url` is the detail page URL (not yt-dlp resolvable directly — the player is sandboxed-iframe-only) so `formats` are populated instead; no proxy needed. | | `freeuseporn` | `fetish-kink` | no | no | Fetish archive pattern. | | `hanime` | `hentai-animation` | no | yes | Uses proxied CDN/thumb handling. | | `heavyfetish` | `fetish-kink` | no | no | Direct media handling. | | `hentaihaven` | `hentai-animation` | no | no | HTML scraper for hentaihaven.xxx (WordPress/Madara theme), Cloudflare-protected so the provider is gated behind `FLARE_URL` in `skip_reason_for_provider` (mod.rs); the shared requester clears CF directly (wreq Firefox136 emulation currently passes for the listing/search/watch/episode/`player.php` GETs) and falls back to Jina/FlareSolverr. Latest feed `/hentai/page/{N}/`, search `/?s={query}` (search is single-page — page>1 returns empty); listing/search cards link to series watch pages `https://hentaihaven.xxx/watch/{slug}/`. Per-series media resolution (the UUID exists nowhere in page HTML, so enrichment is unavoidable): watch page → episode links `…/watch/{slug}/episode-K` (in `manga-chapters-holder`) → episode page → `