Skip to content
    ↑↓ to choose · Enter to open

    · 14 min read

    Wattpad Story Scraper: Up to 1,000 Free Results a Month (2026)

    By CrawlerBros Engineering Team

    Each story record carries up to 46 fields including title, description, categories, and deep engagement statistics like readCount and voteCount. When running in chapter text mode, the output returns clean, plain-text chapter bodies with paragraph breaks preserved, containing 16 descriptive fields such as wordCount and characterLength. This setup is built for researchers tracking fanfiction trends, platform developers building mobile reading feeds, and curators archiving public web fiction. It is not for anyone who needs to extract reader comments or curated reading lists, as those require authentication and are excluded from the dataset.

    Try it before you read further. Apify's free plan includes $5.00 of usage every month with no credit card, enough for up to 1,000 results at $0.005 each before platform usage. Open Wattpad Story Scraper on Apify and run the prefilled example.

    How reliable is Wattpad Story Scraper in production?

    Across the last 30 days of public runs on the Apify platform, Wattpad Story Scraper recorded 1,726 runs with the following outcomes.

    Outcome Runs Share
    Succeeded 1,725 99.9%
    Failed 1 0.1%
    Aborted by the user 0 0.0%
    Timed out 0 0.0%
    Total 1,726 100.0%

    A failure rate of about 0.1% means that roughly one run in a thousand will fail or time out, indicating extremely consistent behavior for scheduled tasks. When scheduling this Actor unattended, standard retries are sufficient to manage these rare occurrences. You do not need to build complex error-handling workflows because the execution is structurally reliable.

    What does it cost to run Wattpad Story Scraper?

    Each result costs $0.005 on Apify's free plan, which is $5.00 per 1,000 results. Starting a run is charged separately at $0.005 per GB of Actor memory. Apify also bills the platform usage each run consumes, at the rates of your Apify plan, on top of these charges.

    Apify plan Per result Per 1,000 results
    FREE $0.005 $5.00
    BRONZE $0.00433 $4.33
    SILVER $0.00367 $3.67
    GOLD $0.003 $3.00
    PLATINUM $0.003 $3.00
    DIAMOND $0.003 $3.00

    Worked example: collecting 10,000 results costs $50.00 in result charges before run-start fees and platform usage. With 0.1% of runs failing or timing out in the last 30 days, budget for re-running a portion of those batches rather than assuming every run completes.

    The main driver of your bill is the maxItems setting, which restricts the total number of records written to your dataset. To keep your API consumption low while validating your setup, run the Actor with maxItems set to 5 before launching full-scale runs.

    How do you run Wattpad Story Scraper from the API?

    The schema marks 1 of its 16 controls as required: mode. Every value in the payload below comes from the published schema's own prefills, which means you can paste it, swap the token, and get a real result.

    Call the synchronous endpoint to start a run and receive dataset items in one request:

    curl -X POST "https://api.apify.com/v2/acts/crawlerbros~wattpad-story-scraper/run-sync-get-dataset-items?token=$APIFY_TOKEN" \
      -H "Content-Type: application/json" \
      -d '{"mode":"search","tags":["werewolf"]}'
    

    The same run from Python, using the official client:

    from apify_client import ApifyClient
    
    client = ApifyClient("<YOUR_APIFY_TOKEN>")
    
    run_input = {
      "mode": "search",
      "tags": [
        "werewolf"
      ]
    }
    
    run = client.actor("crawlerbros~wattpad-story-scraper").call(run_input=run_input)
    
    for item in client.dataset(run["defaultDatasetId"]).iterate_items():
        print(item)
    

    And from Node.js:

    import { ApifyClient } from 'apify-client'
    
    const client = new ApifyClient({ token: '<YOUR_APIFY_TOKEN>' })
    
    const input = {
      "mode": "search",
      "tags": [
        "werewolf"
      ]
    }
    
    const run = await client.actor('crawlerbros~wattpad-story-scraper').call(input)
    const { items } = await client.dataset(run.defaultDatasetId).listItems()
    console.log(items)
    

    That endpoint blocks until the run completes. Fine while you are testing a handful of records, risky once a run takes minutes: a dropped connection loses the response even though the run itself finished. Switch to an asynchronous start with polling or a webhook before you schedule anything.

    Which Wattpad Story Scraper inputs matter, and which can you skip?

    The mode control is the critical parameter that dictates which data endpoints are targeted, such as search, byTag, or chapterText. Most users should leave completedOnly and freeOnly off on initial runs to ensure they see the widest sample of active stories before applying narrowing criteria.

    • mode (string): What to fetch. Default: "search".
    • tags (array): One or more Wattpad tags, without the # (e.g. werewolf, slowburn). Results from each tag are merged and de-duplicated. Default: [].
    • searchQuery (string): Free-text query, e.g. a title, keyword, or theme. Default: "romance".
    • category (string): Filter to a single Wattpad genre. Required for mode=byCategory; optional narrowing filter for mode=search. Default: "".
    • language (string): Filter stories to a single language. Leave blank for any language. Default: "".
    • storyIds (array): Numeric Wattpad story IDs (e.g. 358371807) or full story URLs (e.g. https://www.wattpad.com/story/358371807-whispers-of-romance). Default: [].
    • username (string): Wattpad username or profile URL. Each returned story is enriched with the author's public profile (bio, location, follower/following counts, votes received, join date).
    • feed (string): Narrows a genre browse to a specific curated feed. new returns the most recently updated stories in the genre; leaving this blank returns Wattpad's default (most-popular) ordering. Default: "".
    • partIds (array): Numeric Wattpad chapter ("part") IDs or chapter URLs, e.g. 1406121589 or https://www.wattpad.com/1406121589-whispers-of-romance-character-sketch. Default: [].
    • completedOnly (boolean): Only emit stories the author has marked as complete. Default: false.
    • freeOnly (boolean): Exclude stories that use Wattpad's paid-story (coins) model. Default: false.
    • includeMatureContent (boolean): If disabled, drop stories the author has self-flagged as mature. Wattpad's own maturity flag is self-reported and not exhaustive. Default: true.

    The other 4 controls, with their defaults, are listed in the input schema on Wattpad Story Scraper on Apify.

    Fixed-choice controls: mode accepts search (Search stories by keyword), byCategory (Browse by genre/category), byTag (Browse by tag (hashtag)), byIds (Lookup stories by ID or URL), byUser (List all stories by a username), chapterText (Fetch full chapter text by ID or URL); category accepts 23 values (default ""), including "" (Any genre), 1 (Teen Fiction), 2 (Poetry), 3 (Fantasy); language accepts 27 values (default ""), including "" (Any language), 1 (English), 2 (French), 3 (Italian); feed accepts "" (Default (most popular)), new (Recently updated / newest).

    What does Wattpad Story Scraper return?

    The returned records are optimized for analyzing reading engagement, mapping community metadata, and exporting complete story chapters as plain text. The dataset does not contain comment text or user-curated reading lists, as these endpoints cannot be accessed without an active login session.

    Output per story

    • storyId, title, description
    • authorUsername, authorUrl, authorFullname, authorAvatarUrl, authorVerified (detail mode)
    • authorBio, authorLocation, authorGender, authorFollowers, authorFollowing, authorVotesReceived, authorNumStoriesPublished, authorNumLists, authorVerifiedEmail, authorAmbassador, authorJoinedAt, authorWebsite, authorFacebook, authorBackgroundUrl, authorDeeplink (mode=byUser only - from the author's public profile)
    • categories[] - genre names (e.g. Romance, Werewolf, Fanfiction)
    • tags[] - free-form community tags
    • language, languageId
    • completed, mature, isPaywalled, paidModel
    • numParts, storyLength, voteCount, readCount, commentCount
    • coverUrl, storyUrl
    • createdAt, modifiedAt, lastUpdatedAt, firstPublishedAt (detail mode)
    • chapters[] - full chapter list with partId, title, url, length, voteCount, readCount, commentCount (detail mode, byIds)
    • copyrightCode (detail mode)
    • recordType: "story", scrapedAt

    Output per chapter (mode=chapterText)

    • partId, storyId, chapterTitle, chapterUrl, storyUrl
    • chapterText - full plain-text chapter body
    • wordCount, characterLength
    • voteCount, readCount, commentCount, draft
    • publishedAt, updatedAt
    • recordType: "chapter", scrapedAt

    These are the documented fields. Optional ones can be empty on a given record, so measure how often each field your deliverable depends on is populated across a real sample before automating the handoff.

    How do you build the workflow end to end?

    Open Wattpad Story Scraper and work through these in order. Each step ends with something to check, so a bad configuration surfaces on a small run rather than a scheduled one.

    1. Run once with mode set to search and maxItems set to 5 to check that the returned records populate categories and tags correctly.
    2. Verify the output format for storyUrl before scaling up to ensure your downstream parser handles standard Wattpad story links.
    3. Use mode set to byCategory and category set to 4 (Romance) with feed set to new to confirm the recently updated feed returns expected results.
    4. Perform a detail lookup using mode set to byIds and storyIds set to 358371807 to check that the record populates the nested chapters array with valid partId elements.
    5. Run in mode set to chapterText with partIds set to 1406121589 to inspect the formatting of paragraph breaks in chapterText.
    6. Widen your collection by adding multiple items to storyIds, keeping maxItems within the 500 limit for a single execution.

    How do you apply it? Three worked playbooks

    These are Wattpad Story Scraper's own documented use cases, each worked through as an operating pattern rather than a description.

    Use case 1: Reading apps

    Outcome: Build genre/tag-based discovery feeds from real Wattpad catalog data

    Configure: mode="byCategory", category="4", language="1", feed="new", maxItems=50

    Working method: Run the Actor for category 4 (Romance) using the new feed to fetch recently updated English stories. Verify that the returned list contains populated coverUrl and storyUrl fields, then merge these records into your application's feed cache. Repeat this weekly to maintain fresh content.

    Deliverable: A structured JSON feed of newly updated story profiles with active cover URLs, reading metrics, and canonical story links.

    Stop condition: The categories array does not contain Romance or the returned list is completely empty.

    Use case 2: Content research

    Outcome: Analyze trending tags, tropes, and genre popularity

    Configure: mode="byTag", tags=["werewolf"], sortBy="mostReads", maxItems=100

    Working method: Query Wattpad by specific community hashtags using mode=byTag. Aggregate the tags array from all returned records to rank co-occurring tropes. Compare the readCount and voteCount values to gauge relative user engagement across different themes.

    Deliverable: A CSV export of stories containing their tags, read counts, vote counts, and calculated engagement ratios for trend mapping.

    Stop condition: The tags array in the output contains empty arrays or readCount values are missing.

    Use case 3: Archival / backup

    Outcome: Export a story's full chapter text for offline reading or preservation

    Configure: mode="chapterText", partIds=["1406121589"], maxItems=100

    Working method: Identify the chapter IDs from a previous byIds run, then input those IDs into the partIds array in chapterText mode. Extract the plain text from chapterText, preserving the paragraph layout, and write the output directly to local files.

    Deliverable: A collection of clean plain-text documents containing the full narrative body of the targeted chapters, organized by partId.

    Stop condition: The chapterText field returned is empty or wordCount reports zero.

    What breaks, and how do you design around it?

    • No "hot"/trending filter - Wattpad's own filter=hot parameter is a documented no-op that returns the exact same ordering as no filter at all (verified by direct comparison), so it isn't exposed as a separate option. Wattpad's default byCategory ordering already is the popularity/"hot" ordering. feed=new is the one server-side feed filter that's verified to actually change results.
    • feed only applies to byCategory - the filter query parameter is silently ignored by Wattpad's search endpoint (used by search and byTag), confirmed by comparing identical result sets with and without it. Applying it there would silently do nothing, so it's scoped to byCategory only, where it's confirmed effective.
    • No comments extraction - every public comments endpoint tried (/v4/story_parts/{id}/comments, /v5/..., /api/v3/story_parts/{id}/comments) returns 400/404 without an authenticated session; commentCount is still exposed on every story/chapter, but comment text itself isn't reliably retrievable without login.
    • No curated reading lists - Wattpad's "lists" feature (/v4/story-lists, /api/v3/lists) requires an authenticated session (returns 400 anonymously) and isn't exposed.

    To navigate the absence of a trending filter, use mode=byCategory without a feed specified to fetch Wattpad's default popularity ordering. If your workflow requires chapter text for an entire book, execute a byIds query first to retrieve the nested partId list, then pass those IDs into your chapterText run.

    When should you not use Wattpad Story Scraper?

    Do not use this Actor if your project requires extracting raw reader comments or user-curated reading lists, as the anonymous API endpoints for these features consistently block access. If you need to monitor community discussions on web platforms that allow unrestricted public scraping, use the Discourse Community Scraper instead. If your project demands book discovery focused specifically on retail deals, publisher metadata, and direct e-reader purchase links, look to the Freebooksy Scraper. For tracking social narratives on network platforms that rely heavily on ephemeral visual content, consider the Snapchat User Stories Scraper.

    What should you check before trusting the output?

    • Check that the storyId and title fields are non-null and that storyUrl matches the expected standard Wattpad URL structure.
    • Verify that the chapterText field is not empty and has a characterLength greater than 100 characters when running in chapterText mode.
    • Confirm that isPaywalled is false for all emitted records when running with freeOnly set to true.
    • Validate that no returned records have mature set to true when running with includeMatureContent set to false.
    • Stop scheduled runs if more than 5% of lookup IDs return 0 records instead of resolving to a valid story metadata block.

    None of this proves a record is correct. It gives a scheduled Wattpad Story Scraper run defined points where it should stop instead of quietly passing bad data downstream.

    Frequently asked questions

    Does this scraper require me to upload Wattpad cookies or accounts?

    No. All operations, including searching, browsing genres, and fetching full chapter text, are executed using public API endpoints. This means you do not need to provide passwords, session cookies, or API keys to retrieve data.

    What is the billing model and run cost for this tool?

    Each result returned costs $0.005 on Apify's free plan, which translates to $5.00 per 1,000 results. There is also a platform usage charge billed on top of the results written to your dataset, which is charged every time a run starts.

    Can I extract the comment section of a story using this Actor?

    No. Wattpad's public endpoints for comment data require user authentication and return errors when queried anonymously. While you can retrieve the commentCount for stories and chapters, the actual text of comments is not included.

    What happens if a run fails or times out?

    With only 1 failed run out of 1,726 in the last 30 days, failures are rare. If a run does fail, it is usually due to temporary platform changes, and simply restarting the run or enabling standard retries will resolve the issue.

    How do I download the complete text for an entire book?

    First, run the Actor in byIds mode using the story URL to retrieve the full list of chapters and their partId values. Then, pass those chapter IDs into a second run with mode set to chapterText to pull the full text.

    Where to go next

    When you are ready to run it, open Wattpad Story Scraper on Apify; the free plan covers up to 1,000 results a month.

    Other Actors we maintain for related data:

    Related guides:

    Resources

    • Actor documentation, input schema, and pricing: verified against the published Actor on 2026-09-25.

    • Actor last updated by its maintainers on 2026-07-05.

    • Run outcome figures cover the 30 day public window ending 2026-09-25.

    • Wattpad Story Scraper on Apify

    Featured actors

    Wattpad Story Scraper

    Scrape Wattpad stories - search by keyword, browse by genre or tag, fetch full story metadata and chapter lists by ID, list a user's stories, or pull full chapter text.

    Run on Apify ↗