Lustpress was originally named Lust and Express (legacy name). The motivation of this project is carry an actionable data related to pornhub and other r18 sites with gather, similar design pattern, endpoint bindings, and consistent structure in mind.
Many developers consume r18 websites as a source of data when building web applications. However, most of these sites — such as pornhub, redtube, and others — do not provide official APIs or public resources that can be easily integrated into applications.
As a result, developers often need to implement their own scraping logic, build multiple abstractions, and manually maintain integrations for each site.
Lustpress aims to simplify this process by providing a unified interface for accessing data across multiple r18 sites. Instead of maintaining separate implementations, developers can rely on Lustpress to reduce complexity and development overhead.
The current state of the service is free to use, meaning anonymous usage is allowed. No authentication is required, and CORS is enabled to support browser-based applications.
Don't make it long, make it short. All processed through single rest endpoint bindings

- Aggregates data from multiple sites.
- Provides a consistent and structured response format across all sources.
- Extracted objects are normalized and reassembled to support extensibility.
- Unified interface supporting get, search, and random methods.
- Planned support for optional JWT authentication in future releases.
- Primarily based on pure scraping techniques (with limited exceptions where required).
Some tests may fail in CI environments because certain websites restrict or block automated requests originating from CI infrastructure and shared IP ranges, but trying to keep up
| NOTE: Rust 1.96.0 or higher / or simply just use docker |
To handle several requests, You also need Redis for persistent caching:
- You can use
docker pull ghcr.io/sinkaroid/lustpress-redis:latestfor full control. - If just small usage or experimenting, You can get redis.io/try-free for demo and free tier available on Redis Labs.
Rename .env.schema to .env and fill the value with your own
# default port
PORT = 3000
# backend storage, default is redis, if not set it will consume memory storage
REDIS_URL = redis://default:somenicepassword@redis-666.c10.us-east-6-6.ec666.cloud.redislabs.com:1337
# ttl expire cache (in X hour)
EXPIRE_CACHE = 1
# you must identify your origin, if not set it will use default
USER_AGENT = "lustpress/9.1.0 rustc/1.96.0"
# debug log default is false
ENABLE_DEBUG_LOG = falsedocker pull ghcr.io/sinkaroid/lustpress:latest
docker run -p 3000:3000 -d ghcr.io/sinkaroid/lustpress:latest
docker run -d \
--name=lustpress \
-p 3028:3000 \
-e LUSTPRESS_GRAPHQL=true \
-e REDIS_URL='redis://default:somenicepassword@redis-666.c10.us-east-6-6.ec666.cloud.redislabs.com:1337' \
-e EXPIRE_CACHE='1' \
-e USER_AGENT='lustpress/9.1.0 rustc/1.96.0' \
-e ENABLE_DEBUG_LOG=false \
ghcr.io/sinkaroid/lustpress:latestgit clone https://github.com/sinkaroid/lustpress.git
- Run development server (with optional watch)
cargo dev(orcargo watch)
- Compile release binary
cargo build-release
- Run production server
cargo prod
Run the following cargo alias commands to execute tests and static analysis:
# Run all unit tests transparently
cargo t
# Check types and borrow checker across all targets
cargo typecheck
# Lint with Clippy (strict best practices)
cargo lint
# Run tests for individual sources
cargo test-pornhub
cargo test-xnxx
cargo test-redtube
cargo test-xvideos
cargo test-xhamster
cargo test-youporn
cargo test-eporner
cargo test-txxx
cargo test-graphqlcargo prod
cargo dev
For full list of available aliases, check
.cargo/config.toml.
https://sinkaroid.github.io/lustpress
The GraphQL endpoint is experimental and gated behind the LUSTPRESS_GRAPHQL=true environment variable.
Start the server with GraphQL enabled:
# On Unix-like systems
LUSTPRESS_GRAPHQL=true cargo dev
# On Windows (PowerShell)
$env:LUSTPRESS_GRAPHQL="true"; cargo devAccessing endpoint: Send GET or POST requests to http://localhost:3000/graphql.
GraphiQL Playground: Open http://localhost:3000/graphql in your browser when running in development mode to use the interactive playground.
POST Request:
curl -X POST http://localhost:3000/graphql \
-H "Content-Type: application/json" \
-d "{\"query\": \"{ xnxx { get(id: \\\"video-1crugx78/chainsaw_man_hentai\\\") { success data { title } } } }\"}"GET Request:
curl -G "http://localhost:3000/graphql" \
--data-urlencode "query={ xnxx { get(id: \"video-1crugx78/chainsaw_man_hentai\") { success data { title } } } }"Raw POST (application/graphql):
curl -X POST http://localhost:3000/graphql \
-H "Content-Type: application/graphql" \
-d "{ xnxx { search(key: \"makima\", page: \"1\") { data { title link } } } }"Query Pornhub Video:
query {
pornhub {
get(id: "6484dd996d97a") {
success
data {
title
}
}
}
}Search Xnxx:
query {
xnxx {
search(key: "milf", page: "1") {
data {
title
link
}
}
}
}Random Redtube:
query {
redtube {
random {
success
data {
title
id
}
}
}
}-
These
parameter?: means is optional -
/: index page
The missing piece of pornhub.com - https://sinkaroid.github.io/lustpress/#api-pornhub
/pornhub: pornhub api- get, takes parameters :
id - search, takes parameters :
key,?page,?sort - related, takes parameters :
id - random
- sort parameters on search
- "mr", "mv", "tr", "lg"
- Example
- get, takes parameters :
The missing piece of xnxx.com - https://sinkaroid.github.io/lustpress/#api-xnxx
/xnxx: xnxx api- get, takes parameters :
id - search, takes parameters :
key,?page, and TBD - related, takes parameters :
id - random
- sort parameters on search
- TBD
- Example
- get, takes parameters :
The missing piece of redtube.com - https://sinkaroid.github.io/lustpress/#api-redtube
/redtube: redtube api- get, takes parameters :
id - search, takes parameters :
key,?page, and TBD - related, takes parameters :
id - random
- sort parameters on search
- TBD
- Example
- get, takes parameters :
The missing piece of xvideos.com - https://sinkaroid.github.io/lustpress/#api-xvideos
/xvideos: xvideos api- get, takes parameters :
id - search, takes parameters :
key,?page, and TBD - related, takes parameters :
id - random
- sort parameters on search
- TBD
- Example
- get, takes parameters :
The missing piece of xhamster.com - https://sinkaroid.github.io/lustpress/#api-xhamster
/xhamster: xhamster api- get, takes parameters :
id - search, takes parameters :
key,?page, and TBD - related, takes parameters :
id - random
- Example
- get, takes parameters :
The missing piece of youporn.com - https://sinkaroid.github.io/lustpress/#api-youporn
/youporn: youporn api- get, takes parameters :
id - search, takes parameters :
key,?page - related, takes parameters :
id - random
- Example
- get, takes parameters :
https://sinkaroid.github.io/lustpress/#api-eporner
/eporner: eporner api- get, takes parameters :
id - search, takes parameters :
key,?page - related, takes parameters :
id - random
- sort parameters on search
- TBD
- Example
- get, takes parameters :
https://sinkaroid.github.io/lustpress/#api-txxx
/txxx: txxx api- get, takes parameters :
id - search, takes parameters :
key,?page - related, takes parameters :
id - random
- Example
- get, takes parameters :
"success": true, or "success": false,
HTTP/1.1 200 OK
HTTP/1.1 400 Bad Request
HTTP/1.1 500 Fail to get data
Pornhub serves a JavaScript challenge page to detect automated requests. Instead of relying on a headless browser (Playwright/Puppeteer), Lustpress solves this natively with zero external dependencies.
How it works:
- Fetch the index page and capture initial session cookies
- Detect the
leastFactormath challenge in the response HTML - Parse obfuscated variables (
p,s) and conditional bitwise operations - Compute the correct
KEYcookie value - Verify the solved cookie against the index
- Cache and reuse cookies for subsequent requests, auto-refresh on expiry
This approach runs in < 1ms compared to 5-10s with a headless browser, uses virtually no memory, and is fully Docker-friendly — no Chromium installation required.
The solver logic lives in src/fetch.rs. If Pornhub changes its obfuscation pattern, update the solver logic in that file.
Q: The website response is slow
That's unfortunate, this repository was opensource already, You can host and deploy Lustpress with your own instance. Any fixes and improvements will updating to this repo.
March 11, 2026: We have discontinued providing public APIs and playground services due to ongoing abuse and excessive usage. To continue using Lustpress, please deploy and run your own self-hosted instance.
en_US • /lʌstˈprɛs/ — "lust" stand for this project and "press" for express.
This tool can be freely copied, modified, altered, distributed without any attribution whatsoever. However, if you feel like this tool deserves an attribution, mention it. It won't hurt anybody.
Licence: WTF.
Microservices and subprojects is part of a broader ecosystem of specialized services, each focused on a specific platform or content source while sharing a common design philosophy maintained by ScathachGrip
- sinkaroid/lustpress — Unified REST and GraphQL API for PornHub and other R18 platforms
- sinkaroid/jandapress — Unified REST and GraphQL API for nhentai and other doujinshi.
- sinkaroid/matoi — Unified REST + GraphQL gateway for booru imageboards
- sinkaroid/pixivHono — Unified REST and GraphQL API for Pixiv
Each service is developed independently, enabling modular deployments, isolated maintenance, and platform-specific optimizations while remaining interoperable within the ecosystem.
