OnlyFans Posts Scraper
Pricing
$4.50 / 1,000 media links
OnlyFans Posts Scraper
Get source-hosted media links from public OnlyFans profiles, media sections, and posts. Export creator, post, thumbnail, media type, duration, dimensions, and source details without copying or hosting the files.
Pricing
$4.50 / 1,000 media links
Rating
0.0
(0)
Developer
Maxime Dupré
Maintained by CommunityActor stats
1
Bookmarked
798
Total users
21
Monthly active users
11 days ago
Last modified
Categories
Security
Limited permissionsShare
📥 Export public OnlyFans media links
OnlyFans Downloader is for researchers, media teams, and developers who have public OnlyFans targets and need source-hosted media links with creator, post, thumbnail, media type, duration, dimensions, and source details in an Apify dataset. Add profiles, media sections, posts, usernames, or supported URLs in one run. Use filters and a per-target limit to keep the output focused and make a short run easier to review.
- Collect media from several public targets in one run with OnlyFans Bulk Downloader.
- Keep video links and available details with OnlyFans Video Downloader.
- Keep photo links and thumbnails when shown with OnlyFans Photo Downloader.
- Extract source-hosted media URLs for a downstream workflow with OnlyFans Media URL Extractor.
- Collect media and post context from known posts with OnlyFans Post Media Downloader.
- Export creator, post, media type, duration, and source details when shown with OnlyFans Media Metadata Export.
This Actor does not bypass subscriptions, paywalls, private profiles, DRM, expired links, or OnlyFans access rules. It does not copy or host the media files.
📦 Media rows and source details
Each dataset row is one saved media link or one text-only post, and resultType says which one. A media row includes the submitted target, creator details, the creator's verified flag, post details, linked and mentioned user IDs, media links, thumbnails, technical details, and distinct additional source-hosted versions of the same media item. mediaVariants excludes the main media URL and thumbnail URL, and is [] when no additional version is available. A text-only post comes from a post URL whose post has text but no media. It keeps its creator and post details, and its media fields are null. Some fields can be null when OnlyFans does not show them. Source-hosted links can expire or stop working.
🚀 Run the OnlyFans media link collector
- Add one or more public OnlyFans targets.
- Choose the media kind to collect.
- Add a date range if needed.
- Set the maximum media rows to save per target.
- Start the Actor and open the dataset.
The Actor works through your targets one by one. It skips a target that is not a profile, section, or post, such as two links joined together or a signed-in account page. It also skips a target that OnlyFans says does not exist. A profile that shows its media only to paying subscribers saves no rows, and a valid target with no matching media saves no rows. The log names each of these targets, and none of them fails the run.
When OnlyFans cannot be read for a target, the Actor tries that target up to 11 times. If it still cannot be read, the log names it, rows already saved are kept, and the Actor moves on to the next target. The run fails only when a target stays unreadable and no other target could be finished. The Actor saves the first eligible occurrence of a media item and ignores later matches of that same item, so it does not merge later target or source matches into the saved row.
For a shorter run, use a small maxMediaPerTarget value. Leave it empty or use 0 to return all available results until the source is exhausted.
⚙️ Input
Input fields
| Field | Type | What it does |
|---|---|---|
targets | array of strings | Adds 1 to 100 public usernames, @handles, profile URLs, media-section URLs, or post URLs, one per entry. The form is prefilled with https://onlyfans.com/oftv/videos. A post URL can also return a text-only post. |
downloadMode | string | Chooses media for all media, videos, photos, or post_media for media from posts. The default is videos. A media-section URL uses the section in its URL instead. |
sortOrder | string | Chooses latest, oldest, mostLiked, leastLiked, highestTips, or lowestTips. The default is latest. It sets the post order for profile and section targets. The tips orders work only without a start or end date. |
dateFrom | string in YYYY-MM-DD form | Keeps rows from posts published on or after this date. Leave it empty for no start date. It works with date and like orders, not with tips orders. |
dateTo | string in YYYY-MM-DD form | Keeps rows from posts published on or before this date. Leave it empty for no end date. It works with date and like orders, not with tips orders. |
maxMediaPerTarget | integer | Sets the most rows to save for each target, including text-only post rows. Leave it empty or use 0 to return all available results. The form is prefilled with 5, but there is no schema default. |
textFormat | string | Chooses how postText is written: plain, markdown, or html for the original HTML. The default is plain. |
Example input
{"maxMediaPerTarget": 5,"downloadMode": "videos","sortOrder": "latest","textFormat": "plain","targets": ["https://onlyfans.com/oftv/videos"]}
🧾 Output
Output fields
Each saved row is either a media row or a text-only post row. Each row type has its own table below.
Media row fields
| Field | Type | What it does |
|---|---|---|
resultType | string | Always media for a media row. |
target | string | Shows the submitted target that led to this media item. |
profileUsername | string | Shows the creator's OnlyFans username. |
profileDisplayName | string or null | Shows the creator's display name when available. |
profileId | string or null | Shows the creator's source ID when available. |
profileUrl | string | Links to the creator's OnlyFans profile. |
profileAvatarUrl | string or null | Links to the creator's avatar when available. |
profileVerified | boolean or null | Says whether OnlyFans marks the creator as verified, when available. |
postId | string or null | Shows the parent post's source ID when available. |
postUrl | string or null | Links to the parent OnlyFans post when available. |
postText | string or null | Shows the parent post's text in the chosen textFormat when available. |
publishedAt | date-time string or null | Shows when the parent post was published when available. |
likesCount | integer or null | Shows the parent post's like count when available. |
linkedUserIds | array of strings | Lists the source IDs of users linked in the post. It is [] when there are none. |
mentionedUserIds | array of strings | Lists the source IDs of users mentioned in the post. It is [] when there are none. |
mediaId | string | Shows the source ID used to identify the media item. |
mediaType | string | Says whether the media is a photo, video, or unknown. |
mediaUrl | string | Gives the source-hosted URL for the media file. |
thumbnailUrl | string or null | Gives the media thumbnail URL when available. |
durationSeconds | number or null | Gives the media length in seconds when available. |
width | integer or null | Gives the media width in pixels when available. |
height | integer or null | Gives the media height in pixels when available. |
mediaVariants | array of objects | Lists distinct additional source-hosted versions of the same media item, excluding the main file and thumbnail. It is [] when no additional version is available. |
mediaVariants.url | string | Gives the source URL for this additional media version. |
mediaVariants.height | integer or null | Gives this media version's height in pixels when available. |
Example media row
This complete row is a genuine example from a successful run:
{"resultType": "media","target": "https://onlyfans.com/oftv/videos","profileUsername": "oftv","profileId": "82517634","profileDisplayName": "OFTV","profileUrl": "https://onlyfans.com/oftv","profileAvatarUrl": "https://public.onlyfans.com/files/i/iq/iq5/iq5mc3hvgh4uq3rgdx8xrnvugxymbhiz1667246997/82517634/avatar.jpg","profileVerified": true,"postId": "2829420167","postUrl": "https://onlyfans.com/2829420167/oftv","postText": "I Took a Pro Bodybuilder to Pilates! | Chilling With Rosie Payback time! @rosie.knight.x puts @fitnessbarbiex through her first-ever Pilates session after surviving her brutal gym workout. Heavy lifting is one thing, but can she handle the burn of Pilates? Watch here: https://of.tv/v/2ezVe onlyfans.com/rosie.knight.x / onlyfans.com/fitnessbarbiex","publishedAt": "2026-10-25T23:00:29+00:00","likesCount": 38,"linkedUserIds": ["340674489","462428872"],"mentionedUserIds": ["340674489","462428872"],"mediaId": "4755384251","mediaType": "video","mediaUrl": "https://cdn2.onlyfans.com/files/b/b7/b717a95bcfcf024394d242f5dfdb51fd/0ii8cb8yrom8lkfl2h1ec_source.mp4?Tag=2&u=0&Expires=1793412000&Signature=homSG4MhjTJoPW~7ubMa~RfU3OQTTQf9G2ZXeUuVxkUMw3uFiwBb31UW6oB1GheOwfGDZW1xKcvvD9Ku3nYLo7NP9D5oRAmuCui71ad3~RFl2VycwSSoC1MgdkoCls087~uO3JiZNnuLFmlTS92KdwqD~kRX3mlXv9VL4rpHoFg-ZljlxI2b-3AnW5khHZMh~DdTgrW7BWhiXoa5FhfD49W0PEkSAzuP0iDkFzp5vwozrfFsMYtAiSxwqoldrHVYrekd0GDtCyYqnnRjT-x77uxnuIQCa-pcvbKaSREK-2jlddaWEuvQVwYejqse3s6YJvEZ7KeNuhmmhQYXhkfCpA__&Key-Pair-Id=APKAUSX4CWPPEEDS2V6V","thumbnailUrl": "https://cdn2.onlyfans.com/files/f/f3/f3e155a343fa369f351a2dc98adceb4f/960x540_734bf4581f13a85a0f04ad73f95ed162.jpg?Tag=2&u=0&Expires=1793412000&Signature=LyDzjMkFrYRl-uyl9bWDWaIWd0kZF9sF2wWP6JMGAxJSXNjVjBY1SG~w825-mwuMG1reqg8ijhGQsgLvV-ps5zyPmM0G4c6ozXyEmWdPXTRpmgOKPxfFL9E98tj9wLi~5Z-Vlj2mm6~wRDo29qaRI9ceQ13HXlA5dSYi6kJRvwJuipNx1R65cwlc6DW3W5ZTzqtOHCi6qbaiK0ylLa5UNNh6v~adBO8xFuWMeU3IDacM0~DLCvUOUD1lo6CLNGNRoLa2iYFhaP6~1E7cKL8Kgib9wAwC3Ju7T9Zkx30kM0mO3xubuRQBSkSZzzCYBhxNlyk81Z0xxQlJXedEac8XGA__&Key-Pair-Id=APKAUSX4CWPPEEDS2V6V","durationSeconds": 233,"width": 1920,"height": 1080,"mediaVariants": [{"url": "https://cdn2.onlyfans.com/files/a/ae/ae9e67c8934328e295a008b9454ef9b4/0ii8cb8yrom8lkfl2h1ec_240p.mp4?Tag=2&u=0&Expires=1793412000&Signature=dTtiLhs~xaNDl7H6kJcyf~69KLVrbexbO0pVFL1ULZn6thfMc0kSrI10I~6tBRhzF8vUPpTo-p5aAf0iLZ0jytG4m4HN9qA4vAaL~oEJlq1Heew~7bKiHraOoKiXrDk~FmEe27ebGMpoB6VwwgRCZRRWdzlpQDaDESSG-ydMLdgK5-PCuMrD7M589kQn0cNVCKEYcgak5jaFUFoeZt6IoA-f4Jxuu3KUV5Akps8FRQlUvEYLJRI4J~6OzSoqu7EoDliXz7mL7rsRjjsSuKO4Z-Yum7yatwAS3PQb2c1oVYapJnGliVn6NNChHEJ5o88X4oWL5KVnhY3jQ~paO29tAQ__&Key-Pair-Id=APKAUSX4CWPPEEDS2V6V","height": 240},{"url": "https://cdn2.onlyfans.com/files/8/89/89ccdc9f297f70eaeb58dff850fc4a54/0ii8cb8yrom8lkfl2h1ec_720p.mp4?Tag=2&u=0&Expires=1793412000&Signature=atODXCokkrr7SQs6H1OhN3pbFwT4aeduwoytbV-tbUM0JbkLNFHPnnosKMIBsifvrtGAXLmdEZefnTHS3O9vTP~Zix7sTiU8ZokvsEQ5knYfqbGXTAMx34BC2oPYbD5slC1jYh5vuhShOIN77y4BW9XF0te-b~gTFzNBoyM5gFzFup3cyVfm98xUTe~kSgq7LVZ~1kC~0kKL1GR13g3zP3vztyVpNbDWWWZp8XaQE3dUlHDVdcL~vFWoSBA19LYxCS5hYQgsSY74b6~Ct~CwgBfouoY7-Rpdlsc-3GME9-o7U3GPZv2g3-bc7bdJXMlQVoXwMq5pMCCCDJ4lpqbPGw__&Key-Pair-Id=APKAUSX4CWPPEEDS2V6V","height": 720}]}
Text-only post row fields
A text-only post row has no media link. It keeps the post and creator details, and its media fields are null.
| Field | Type | What it does |
|---|---|---|
resultType | string | Always textPost for a text-only post row. |
target | string | Shows the submitted post URL that led to this post. |
profileUsername | string | Shows the creator's OnlyFans username. |
profileDisplayName | string or null | Shows the creator's display name when available. |
profileId | string or null | Shows the creator's source ID when available. |
profileUrl | string | Links to the creator's OnlyFans profile. |
profileAvatarUrl | string or null | Links to the creator's avatar when available. |
profileVerified | boolean or null | Says whether OnlyFans marks the creator as verified, when available. |
postId | string | Shows the post's source ID. |
postUrl | string or null | Links to the OnlyFans post when available. |
postText | string | Shows the post's text in the chosen textFormat. |
publishedAt | date-time string or null | Shows when the post was published when available. |
likesCount | integer or null | Shows the post's like count when available. |
linkedUserIds | array of strings | Lists the source IDs of users linked in the post. It is [] when there are none. |
mentionedUserIds | array of strings | Lists the source IDs of users mentioned in the post. It is [] when there are none. |
mediaId | null | Always null for a text-only post. |
mediaType | null | Always null for a text-only post. |
mediaUrl | null | Always null for a text-only post. |
thumbnailUrl | null | Always null for a text-only post. |
durationSeconds | null | Always null for a text-only post. |
width | null | Always null for a text-only post. |
height | null | Always null for a text-only post. |
mediaVariants | array | Always [] for a text-only post. |
Dataset exports
Export the dataset as JSON, CSV, Excel, XML, RSS, or HTML. You can also read it through the Apify API. Source-hosted links in the row can expire, so use them while they are available.
💳 Pricing
Charged events
This Actor uses pay-per-event pricing. You pay once for each media link saved to the dataset. You also pay once for each text-only post saved, which costs slightly less than a media link. A target that saves no rows creates no charge. This includes a skipped target, a subscription-only profile, and a target that could not be read.
Control run size
Use a small maxMediaPerTarget value when you want a short run. Leave it empty or use 0 to return all available results until the source is exhausted.
🔌 Integrations
Ways to use the output
Run the Actor in Apify Console, use the Apify API, schedule repeat runs, add webhooks for run events, or connect the dataset to Apify integrations.
❓ FAQ
What happens when the same media is found more than once?
The Actor saves the first eligible occurrence and ignores later matches of that same source item. The saved row keeps the target and source details from the first match.
What happens with a profile that needs a subscription?
The Actor saves no rows for it and says in the log that the profile shows its media only to paying subscribers. It does not retry that profile, and the other targets keep running. You are not charged for it.
Why did a valid target return no rows?
It may have no posts, or no media that matches your media kind or date range. A public page may also have no media you can view without a subscription.
Can I sort by tips and use a date range?
No. The tips orders work only without a start or end date. If you pick a tips order with a date range, the run saves no rows and the log tells you why. You are not charged. To use a date range, pick a date or like order.
Why was my target skipped?
The Actor skips a target that is not a profile, section, or post, such as two links joined into one entry or a signed-in account page. It also skips a target that OnlyFans says does not exist. Put each username or URL in its own entry and check the spelling.
What happens when OnlyFans is slow or cannot be read?
The Actor retries temporary source problems, up to 11 attempts for each target. It then names the target in the log and continues with the next one. If a target stays unreadable and no other target could be finished, the run fails instead of showing a generic empty result.
Can one invalid target stop the other targets?
No. The Actor reports invalid, unavailable, or unreadable targets and continues with the other targets.
Do I need a GitHub script or my own code?
No. The Actor runs on Apify, so you do not install an OnlyFans downloader from GitHub. You can still start runs and read the dataset from your own code through the Apify API.
Can it read paid, private, or message media?
No. The Actor uses public page access and does not take an OnlyFans session. It does not bypass a paywall, private profile, or message access rule.
Does it download or store media files?
No. It saves source-hosted URLs and metadata, but it does not copy or host the files. Use the links soon because the source can change or expire them.
Do the source-hosted links stay valid forever?
No. The source can change or expire a link after the run. Use or refresh important links while they are available.
Does it need an OnlyFans login or API key?
No. The public input uses usernames and supported public URLs. The Actor does not ask for an OnlyFans session or API key and does not unlock private content.
What should I check before using public media links?
Review OnlyFans terms, copyright rules, and local law before using or sharing source data. The Actor only reads public pages, does not bypass access rules, and leaves media files at the source.
Can I use it on Android, Firefox, or another device?
Yes, through Apify Console or the Apify API. This Actor is not a browser extension or mobile app, and device choice does not unlock more OnlyFans content.
Can I use the output with ChatGPT or Perplexity?
You can export the dataset and use suitable text fields in your own tools. The Actor does not send data to ChatGPT or Perplexity.
📝 Changelog
v4.0 (29-10-2026)
mediaTypeno longer returnsaudioorstream. That media now shows asunknown. If you filter rows by those two values, useunknowninstead.- Adds a
resultTypefield that says whether a row ismediaortextPost. - Text-only post rows now have their own "Text-only post" event, priced a little lower than a media link.
- Adds
profileVerified,linkedUserIds, andmentionedUserIdsto rows, when available. - Adds "Least liked first" and "Lowest tips first" post orders.
- Adds a "Post text format" choice: plain text, Markdown, or original HTML.
- "Max results per input" counts text-only post rows too. Use
0or leave it empty to get all available results. - Targets that need a paid subscription, have no posts, or do not exist now get one warning with no retries. The run goes on with other targets and does not fail because of them.
- Reliability improvements.
v3.1 (14-10-2026)
- Shows post text in the default output table.
- "Media from posts" now collects media from public profile pages.
- Skips invalid targets, such as two links joined by a space or a signed-in account page, and warns about each one. These targets no longer fail the run.
- Waits for the retry time that OnlyFans sends when it limits requests.
- Attempts on paid or private profiles that cannot be read end sooner.
- Stops sooner when a run is aborted.
- Runs need at least 2048 MB of memory, which is also the default.
v3.0 (21-09-2026)
- Fails clearly after retries when every submitted target stays unreadable, while mixed runs keep rows from usable targets.
- Media variant entries now contain the source URL and height without a separate width field.
v2.0 (01-09-2026)
- Continues with usable targets when another target cannot be accessed, keeps the rows already saved, and names the affected target in run diagnostics.
- Charges only for media links saved to the dataset.
- Uses a focused media-link output format with creator, post, thumbnail, media type, duration, dimensions, and source details.
v1.0
- Improves access to public OnlyFans media and reports persistent source problems clearly.
- Focuses collection on video, photo, all-media, and post-media links with source details.
v0.1
- Initial release.
🆘 Support
For issues, questions, or feature requests, file a ticket and I'll fix or implement it in less than 24h 🫡
🔗 Related Actors
- OnlyFans Profile Scraper: collect public OnlyFans creator profile details, such as bios, verification, and content counts.
- Fansly Profile Scraper: find public Fansly creator profiles by keyword or look up known profile identifiers for creator research.
- ManyVids Video Downloader: resolve known public ManyVids video pages into source-hosted media links and creator details.
- EroThots Video Downloader: get direct MP4 links and quality details from known public EroThots videos.
- RedGifs Bulk Video Downloader: resolve public RedGifs links or IDs in bulk into direct MP4 links and video details.
Made with ❤️ by Maxime Dupré