Post

Medium API Data Scraping|Bypass Cloudflare Verification Efficiently

Discover how to efficiently scrape data from Medium's GraphQL Private API, backup articles, and bypass Cloudflare verification blocks to ensure uninterrupted data access and reliable content backup.

Medium API Data Scraping|Bypass Cloudflare Verification Efficiently

This post was translated with AI assistance — let me know if anything sounds off!

Table of Contents


The Journey of Crawling Medium API Data and Battling Cloudflare Defenses

Using Medium GraphQL Private API to Scrape Data, Backup Articles, and Bypass Cloudflare Verification Blocks.

Background

Since I started writing on Medium in 2018, by around 2022 I had accumulated over 50 articles, nearly 60,000 words, and about 3 GB of article images (by 2025, over 120 articles/100,000+ words/6 GB+ images); no backups! no backups! no backups! Because I always wrote directly on Medium (the editor is really good), I published immediately after writing without any local backups.

At that time, a sense of unease arose: what if Medium shut down one day and my articles disappeared? (And Medium had been struggling for years, not making money) Or what if my account suddenly got suspended and all my hard work was lost?

So that year, I started researching how to scrape Medium data, especially article content and how to download backups.

Medium HTML ❌

The structure is very complex, prone to changes, and slow to crawl. Directly using a browser to scrape content is the worst approach.

Medium Official API ❌

Warning The Medium API is no longer supported. We do not recommend using it.

Medium once provided an official API, but it was likely discontinued shortly after launch. It is assumed this was due to different product goals—Medium aims to keep content within its own platform rather than allowing external access through an API.

Medium Unofficial API 🤔

Since the official API is not provided, some developers have created external API interfaces for users in need; however, I suspect the underlying principle is still calling the Medium Private API, just with an additional layer of encapsulation that converts your requests into Private API calls to fetch the original data.

The fee is not cheap, about $USD 5 for every 2,500 requests ; this service has been running for quite a while, but since it ultimately calls the Medium Private API, I might as well sniff and call it myself.

Medium Private API ✅

What is a Private API? It is an API interface not intended for external use, undocumented, may be disabled at any time, and may carry legal risks; basically, directly observing the website/App behavior to find the corresponding API calls and writing your own code to reuse this API to fetch data for your own service.

https://medium.com/_/graphql

By sniffing network requests, we can find that all Medium APIs use the https://medium.com/_/graphql endpoint. As long as we can call this in our own program and get the same data, this approach will work.

Medium Private API — Sniffing Medium GraphQL (Example: Getting Follower Count)

My first application is to crawl my follower count and display it on my portal site.

link.zhgchg.li :

Therefore, I must scrape the follower count of my account on Medium.

  • First, open the browser’s “Developer Mode” (Chrome -> Right-click -> Inspect), switch to the “Network” tab, check “Preserve log,” and enter “graphql” in the search box.

  • Go to the Medium account followers page: https://medium.com/@YOUR_USER_NAME/followers
    Only this format of follower URL can be sniffed; https://YOUR_USER_NAME.medium.com/followers does not call the Followers API.

  • Check each “graphql” request on the left, search for the keyword “followerCount” in the “Response” data, and find the request where the username matches the webpage’s username and the follower count matches the number shown on the page. This is the target request.

  • After finding the target API, switch to Payload -> View Source -> copy all the following content.

Now that we have the Medium followers API & Payload, let’s test it with Postman!

Medium Get Followers Count Endpoint — Request & Response

Endpoint:

1
POST https://medium.com/_/graphql

Authorization: No authorization required (No need to include Token or set cookies)

Payload:

1
2
3
4
5
6
7
8
9
10
[
    {
        "operationName": "UserFollowers",
        "variables": {
            "id": null,
            "username": "zhgchgli"
        },
        "query": "query UserFollowers($username: ID, $id: ID, $paging: PagingOptions) {\n  userResult(username: $username, id: $id) {\n    __typename\n    ... on User {\n      id\n      followersUserConnection(paging: $paging) {\n        pagingInfo {\n          next {\n            from\n            limit\n            __typename\n          }\n          __typename\n        }\n        users {\n          ...FollowList_publisher\n          __typename\n        }\n        __typename\n      }\n      ...UserCanonicalizer_user\n      ...FollowersHeader_publisher\n      ...NoFollows_publisher\n      __typename\n    }\n  }\n}\n\nfragment collectionUrl_collection on Collection {\n  id\n  domain\n  slug\n  __typename\n}\n\nfragment CollectionAvatar_collection on Collection {\n  name\n  avatar {\n    id\n    __typename\n  }\n  ...collectionUrl_collection\n  __typename\n  id\n}\n\nfragment SignInOptions_collection on Collection {\n  id\n  name\n  __typename\n}\n\nfragment SignUpOptions_collection on Collection {\n  id\n  name\n  __typename\n}\n\nfragment SusiModal_collection on Collection {\n  name\n  ...SignInOptions_collection\n  ...SignUpOptions_collection\n  __typename\n  id\n}\n\nfragment PublicationFollowButton_collection on Collection {\n  id\n  slug\n  name\n  ...SusiModal_collection\n  __typename\n}\n\nfragment PublicationFollowRow_collection on Collection {\n  __typename\n  id\n  name\n  description\n  ...CollectionAvatar_collection\n  ...PublicationFollowButton_collection\n}\n\nfragment userUrl_user on User {\n  __typename\n  id\n  customDomainState {\n    live {\n      domain\n      __typename\n    }\n    __typename\n  }\n  hasSubdomain\n  username\n}\n\nfragment UserAvatar_user on User {\n  __typename\n  id\n  imageId\n  membership {\n    tier\n    __typename\n    id\n  }\n  name\n  username\n  ...userUrl_user\n}\n\nfragment isUserVerifiedBookAuthor_user on User {\n  verifications {\n    isBookAuthor\n    __typename\n  }\n  __typename\n  id\n}\n\nfragment SignInOptions_user on User {\n  id\n  name\n  imageId\n  __typename\n}\n\nfragment SignUpOptions_user on User {\n  id\n  name\n  imageId\n  __typename\n}\n\nfragment SusiModal_user on User {\n  ...SignInOptions_user\n  ...SignUpOptions_user\n  __typename\n  id\n}\n\nfragment useNewsletterV3Subscription_newsletterV3 on NewsletterV3 {\n  id\n  type\n  slug\n  name\n  collection {\n    slug\n    __typename\n    id\n  }\n  user {\n    id\n    name\n    username\n    newsletterV3 {\n      id\n      __typename\n    }\n    __typename\n  }\n  __typename\n}\n\nfragment useNewsletterV3Subscription_user on User {\n  id\n  username\n  newsletterV3 {\n    ...useNewsletterV3Subscription_newsletterV3\n    __typename\n    id\n  }\n  __typename\n}\n\nfragment useAuthorFollowSubscribeButton_user on User {\n  id\n  name\n  ...useNewsletterV3Subscription_user\n  __typename\n}\n\nfragment useAuthorFollowSubscribeButton_newsletterV3 on NewsletterV3 {\n  id\n  name\n  ...useNewsletterV3Subscription_newsletterV3\n  __typename\n}\n\nfragment AuthorFollowSubscribeButton_user on User {\n  id\n  name\n  imageId\n  ...SusiModal_user\n  ...useAuthorFollowSubscribeButton_user\n  newsletterV3 {\n    id\n    ...useAuthorFollowSubscribeButton_newsletterV3\n    __typename\n  }\n  __typename\n}\n\nfragment UserFollowRow_user on User {\n  __typename\n  id\n  name\n  bio\n  ...UserAvatar_user\n  ...isUserVerifiedBookAuthor_user\n  ...AuthorFollowSubscribeButton_user\n}\n\nfragment FollowsHeader_publisher on Publisher {\n  __typename\n  id\n  name\n  ... on Collection {\n    ...collectionUrl_collection\n    __typename\n    id\n  }\n  ... on User {\n    ...userUrl_user\n    __typename\n    id\n  }\n}\n\nfragment FollowList_publisher on Publisher {\n  id\n  ... on Collection {\n    ...PublicationFollowRow_collection\n    __typename\n    id\n  }\n  ... on User {\n    ...UserFollowRow_user\n    __typename\n    id\n  }\n  __typename\n}\n\nfragment UserCanonicalizer_user on User {\n  id\n  username\n  hasSubdomain\n  customDomainState {\n    live {\n      domain\n      __typename\n    }\n    __typename\n  }\n  __typename\n}\n\nfragment FollowersHeader_publisher on Publisher {\n  ...FollowsHeader_publisher\n  ... on Collection {\n    subscriberCount\n    __typename\n    id\n  }\n  ... on User {\n    socialStats {\n      followerCount\n      __typename\n    }\n    __typename\n    id\n  }\n  __typename\n}\n\nfragment NoFollows_publisher on Publisher {\n  id\n  name\n  __typename\n}\n"
    }
]

username : Replace with the username you want to query.

Postman :

  • POST https://medium.com/_/graphql

  • Body -> raw -> JSON

Response:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
[
    {
        "data": {
            "userResult": {
                "__typename": "User",
                "id": "8854784154b8",
                "followersUserConnection": {
                    "pagingInfo": {
                        "next": {
                            "from": "1140babdfef7",
                            "limit": 8,
                            "__typename": "PageParams"
                        },
                        "__typename": "Paging"
                    },
                    "users": [
                        ///.. omitted
                    ],
                    "__typename": "UserConnection"
                },
                "username": "zhgchgli",
                "hasSubdomain": true,
                "customDomainState": {
                    "live": {
                        "domain": "zhgchgli.medium.com",
                        "__typename": "CustomDomain"
                    },
                    "__typename": "CustomDomainState"
                },
                "name": "ZhgChgLi",
                "socialStats": {
                    "followerCount": 1050,
                    "__typename": "SocialStats"
                }
            }
        }
    }
]

Key info: response[0]["data"]["userResult"]["socialStats"]["followerCount"] is the target follower count!

Ruby Demo Code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
def load_medium_followers(username)
    begin
        url = "https://medium.com/_/graphql"
        uri = URI.parse(url)

        payload = [
            {
            "operationName": "UserFollowers",
            "variables": {
                "id": nil,
                "username": username,
                "paging": nil
            },
            "query": "query UserFollowers($username: ID, $id: ID, $paging: PagingOptions) {\n  userResult(username: $username, id: $id) {\n    __typename\n    ... on User {\n      id\n      followersUserConnection(paging: $paging) {\n        pagingInfo {\n          next {\n            from\n            limit\n            __typename\n          }\n          __typename\n        }\n        users {\n          ...FollowList_publisher\n          __typename\n        }\n        __typename\n      }\n      ...UserCanonicalizer_user\n      ...FollowersHeader_publisher\n      ...NoFollows_publisher\n      __typename\n    }\n  }\n}\n\nfragment collectionUrl_collection on Collection {\n  id\n  domain\n  slug\n  __typename\n}\n\nfragment CollectionAvatar_collection on Collection {\n  name\n  avatar {\n    id\n    __typename\n  }\n  ...collectionUrl_collection\n  __typename\n  id\n}\n\nfragment SignInOptions_collection on Collection {\n  id\n  name\n  __typename\n}\n\nfragment SignUpOptions_collection on Collection {\n  id\n  name\n  __typename\n}\n\nfragment SusiModal_collection on Collection {\n  name\n  ...SignInOptions_collection\n  ...SignUpOptions_collection\n  __typename\n  id\n}\n\nfragment PublicationFollowButton_collection on Collection {\n  id\n  slug\n  name\n  ...SusiModal_collection\n  __typename\n}\n\nfragment PublicationFollowRow_collection on Collection {\n  __typename\n  id\n  name\n  description\n  ...CollectionAvatar_collection\n  ...PublicationFollowButton_collection\n}\n\nfragment userUrl_user on User {\n  __typename\n  id\n  customDomainState {\n    live {\n      domain\n      __typename\n    }\n    __typename\n  }\n  hasSubdomain\n  username\n}\n\nfragment UserAvatar_user on User {\n  __typename\n  id\n  imageId\n  membership {\n    tier\n    __typename\n    id\n  }\n  name\n  username\n  ...userUrl_user\n}\n\nfragment isUserVerifiedBookAuthor_user on User {\n  verifications {\n    isBookAuthor\n    __typename\n  }\n  __typename\n  id\n}\n\nfragment SignInOptions_user on User {\n  id\n  name\n  imageId\n  __typename\n}\n\nfragment SignUpOptions_user on User {\n  id\n  name\n  imageId\n  __typename\n}\n\nfragment SusiModal_user on User {\n  ...SignInOptions_user\n  ...SignUpOptions_user\n  __typename\n  id\n}\n\nfragment useNewsletterV3Subscription_newsletterV3 on NewsletterV3 {\n  id\n  type\n  slug\n  name\n  collection {\n    slug\n    __typename\n    id\n  }\n  user {\n    id\n    name\n    username\n    newsletterV3 {\n      id\n      __typename\n    }\n    __typename\n  }\n  __typename\n}\n\nfragment useNewsletterV3Subscription_user on User {\n  id\n  username\n  newsletterV3 {\n    ...useNewsletterV3Subscription_newsletterV3\n    __typename\n    id\n  }\n  __typename\n}\n\nfragment useAuthorFollowSubscribeButton_user on User {\n  id\n  name\n  ...useNewsletterV3Subscription_user\n  __typename\n}\n\nfragment useAuthorFollowSubscribeButton_newsletterV3 on NewsletterV3 {\n  id\n  name\n  ...useNewsletterV3Subscription_newsletterV3\n  __typename\n}\n\nfragment AuthorFollowSubscribeButton_user on User {\n  id\n  name\n  imageId\n  ...SusiModal_user\n  ...useAuthorFollowSubscribeButton_user\n  newsletterV3 {\n    id\n    ...useAuthorFollowSubscribeButton_newsletterV3\n    __typename\n  }\n  __typename\n}\n\nfragment UserFollowRow_user on User {\n  __typename\n  id\n  name\n  bio\n  ...UserAvatar_user\n  ...isUserVerifiedBookAuthor_user\n  ...AuthorFollowSubscribeButton_user\n}\n\nfragment FollowsHeader_publisher on Publisher {\n  __typename\n  id\n  name\n  ... on Collection {\n    ...collectionUrl_collection\n    __typename\n    id\n  }\n  ... on User {\n    ...userUrl_user\n    __typename\n    id\n  }\n}\n\nfragment FollowList_publisher on Publisher {\n  id\n  ... on Collection {\n    ...PublicationFollowRow_collection\n    __typename\n    id\n  }\n  ... on User {\n    ...UserFollowRow_user\n    __typename\n    id\n  }\n  __typename\n}\n\nfragment UserCanonicalizer_user on User {\n  id\n  username\n  hasSubdomain\n  customDomainState {\n    live {\n      domain\n      __typename\n    }\n    __typename\n  }\n  __typename\n}\n\nfragment FollowersHeader_publisher on Publisher {\n  ...FollowsHeader_publisher\n  ... on Collection {\n    subscriberCount\n    __typename\n    id\n  }\n  ... on User {\n    socialStats {\n      followerCount\n      __typename\n    }\n    __typename\n    id\n  }\n  __typename\n}\n\nfragment NoFollows_publisher on Publisher {\n  id\n  name\n  __typename\n}\n"
            }
        ];

        headers = {
            "User-Agent" => "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/142.0.0.0 Safari/537.36 Edg/142.0.0.0",
            "Content-Type" => "application/json"
        }

        https = Net::HTTP.new(uri.host, uri.port)
        https.read_timeout = 30
        https.open_timeout = 10
        https.use_ssl = true

        # --- TLS / Certificate verification setup ---
        # Some OpenSSL builds/configs enable CRL checking, which can fail with:
        # "certificate verify failed (unable to get certificate CRL)".
        # Net::HTTP/OpenSSL does not automatically fetch CRLs, so we use a default
        # cert store and clear CRL-related flags to avoid hard failures while still
        # verifying the peer certificate.
        https.verify_mode = OpenSSL::SSL::VERIFY_PEER

        store = OpenSSL::X509::Store.new
        store.set_default_paths
        # Ensure no CRL-check flags are enabled by default
        store.flags = 0
        https.cert_store = store

        # Allow overriding CA bundle paths via environment variables if needed.
        if ENV['SSL_CERT_FILE'] && !ENV['SSL_CERT_FILE'].empty?
        https.ca_file = ENV['SSL_CERT_FILE']
        end
        if ENV['SSL_CERT_DIR'] && !ENV['SSL_CERT_DIR'].empty?
        https.ca_path = ENV['SSL_CERT_DIR']
        end

        # (Optional) timeouts to avoid hanging on network issues
        https.open_timeout = 10
        https.read_timeout = 30
        # --- end TLS setup ---


        req = Net::HTTP::Post.new(uri.request_uri, headers)
        req.body = JSON.dump(payload)

        res = https.request(req)

        json = JSON.parse(res.body)
        count = json&.dig(0, "data", "userResult", "socialStats", "followerCount")
        count ? count.to_i : 0
        return "1K+" unless count.to_i > 0
        return "#{count.to_s.reverse.gsub(/(\d{3})(?=\d)/, '\\1,').reverse}+"
    rescue => e
        "1K+"
    end
end

Medium Private API — Get All Articles of an Account

In the same way, we can also get the target account’s list of articles.

Graphql Query Body:

1
2
3
4
5
6
7
8
9
10
11
12
[
      {
        "operationName": "UserProfileQuery",
        "variables": {
          "homepagePostsFrom": null,
          "includeDistributedResponses": true,
          "id": "8854784154b8",
          "homepagePostsLimit": 10
        },
        "query": "query UserProfileQuery($id: ID, $username: ID, $homepagePostsLimit: PaginationLimit, $homepagePostsFrom: String = null, $includeDistributedResponses: Boolean = true) {\n  userResult(id: $id, username: $username) {\n    __typename\n    ... on User {\n      id\n      name\n      viewerIsUser\n      viewerEdge {\n        id\n        isFollowing\n        __typename\n      }\n      homePostsPublished: homepagePostsConnection(paging: {limit: 1}) {\n        posts {\n          id\n          __typename\n        }\n        __typename\n      }\n      ...UserCanonicalizer_user\n      ...UserProfileScreen_user\n      ...EntityDrivenSubscriptionLandingPageScreen_writer\n      ...useShouldShowEntityDrivenSubscription_creator\n      __typename\n    }\n  }\n}\n\nfragment UserCanonicalizer_user on User {\n  id\n  username\n  hasSubdomain\n  customDomainState {\n    live {\n      domain\n      __typename\n    }\n    __typename\n  }\n  __typename\n}\n\nfragment UserProfileScreen_user on User {\n  __typename\n  id\n  viewerIsUser\n  ...PublisherHeader_publisher\n  ...PublisherHomePosts_publisher\n  ...UserSubdomainFlow_user\n  ...UserProfileMetadata_user\n  ...SuspendedBannerLoader_user\n  ...ExpandablePost_user\n  ...useAnalytics_user\n}\n\nfragment PublisherHeader_publisher on Publisher {\n  id\n  ...PublisherHeaderBackground_publisher\n  ...PublisherHeaderNameplate_publisher\n  ...PublisherHeaderActions_publisher\n  ...PublisherHeaderNav_publisher\n  __typename\n}\n\nfragment PublisherHeaderBackground_publisher on Publisher {\n  __typename\n  id\n  customStyleSheet {\n    ...PublisherHeaderBackground_customStyleSheet\n    __typename\n    id\n  }\n  ... on Collection {\n    colorPalette {\n      tintBackgroundSpectrum {\n        backgroundColor\n        __typename\n      }\n      __typename\n    }\n    isAuroraVisible\n    legacyHeaderBackgroundImage {\n      id\n      originalWidth\n      focusPercentX\n      focusPercentY\n      __typename\n    }\n    ...collectionTintBackgroundTheme_collection\n    __typename\n    id\n  }\n  ...publisherUrl_publisher\n}\n\nfragment PublisherHeaderBackground_customStyleSheet on CustomStyleSheet {\n  id\n  global {\n    colorPalette {\n      background {\n        rgb\n        __typename\n      }\n      __typename\n    }\n    __typename\n  }\n  header {\n    headerScale\n    backgroundImageDisplayMode\n    backgroundImageVerticalAlignment\n    backgroundColorDisplayMode\n    backgroundColor {\n      alpha\n      rgb\n      ...getHexFromColorValue_colorValue\n      ...getOpaqueHexFromColorValue_colorValue\n      __typename\n    }\n    secondaryBackgroundColor {\n      ...getHexFromColorValue_colorValue\n      __typename\n    }\n    postBackgroundColor {\n      ...getHexFromColorValue_colorValue\n      __typename\n    }\n    backgroundImage {\n      ...MetaHeaderBackground_imageMetadata\n      __typename\n    }\n    __typename\n  }\n  __typename\n}\n\nfragment getHexFromColorValue_colorValue on ColorValue {\n  rgb\n  alpha\n  __typename\n}\n\nfragment getOpaqueHexFromColorValue_colorValue on ColorValue {\n  rgb\n  __typename\n}\n\nfragment MetaHeaderBackground_imageMetadata on ImageMetadata {\n  id\n  originalWidth\n  __typename\n}\n\nfragment collectionTintBackgroundTheme_collection on Collection {\n  colorPalette {\n    ...collectionTintBackgroundTheme_colorPalette\n    __typename\n  }\n  customStyleSheet {\n    id\n    ...collectionTintBackgroundTheme_customStyleSheet\n    __typename\n  }\n  __typename\n  id\n}\n\nfragment collectionTintBackgroundTheme_colorPalette on ColorPalette {\n  ...customTintBackgroundTheme_colorPalette\n  __typename\n}\n\nfragment customTintBackgroundTheme_colorPalette on ColorPalette {\n  tintBackgroundSpectrum {\n    ...ThemeUtil_colorSpectrum\n    __typename\n  }\n  __typename\n}\n\nfragment ThemeUtil_colorSpectrum on ColorSpectrum {\n  backgroundColor\n  ...ThemeUtilInterpolateHelpers_colorSpectrum\n  __typename\n}\n\nfragment ThemeUtilInterpolateHelpers_colorSpectrum on ColorSpectrum {\n  colorPoints {\n    ...ThemeUtil_colorPoint\n    __typename\n  }\n  __typename\n}\n\nfragment ThemeUtil_colorPoint on ColorPoint {\n  color\n  point\n  __typename\n}\n\nfragment collectionTintBackgroundTheme_customStyleSheet on CustomStyleSheet {\n  id\n  ...customTintBackgroundTheme_customStyleSheet\n  __typename\n}\n\nfragment customTintBackgroundTheme_customStyleSheet on CustomStyleSheet {\n  id\n  global {\n    colorPalette {\n      primary {\n        colorPalette {\n          ...customTintBackgroundTheme_colorPalette\n          __typename\n        }\n        __typename\n      }\n      __typename\n    }\n    __typename\n  }\n  __typename\n}\n\nfragment publisherUrl_publisher on Publisher {\n  id\n  __typename\n  ... on Collection {\n    ...collectionUrl_collection\n    __typename\n    id\n  }\n  ... on User {\n    ...userUrl_user\n    __typename\n    id\n  }\n}\n\nfragment collectionUrl_collection on Collection {\n  id\n  domain\n  slug\n  __typename\n}\n\nfragment userUrl_user on User {\n  __typename\n  id\n  customDomainState {\n    live {\n      domain\n      __typename\n    }\n    __typename\n  }\n  hasSubdomain\n  username\n}\n\nfragment PublisherHeaderNameplate_publisher on Publisher {\n  ...PublisherAvatar_publisher\n  ...PublisherHeaderLogo_publisher\n  ...PublisherFollowerCount_publisher\n  __typename\n}\n\nfragment PublisherAvatar_publisher on Publisher {\n  __typename\n  ... on Collection {\n    id\n    ...CollectionAvatar_collection\n    __typename\n  }\n  ... on User {\n    id\n    ...UserAvatar_user\n    __typename\n  }\n}\n\nfragment CollectionAvatar_collection on Collection {\n  name\n  avatar {\n    id\n    __typename\n  }\n  ...collectionUrl_collection\n  __typename\n  id\n}\n\nfragment UserAvatar_user on User {\n  __typename\n  id\n  imageId\n  mediumMemberAt\n  name\n  username\n  ...userUrl_user\n}\n\nfragment PublisherHeaderLogo_publisher on Publisher {\n  __typename\n  id\n  customStyleSheet {\n    id\n    header {\n      logoImage {\n        id\n        originalHeight\n        originalWidth\n        __typename\n      }\n      appNameColor {\n        ...getHexFromColorValue_colorValue\n        __typename\n      }\n      appNameTreatment\n      __typename\n    }\n    __typename\n  }\n  name\n  ... on Collection {\n    isAuroraVisible\n    logo {\n      id\n      originalHeight\n      originalWidth\n      __typename\n    }\n    __typename\n    id\n  }\n  ...CustomHeaderTooltip_publisher\n  ...publisherUrl_publisher\n}\n\nfragment CustomHeaderTooltip_publisher on Publisher {\n  __typename\n  id\n  customStyleSheet {\n    id\n    header {\n      appNameTreatment\n      nameTreatment\n      __typename\n    }\n    __typename\n  }\n  ... on Collection {\n    isAuroraVisible\n    slug\n    __typename\n    id\n  }\n}\n\nfragment PublisherFollowerCount_publisher on Publisher {\n  __typename\n  id\n  ... on Collection {\n    slug\n    subscriberCount\n    __typename\n    id\n  }\n  ... on User {\n    socialStats {\n      followerCount\n      __typename\n    }\n    username\n    __typename\n    id\n  }\n}\n\nfragment PublisherHeaderActions_publisher on Publisher {\n  __typename\n  ...MetaHeaderPubMenu_publisher\n  ... on Collection {\n    ...CollectionFollowButton_collection\n    __typename\n    id\n  }\n  ... on User {\n    ...FollowAndSubscribeButtons_user\n    __typename\n    id\n  }\n}\n\nfragment MetaHeaderPubMenu_publisher on Publisher {\n  __typename\n  ... on Collection {\n    ...MetaHeaderPubMenu_publisher_collection\n    __typename\n    id\n  }\n  ... on User {\n    ...MetaHeaderPubMenu_publisher_user\n    __typename\n    id\n  }\n}\n\nfragment MetaHeaderPubMenu_publisher_collection on Collection {\n  id\n  slug\n  name\n  domain\n  newsletterV3 {\n    slug\n    __typename\n    id\n  }\n  ...MutePopoverOptions_collection\n  __typename\n}\n\nfragment MutePopoverOptions_collection on Collection {\n  id\n  __typename\n}\n\nfragment MetaHeaderPubMenu_publisher_user on User {\n  id\n  username\n  ...MutePopoverOptions_creator\n  __typename\n}\n\nfragment MutePopoverOptions_creator on User {\n  id\n  __typename\n}\n\nfragment CollectionFollowButton_collection on Collection {\n  __typename\n  id\n  name\n  slug\n  ...collectionUrl_collection\n  ...SusiClickable_collection\n}\n\nfragment SusiClickable_collection on Collection {\n  ...SusiContainer_collection\n  __typename\n  id\n}\n\nfragment SusiContainer_collection on Collection {\n  name\n  ...SignInOptions_collection\n  ...SignUpOptions_collection\n  __typename\n  id\n}\n\nfragment SignInOptions_collection on Collection {\n  id\n  name\n  __typename\n}\n\nfragment SignUpOptions_collection on Collection {\n  id\n  name\n  __typename\n}\n\nfragment FollowAndSubscribeButtons_user on User {\n  ...UserFollowButton_user\n  ...UserSubscribeButton_user\n  __typename\n  id\n}\n\nfragment UserFollowButton_user on User {\n  ...UserFollowButtonSignedIn_user\n  ...UserFollowButtonSignedOut_user\n  __typename\n  id\n}\n\nfragment UserFollowButtonSignedIn_user on User {\n  id\n  __typename\n}\n\nfragment UserFollowButtonSignedOut_user on User {\n  id\n  ...SusiClickable_user\n  __typename\n}\n\nfragment SusiClickable_user on User {\n  ...SusiContainer_user\n  __typename\n  id\n}\n\nfragment SusiContainer_user on User {\n  ...SignInOptions_user\n  ...SignUpOptions_user\n  __typename\n  id\n}\n\nfragment SignInOptions_user on User {\n  id\n  name\n  __typename\n}\n\nfragment SignUpOptions_user on User {\n  id\n  name\n  __typename\n}\n\nfragment UserSubscribeButton_user on User {\n  id\n  isPartnerProgramEnrolled\n  name\n  viewerEdge {\n    id\n    isFollowing\n    isUser\n    __typename\n  }\n  viewerIsUser\n  newsletterV3 {\n    id\n    ...useNewsletterV3Subscription_newsletterV3\n    __typename\n  }\n  ...useNewsletterV3Subscription_user\n  ...MembershipUpsellModal_user\n  __typename\n}\n\nfragment useNewsletterV3Subscription_newsletterV3 on NewsletterV3 {\n  id\n  type\n  slug\n  name\n  collection {\n    slug\n    __typename\n    id\n  }\n  user {\n    id\n    name\n    username\n    newsletterV3 {\n      id\n      __typename\n    }\n    __typename\n  }\n  __typename\n}\n\nfragment useNewsletterV3Subscription_user on User {\n  id\n  username\n  newsletterV3 {\n    ...useNewsletterV3Subscription_newsletterV3\n    __typename\n    id\n  }\n  __typename\n}\n\nfragment MembershipUpsellModal_user on User {\n  id\n  name\n  imageId\n  postSubscribeMembershipUpsellShownAt\n  newsletterV3 {\n    id\n    __typename\n  }\n  __typename\n}\n\nfragment PublisherHeaderNav_publisher on Publisher {\n  __typename\n  id\n  customStyleSheet {\n    navigation {\n      navItems {\n        name\n        ...PublisherHeaderNavLink_headerNavigationItem\n        __typename\n      }\n      __typename\n    }\n    __typename\n    id\n  }\n  ...PublisherHeaderNavLink_publisher\n  ... on Collection {\n    domain\n    isAuroraVisible\n    slug\n    navItems {\n      tagSlug\n      title\n      url\n      __typename\n    }\n    __typename\n    id\n  }\n  ... on User {\n    customDomainState {\n      live {\n        domain\n        __typename\n      }\n      __typename\n    }\n    hasSubdomain\n    username\n    about\n    homePostsPublished: homepagePostsConnection(paging: {limit: 1}) {\n      posts {\n        id\n        __typename\n      }\n      __typename\n    }\n    __typename\n    id\n  }\n}\n\nfragment PublisherHeaderNavLink_headerNavigationItem on HeaderNavigationItem {\n  href\n  name\n  tags {\n    id\n    normalizedTagSlug\n    __typename\n  }\n  type\n  __typename\n}\n\nfragment PublisherHeaderNavLink_publisher on Publisher {\n  __typename\n  id\n  ... on Collection {\n    slug\n    __typename\n    id\n  }\n}\n\nfragment PublisherHomePosts_publisher on Publisher {\n  __typename\n  id\n  homepagePostsConnection(\n    paging: {limit: $homepagePostsLimit, from: $homepagePostsFrom}\n    includeDistributedResponses: $includeDistributedResponses\n  ) {\n    posts {\n      ...PublisherHomePosts_post\n      __typename\n    }\n    pagingInfo {\n      next {\n        from\n        limit\n        __typename\n      }\n      __typename\n    }\n    __typename\n  }\n  ...CardByline_publisher\n  ...NewsletterV3Promo_publisher\n  ...PublisherHomePosts_user\n}\n\nfragment PublisherHomePosts_post on Post {\n  id\n  collection {\n    id\n    name\n    ...collectionUrl_collection\n    __typename\n  }\n  ...ExpandablePost_post\n  __typename\n}\n\nfragment ExpandablePost_post on Post {\n  id\n  creator {\n    ...ExpandablePost_user\n    __typename\n    id\n  }\n  collection {\n    ...CardByline_collection\n    __typename\n    id\n  }\n  ...InteractivePostBody_postPreview\n  firstPublishedAt\n  isLocked\n  isSeries\n  isShortform\n  latestPublishedAt\n  inResponseToCatalogResult {\n    __typename\n  }\n  mediumUrl\n  postResponses {\n    count\n    __typename\n  }\n  previewImage {\n    id\n    focusPercentX\n    focusPercentY\n    __typename\n  }\n  readingTime\n  sequence {\n    slug\n    __typename\n  }\n  title\n  uniqueSlug\n  visibility\n  ...CardByline_post\n  ...ExpandablePostFooter_post\n  ...InResponseToEntityPreview_post\n  ...PostScrollTracker_post\n  ...ReadMore_post\n  ...HighDensityPreview_post\n  __typename\n}\n\nfragment ExpandablePost_user on User {\n  __typename\n  name\n  username\n  ...CardByline_user\n  id\n}\n\nfragment CardByline_user on User {\n  __typename\n  id\n  name\n  username\n  mediumMemberAt\n  socialStats {\n    followerCount\n    __typename\n  }\n  ...userUrl_user\n  ...UserMentionTooltip_user\n}\n\nfragment UserMentionTooltip_user on User {\n  id\n  name\n  username\n  bio\n  imageId\n  mediumMemberAt\n  ...UserAvatar_user\n  ...UserFollowButton_user\n  __typename\n}\n\nfragment CardByline_collection on Collection {\n  __typename\n  id\n  name\n  ...collectionUrl_collection\n}\n\nfragment InteractivePostBody_postPreview on Post {\n  extendedPreviewContent(\n    truncationConfig: {previewParagraphsWordCountThreshold: 400, minimumWordLengthForTruncation: 150, truncateAtEndOfSentence: true, showFullImageCaptions: true, shortformPreviewParagraphsWordCountThreshold: 30, shortformMinimumWordLengthForTruncation: 30}\n  ) {\n    bodyModel {\n      ...PostBody_bodyModel\n      __typename\n    }\n    isFullContent\n    __typename\n  }\n  __typename\n  id\n}\n\nfragment PostBody_bodyModel on RichText {\n  sections {\n    name\n    startIndex\n    textLayout\n    imageLayout\n    backgroundImage {\n      id\n      originalHeight\n      originalWidth\n      __typename\n    }\n    videoLayout\n    backgroundVideo {\n      videoId\n      originalHeight\n      originalWidth\n      previewImageId\n      __typename\n    }\n    __typename\n  }\n  paragraphs {\n    id\n    ...PostBodySection_paragraph\n    __typename\n  }\n  ...normalizedBodyModel_richText\n  __typename\n}\n\nfragment PostBodySection_paragraph on Paragraph {\n  name\n  ...PostBodyParagraph_paragraph\n  __typename\n  id\n}\n\nfragment PostBodyParagraph_paragraph on Paragraph {\n  name\n  type\n  ...ImageParagraph_paragraph\n  ...TextParagraph_paragraph\n  ...IframeParagraph_paragraph\n  ...MixtapeParagraph_paragraph\n  __typename\n  id\n}\n\nfragment ImageParagraph_paragraph on Paragraph {\n  href\n  layout\n  metadata {\n    id\n    originalHeight\n    originalWidth\n    focusPercentX\n    focusPercentY\n    alt\n    __typename\n  }\n  ...Markups_paragraph\n  ...ParagraphRefsMapContext_paragraph\n  ...PostAnnotationsMarker_paragraph\n  __typename\n  id\n}\n\nfragment Markups_paragraph on Paragraph {\n  name\n  text\n  hasDropCap\n  dropCapImage {\n    ...MarkupNode_data_dropCapImage\n    __typename\n    id\n  }\n  markups {\n    type\n    start\n    end\n    href\n    anchorType\n    userId\n    linkMetadata {\n      httpStatus\n      __typename\n    }\n    __typename\n  }\n  __typename\n  id\n}\n\nfragment MarkupNode_data_dropCapImage on ImageMetadata {\n  ...DropCap_image\n  __typename\n  id\n}\n\nfragment DropCap_image on ImageMetadata {\n  id\n  originalHeight\n  originalWidth\n  __typename\n}\n\nfragment ParagraphRefsMapContext_paragraph on Paragraph {\n  id\n  name\n  text\n  __typename\n}\n\nfragment PostAnnotationsMarker_paragraph on Paragraph {\n  ...PostViewNoteCard_paragraph\n  __typename\n  id\n}\n\nfragment PostViewNoteCard_paragraph on Paragraph {\n  name\n  __typename\n  id\n}\n\nfragment TextParagraph_paragraph on Paragraph {\n  type\n  hasDropCap\n  ...Markups_paragraph\n  ...ParagraphRefsMapContext_paragraph\n  __typename\n  id\n}\n\nfragment IframeParagraph_paragraph on Paragraph {\n  iframe {\n    mediaResource {\n      id\n      iframeSrc\n      iframeHeight\n      iframeWidth\n      title\n      __typename\n    }\n    __typename\n  }\n  layout\n  ...getEmbedlyCardUrlParams_paragraph\n  ...Markups_paragraph\n  __typename\n  id\n}\n\nfragment getEmbedlyCardUrlParams_paragraph on Paragraph {\n  type\n  iframe {\n    mediaResource {\n      iframeSrc\n      __typename\n    }\n    __typename\n  }\n  __typename\n  id\n}\n\nfragment MixtapeParagraph_paragraph on Paragraph {\n  type\n  mixtapeMetadata {\n    href\n    mediaResource {\n      mediumCatalog {\n        id\n        __typename\n      }\n      __typename\n    }\n    __typename\n  }\n  ...GenericMixtapeParagraph_paragraph\n  __typename\n  id\n}\n\nfragment GenericMixtapeParagraph_paragraph on Paragraph {\n  text\n  mixtapeMetadata {\n    href\n    thumbnailImageId\n    __typename\n  }\n  markups {\n    start\n    end\n    type\n    href\n    __typename\n  }\n  __typename\n  id\n}\n\nfragment normalizedBodyModel_richText on RichText {\n  paragraphs {\n    markups {\n      type\n      __typename\n    }\n    ...getParagraphHighlights_paragraph\n    ...getParagraphPrivateNotes_paragraph\n    __typename\n  }\n  sections {\n    startIndex\n    ...getSectionEndIndex_section\n    __typename\n  }\n  ...getParagraphStyles_richText\n  ...getParagraphSpaces_richText\n  __typename\n}\n\nfragment getParagraphHighlights_paragraph on Paragraph {\n  name\n  __typename\n  id\n}\n\nfragment getParagraphPrivateNotes_paragraph on Paragraph {\n  name\n  __typename\n  id\n}\n\nfragment getSectionEndIndex_section on Section {\n  startIndex\n  __typename\n}\n\nfragment getParagraphStyles_richText on RichText {\n  paragraphs {\n    text\n    type\n    __typename\n  }\n  sections {\n    ...getSectionEndIndex_section\n    __typename\n  }\n  __typename\n}\n\nfragment getParagraphSpaces_richText on RichText {\n  paragraphs {\n    layout\n    metadata {\n      originalHeight\n      originalWidth\n      __typename\n    }\n    type\n    ...paragraphExtendsImageGrid_paragraph\n    __typename\n  }\n  ...getSeriesParagraphTopSpacings_richText\n  ...getPostParagraphTopSpacings_richText\n  __typename\n}\n\nfragment paragraphExtendsImageGrid_paragraph on Paragraph {\n  layout\n  type\n  __typename\n  id\n}\n\nfragment getSeriesParagraphTopSpacings_richText on RichText {\n  paragraphs {\n    id\n    __typename\n  }\n  sections {\n    startIndex\n    __typename\n  }\n  __typename\n}\n\nfragment getPostParagraphTopSpacings_richText on RichText {\n  paragraphs {\n    layout\n    text\n    __typename\n  }\n  sections {\n    startIndex\n    __typename\n  }\n  __typename\n}\n\nfragment CardByline_post on Post {\n  ...DraftStatus_post\n  __typename\n  id\n}\n\nfragment DraftStatus_post on Post {\n  id\n  pendingCollection {\n    id\n    creator {\n      id\n      __typename\n    }\n    ...BoldCollectionName_collection\n    __typename\n  }\n  statusForCollection\n  creator {\n    id\n    __typename\n  }\n  isPublished\n  __typename\n}\n\nfragment BoldCollectionName_collection on Collection {\n  id\n  name\n  __typename\n}\n\nfragment ExpandablePostFooter_post on Post {\n  id\n  allowResponses\n  postResponses {\n    count\n    __typename\n  }\n  isLimitedState\n  ...ExpandablePostCardOverflowButton_post\n  ...BookmarkButton_post\n  ...PostFooterSocialPopover_post\n  ...MultiVote_post\n  ...OverflowMenuButtonWithNegativeSignal_post\n  __typename\n}\n\nfragment ExpandablePostCardOverflowButton_post on Post {\n  creator {\n    id\n    __typename\n  }\n  ...ExpandablePostCardEditorWriterButton_post\n  ...ExpandablePostCardReaderButton_post\n  __typename\n  id\n}\n\nfragment ExpandablePostCardEditorWriterButton_post on Post {\n  id\n  collection {\n    id\n    name\n    slug\n    __typename\n  }\n  allowResponses\n  clapCount\n  visibility\n  mediumUrl\n  responseDistribution\n  ...useIsPinnedInContext_post\n  ...CopyFriendLinkMenuItem_post\n  ...NewsletterV3EmailToSubscribersMenuItem_post\n  ...OverflowMenuItemUndoClaps_post\n  __typename\n}\n\nfragment useIsPinnedInContext_post on Post {\n  id\n  collection {\n    id\n    __typename\n  }\n  pendingCollection {\n    id\n    __typename\n  }\n  pinnedAt\n  pinnedByCreatorAt\n  __typename\n}\n\nfragment CopyFriendLinkMenuItem_post on Post {\n  id\n  __typename\n}\n\nfragment NewsletterV3EmailToSubscribersMenuItem_post on Post {\n  id\n  creator {\n    id\n    newsletterV3 {\n      id\n      subscribersCount\n      __typename\n    }\n    __typename\n  }\n  isNewsletter\n  isAuthorNewsletter\n  __typename\n}\n\nfragment OverflowMenuItemUndoClaps_post on Post {\n  id\n  clapCount\n  ...ClapMutation_post\n  __typename\n}\n\nfragment ClapMutation_post on Post {\n  __typename\n  id\n  clapCount\n  ...MultiVoteCount_post\n}\n\nfragment MultiVoteCount_post on Post {\n  id\n  ...PostVotersNetwork_post\n  __typename\n}\n\nfragment PostVotersNetwork_post on Post {\n  id\n  voterCount\n  recommenders {\n    name\n    __typename\n  }\n  __typename\n}\n\nfragment ExpandablePostCardReaderButton_post on Post {\n  id\n  collection {\n    id\n    __typename\n  }\n  creator {\n    id\n    __typename\n  }\n  clapCount\n  ...ClapMutation_post\n  __typename\n}\n\nfragment BookmarkButton_post on Post {\n  visibility\n  ...SusiClickable_post\n  ...AddToCatalogBookmarkButton_post\n  __typename\n  id\n}\n\nfragment SusiClickable_post on Post {\n  id\n  mediumUrl\n  ...SusiContainer_post\n  __typename\n}\n\nfragment SusiContainer_post on Post {\n  id\n  __typename\n}\n\nfragment AddToCatalogBookmarkButton_post on Post {\n  ...AddToCatalogBase_post\n  __typename\n  id\n}\n\nfragment AddToCatalogBase_post on Post {\n  id\n  __typename\n}\n\nfragment PostFooterSocialPopover_post on Post {\n  id\n  mediumUrl\n  title\n  ...SharePostButton_post\n  __typename\n}\n\nfragment SharePostButton_post on Post {\n  id\n  __typename\n}\n\nfragment MultiVote_post on Post {\n  id\n  clapCount\n  creator {\n    id\n    ...SusiClickable_user\n    __typename\n  }\n  isPublished\n  ...SusiClickable_post\n  collection {\n    id\n    slug\n    __typename\n  }\n  isLimitedState\n  ...MultiVoteCount_post\n  __typename\n}\n\nfragment OverflowMenuButtonWithNegativeSignal_post on Post {\n  id\n  ...OverflowMenuWithNegativeSignal_post\n  ...CreatorActionOverflowPopover_post\n  __typename\n}\n\nfragment OverflowMenuWithNegativeSignal_post on Post {\n  id\n  creator {\n    id\n    __typename\n  }\n  collection {\n    id\n    __typename\n  }\n  ...OverflowMenuItemUndoClaps_post\n  __typename\n}\n\nfragment CreatorActionOverflowPopover_post on Post {\n  allowResponses\n  id\n  statusForCollection\n  isLocked\n  isPublished\n  clapCount\n  mediumUrl\n  pinnedAt\n  pinnedByCreatorAt\n  curationEligibleAt\n  mediumUrl\n  responseDistribution\n  visibility\n  inResponseToPostResult {\n    __typename\n  }\n  inResponseToCatalogResult {\n    __typename\n  }\n  pendingCollection {\n    id\n    name\n    creator {\n      id\n      __typename\n    }\n    avatar {\n      id\n      __typename\n    }\n    domain\n    slug\n    __typename\n  }\n  creator {\n    id\n    ...MutePopoverOptions_creator\n    ...auroraHooks_publisher\n    __typename\n  }\n  collection {\n    id\n    name\n    creator {\n      id\n      __typename\n    }\n    avatar {\n      id\n      __typename\n    }\n    domain\n    slug\n    ...MutePopoverOptions_collection\n    ...auroraHooks_publisher\n    __typename\n  }\n  ...useIsPinnedInContext_post\n  ...NewsletterV3EmailToSubscribersMenuItem_post\n  ...OverflowMenuItemUndoClaps_post\n  __typename\n}\n\nfragment auroraHooks_publisher on Publisher {\n  __typename\n  ... on Collection {\n    isAuroraEligible\n    isAuroraVisible\n    viewerEdge {\n      id\n      isEditor\n      __typename\n    }\n    __typename\n    id\n  }\n  ... on User {\n    isAuroraVisible\n    __typename\n    id\n  }\n}\n\nfragment InResponseToEntityPreview_post on Post {\n  id\n  inResponseToEntityType\n  __typename\n}\n\nfragment PostScrollTracker_post on Post {\n  id\n  collection {\n    id\n    __typename\n  }\n  sequence {\n    sequenceId\n    __typename\n  }\n  __typename\n}\n\nfragment ReadMore_post on Post {\n  mediumUrl\n  readingTime\n  ...usePostUrl_post\n  __typename\n  id\n}\n\nfragment usePostUrl_post on Post {\n  id\n  creator {\n    ...userUrl_user\n    __typename\n    id\n  }\n  collection {\n    id\n    domain\n    slug\n    __typename\n  }\n  isSeries\n  mediumUrl\n  sequence {\n    slug\n    __typename\n  }\n  uniqueSlug\n  __typename\n}\n\nfragment HighDensityPreview_post on Post {\n  id\n  title\n  previewImage {\n    id\n    focusPercentX\n    focusPercentY\n    __typename\n  }\n  extendedPreviewContent(\n    truncationConfig: {previewParagraphsWordCountThreshold: 400, minimumWordLengthForTruncation: 150, truncateAtEndOfSentence: true, showFullImageCaptions: true, shortformPreviewParagraphsWordCountThreshold: 30, shortformMinimumWordLengthForTruncation: 30}\n  ) {\n    subtitle\n    __typename\n  }\n  ...HighDensityFooter_post\n  __typename\n}\n\nfragment HighDensityFooter_post on Post {\n  id\n  readingTime\n  tags {\n    ...TopicPill_tag\n    __typename\n  }\n  ...BookmarkButton_post\n  ...ExpandablePostCardOverflowButton_post\n  ...OverflowMenuButtonWithNegativeSignal_post\n  __typename\n}\n\nfragment TopicPill_tag on Tag {\n  __typename\n  id\n  displayTitle\n}\n\nfragment CardByline_publisher on Publisher {\n  __typename\n  ... on User {\n    id\n    ...CardByline_user\n    __typename\n  }\n  ... on Collection {\n    id\n    ...CardByline_collection\n    __typename\n  }\n}\n\nfragment NewsletterV3Promo_publisher on Publisher {\n  __typename\n  ... on User {\n    ...NewsletterV3Promo_publisher_User\n    __typename\n    id\n  }\n  ... on Collection {\n    ...NewsletterV3Promo_publisher_Collection\n    __typename\n    id\n  }\n}\n\nfragment NewsletterV3Promo_publisher_User on User {\n  id\n  username\n  name\n  viewerIsUser\n  newsletterV3 {\n    id\n    ...NewsletterV3Promo_newsletterV3\n    __typename\n  }\n  __typename\n}\n\nfragment NewsletterV3Promo_newsletterV3 on NewsletterV3 {\n  slug\n  name\n  description\n  promoHeadline\n  promoBody\n  ...NewsletterV3AmpButton_newsletterV3\n  ...NewsletterV3SubscribeButton_newsletterV3\n  ...NewsletterV3SubscribeByEmail_newsletterV3\n  __typename\n  id\n}\n\nfragment NewsletterV3AmpButton_newsletterV3 on NewsletterV3 {\n  id\n  collection {\n    ...collectionDefaultBackgroundTheme_collection\n    __typename\n    id\n  }\n  __typename\n}\n\nfragment collectionDefaultBackgroundTheme_collection on Collection {\n  colorPalette {\n    ...collectionDefaultBackgroundTheme_colorPalette\n    __typename\n  }\n  customStyleSheet {\n    id\n    ...collectionDefaultBackgroundTheme_customStyleSheet\n    __typename\n  }\n  __typename\n  id\n}\n\nfragment collectionDefaultBackgroundTheme_colorPalette on ColorPalette {\n  ...customDefaultBackgroundTheme_colorPalette\n  __typename\n}\n\nfragment customDefaultBackgroundTheme_colorPalette on ColorPalette {\n  highlightSpectrum {\n    ...ThemeUtil_colorSpectrum\n    __typename\n  }\n  defaultBackgroundSpectrum {\n    ...ThemeUtil_colorSpectrum\n    __typename\n  }\n  tintBackgroundSpectrum {\n    ...ThemeUtil_colorSpectrum\n    __typename\n  }\n  __typename\n}\n\nfragment collectionDefaultBackgroundTheme_customStyleSheet on CustomStyleSheet {\n  id\n  ...customDefaultBackgroundTheme_customStyleSheet\n  __typename\n}\n\nfragment customDefaultBackgroundTheme_customStyleSheet on CustomStyleSheet {\n  id\n  global {\n    colorPalette {\n      primary {\n        colorPalette {\n          ...customDefaultBackgroundTheme_colorPalette\n          __typename\n        }\n        __typename\n      }\n      background {\n        colorPalette {\n          ...customDefaultBackgroundTheme_colorPalette\n          __typename\n        }\n        __typename\n      }\n      __typename\n    }\n    __typename\n  }\n  __typename\n}\n\nfragment NewsletterV3SubscribeButton_newsletterV3 on NewsletterV3 {\n  id\n  name\n  slug\n  type\n  user {\n    id\n    name\n    username\n    __typename\n  }\n  collection {\n    slug\n    ...SusiClickable_collection\n    ...collectionDefaultBackgroundTheme_collection\n    __typename\n    id\n  }\n  ...SusiClickable_newsletterV3\n  ...useNewsletterV3Subscription_newsletterV3\n  __typename\n}\n\nfragment SusiClickable_newsletterV3 on NewsletterV3 {\n  ...SusiContainer_newsletterV3\n  __typename\n  id\n}\n\nfragment SusiContainer_newsletterV3 on NewsletterV3 {\n  ...SignInOptions_newsletterV3\n  ...SignUpOptions_newsletterV3\n  __typename\n  id\n}\n\nfragment SignInOptions_newsletterV3 on NewsletterV3 {\n  id\n  name\n  __typename\n}\n\nfragment SignUpOptions_newsletterV3 on NewsletterV3 {\n  id\n  name\n  __typename\n}\n\nfragment NewsletterV3SubscribeByEmail_newsletterV3 on NewsletterV3 {\n  id\n  slug\n  type\n  user {\n    id\n    name\n    username\n    __typename\n  }\n  collection {\n    ...collectionDefaultBackgroundTheme_collection\n    ...collectionUrl_collection\n    __typename\n    id\n  }\n  __typename\n}\n\nfragment NewsletterV3Promo_publisher_Collection on Collection {\n  id\n  slug\n  domain\n  name\n  newsletterV3 {\n    id\n    ...NewsletterV3Promo_newsletterV3\n    __typename\n  }\n  __typename\n}\n\nfragment PublisherHomePosts_user on User {\n  id\n  ...useShowAuthorNewsletterV3Promo_user\n  __typename\n}\n\nfragment useShowAuthorNewsletterV3Promo_user on User {\n  id\n  username\n  newsletterV3 {\n    id\n    showPromo\n    slug\n    __typename\n  }\n  __typename\n}\n\nfragment UserSubdomainFlow_user on User {\n  id\n  hasCompletedProfile\n  name\n  bio\n  imageId\n  ...UserCompleteProfileDialog_user\n  ...UserSubdomainOnboardingDialog_user\n  __typename\n}\n\nfragment UserCompleteProfileDialog_user on User {\n  id\n  name\n  bio\n  imageId\n  hasCompletedProfile\n  __typename\n}\n\nfragment UserSubdomainOnboardingDialog_user on User {\n  id\n  customDomainState {\n    pending {\n      status\n      __typename\n    }\n    live {\n      status\n      __typename\n    }\n    __typename\n  }\n  username\n  __typename\n}\n\nfragment UserProfileMetadata_user on User {\n  id\n  username\n  name\n  bio\n  socialStats {\n    followerCount\n    followingCount\n    __typename\n  }\n  ...userUrl_user\n  ...UserProfileMetadataHelmet_user\n  __typename\n}\n\nfragment UserProfileMetadataHelmet_user on User {\n  username\n  name\n  imageId\n  twitterScreenName\n  navItems {\n    title\n    __typename\n  }\n  __typename\n  id\n}\n\nfragment SuspendedBannerLoader_user on User {\n  id\n  isSuspended\n  __typename\n}\n\nfragment useAnalytics_user on User {\n  id\n  imageId\n  name\n  username\n  __typename\n}\n\nfragment EntityDrivenSubscriptionLandingPageScreen_writer on User {\n  name\n  imageId\n  id\n  username\n  isPartnerProgramEnrolled\n  customStyleSheet {\n    ...CustomThemeProvider_customStyleSheet\n    ...CustomBackgroundWrapper_customStyleSheet\n    ...MetaHeader_customStyleSheet\n    __typename\n    id\n  }\n  ...MetaHeader_publisher\n  ...userUrl_user\n  __typename\n}\n\nfragment CustomThemeProvider_customStyleSheet on CustomStyleSheet {\n  id\n  ...customDefaultBackgroundTheme_customStyleSheet\n  ...customStyleSheetFontTheme_customStyleSheet\n  __typename\n}\n\nfragment customStyleSheetFontTheme_customStyleSheet on CustomStyleSheet {\n  id\n  global {\n    fonts {\n      font1 {\n        name\n        __typename\n      }\n      font2 {\n        name\n        __typename\n      }\n      font3 {\n        name\n        __typename\n      }\n      __typename\n    }\n    __typename\n  }\n  __typename\n}\n\nfragment CustomBackgroundWrapper_customStyleSheet on CustomStyleSheet {\n  id\n  global {\n    colorPalette {\n      background {\n        ...getHexFromColorValue_colorValue\n        __typename\n      }\n      __typename\n    }\n    __typename\n  }\n  __typename\n}\n\nfragment MetaHeader_customStyleSheet on CustomStyleSheet {\n  id\n  header {\n    headerScale\n    horizontalAlignment\n    __typename\n  }\n  ...MetaHeaderBackground_customStyleSheet\n  ...MetaHeaderEngagement_customStyleSheet\n  ...MetaHeaderLogo_customStyleSheet\n  ...MetaHeaderNavVertical_customStyleSheet\n  ...MetaHeaderTagline_customStyleSheet\n  ...MetaHeaderThemeProvider_customStyleSheet\n  __typename\n}\n\nfragment MetaHeaderBackground_customStyleSheet on CustomStyleSheet {\n  id\n  header {\n    headerScale\n    backgroundImageDisplayMode\n    backgroundImageVerticalAlignment\n    backgroundColorDisplayMode\n    backgroundColor {\n      ...getHexFromColorValue_colorValue\n      ...getOpaqueHexFromColorValue_colorValue\n      __typename\n    }\n    secondaryBackgroundColor {\n      ...getHexFromColorValue_colorValue\n      __typename\n    }\n    postBackgroundColor {\n      ...getHexFromColorValue_colorValue\n      __typename\n    }\n    backgroundImage {\n      ...MetaHeaderBackground_imageMetadata\n      __typename\n    }\n    __typename\n  }\n  __typename\n}\n\nfragment MetaHeaderEngagement_customStyleSheet on CustomStyleSheet {\n  ...MetaHeaderNav_customStyleSheet\n  __typename\n  id\n}\n\nfragment MetaHeaderNav_customStyleSheet on CustomStyleSheet {\n  id\n  navigation {\n    navItems {\n      ...MetaHeaderNav_headerNavigationItem\n      __typename\n    }\n    __typename\n  }\n  __typename\n}\n\nfragment MetaHeaderNav_headerNavigationItem on HeaderNavigationItem {\n  name\n  tagSlugs\n  ...MetaHeaderNavLink_headerNavigationItem\n  __typename\n}\n\nfragment MetaHeaderNavLink_headerNavigationItem on HeaderNavigationItem {\n  name\n  ...getNavItemHref_headerNavigationItem\n  __typename\n}\n\nfragment getNavItemHref_headerNavigationItem on HeaderNavigationItem {\n  href\n  type\n  tags {\n    id\n    normalizedTagSlug\n    __typename\n  }\n  __typename\n}\n\nfragment MetaHeaderLogo_customStyleSheet on CustomStyleSheet {\n  id\n  header {\n    nameColor {\n      ...getHexFromColorValue_colorValue\n      __typename\n    }\n    nameTreatment\n    postNameTreatment\n    logoImage {\n      ...MetaHeaderLogo_imageMetadata\n      __typename\n    }\n    logoScale\n    __typename\n  }\n  __typename\n}\n\nfragment MetaHeaderLogo_imageMetadata on ImageMetadata {\n  id\n  originalWidth\n  originalHeight\n  ...PublisherLogo_image\n  __typename\n}\n\nfragment PublisherLogo_image on ImageMetadata {\n  id\n  originalHeight\n  originalWidth\n  __typename\n}\n\nfragment MetaHeaderNavVertical_customStyleSheet on CustomStyleSheet {\n  id\n  navigation {\n    navItems {\n      ...MetaHeaderNavLink_headerNavigationItem\n      __typename\n    }\n    __typename\n  }\n  ...MetaHeaderNav_customStyleSheet\n  __typename\n}\n\nfragment MetaHeaderTagline_customStyleSheet on CustomStyleSheet {\n  id\n  header {\n    taglineColor {\n      ...getHexFromColorValue_colorValue\n      __typename\n    }\n    taglineTreatment\n    __typename\n  }\n  __typename\n}\n\nfragment MetaHeaderThemeProvider_customStyleSheet on CustomStyleSheet {\n  id\n  ...useMetaHeaderTheme_customStyleSheet\n  __typename\n}\n\nfragment useMetaHeaderTheme_customStyleSheet on CustomStyleSheet {\n  ...customDefaultBackgroundTheme_customStyleSheet\n  global {\n    colorPalette {\n      primary {\n        colorPalette {\n          tintBackgroundSpectrum {\n            ...ThemeUtil_colorSpectrum\n            __typename\n          }\n          __typename\n        }\n        __typename\n      }\n      __typename\n    }\n    __typename\n  }\n  header {\n    backgroundColor {\n      colorPalette {\n        tintBackgroundSpectrum {\n          ...ThemeUtil_colorSpectrum\n          __typename\n        }\n        __typename\n      }\n      __typename\n    }\n    postBackgroundColor {\n      colorPalette {\n        tintBackgroundSpectrum {\n          ...ThemeUtil_colorSpectrum\n          __typename\n        }\n        __typename\n      }\n      __typename\n    }\n    backgroundImage {\n      id\n      __typename\n    }\n    __typename\n  }\n  __typename\n  id\n}\n\nfragment MetaHeader_publisher on Publisher {\n  __typename\n  name\n  ...MetaHeaderEngagement_publisher\n  ...MetaHeaderLogo_publisher\n  ...MetaHeaderNavVertical_publisher\n  ...MetaHeaderTagline_publisher\n  ...MetaHeaderThemeProvider_publisher\n  ...MetaHeaderActions_publisher\n  ...MetaHeaderTop_publisher\n  ...MetaHeaderNavLink_publisher\n  ... on Collection {\n    id\n    favicon {\n      id\n      __typename\n    }\n    tagline\n    ...CollectionNavigationContextProvider_collection\n    __typename\n  }\n  ... on User {\n    id\n    bio\n    ...UserProfileCatalogsLink_publisher\n    __typename\n  }\n}\n\nfragment MetaHeaderEngagement_publisher on Publisher {\n  __typename\n  ...MetaHeaderNav_publisher\n  ...PublisherAboutLink_publisher\n  ...PublisherFollowButton_publisher\n  ...PublisherFollowerCount_publisher\n  ... on Collection {\n    creator {\n      id\n      __typename\n    }\n    customStyleSheet {\n      id\n      ...CustomThemeProvider_customStyleSheet\n      __typename\n    }\n    __typename\n    id\n  }\n  ... on User {\n    ...UserProfileCatalogsLink_publisher\n    ...UserSubscribeButton_user\n    customStyleSheet {\n      id\n      ...CustomThemeProvider_customStyleSheet\n      __typename\n    }\n    __typename\n    id\n  }\n}\n\nfragment MetaHeaderNav_publisher on Publisher {\n  id\n  ...MetaHeaderNavLink_publisher\n  __typename\n}\n\nfragment MetaHeaderNavLink_publisher on Publisher {\n  id\n  ...getNavItemHref_publisher\n  __typename\n}\n\nfragment getNavItemHref_publisher on Publisher {\n  id\n  ...publisherUrl_publisher\n  __typename\n}\n\nfragment PublisherAboutLink_publisher on Publisher {\n  __typename\n  id\n  ... on Collection {\n    slug\n    __typename\n    id\n  }\n  ... on User {\n    ...userUrl_user\n    __typename\n    id\n  }\n}\n\nfragment PublisherFollowButton_publisher on Publisher {\n  __typename\n  ... on Collection {\n    ...CollectionFollowButton_collection\n    __typename\n    id\n  }\n  ... on User {\n    ...UserFollowButton_user\n    __typename\n    id\n  }\n}\n\nfragment UserProfileCatalogsLink_publisher on Publisher {\n  __typename\n  id\n  ... on User {\n    ...userUrl_user\n    homePostsPublished: homepagePostsConnection(paging: {limit: 1}) {\n      posts {\n        id\n        __typename\n      }\n      __typename\n    }\n    __typename\n    id\n  }\n}\n\nfragment MetaHeaderLogo_publisher on Publisher {\n  __typename\n  id\n  name\n  ... on Collection {\n    logo {\n      ...MetaHeaderLogo_imageMetadata\n      ...PublisherLogo_image\n      __typename\n      id\n    }\n    __typename\n    id\n  }\n  ...auroraHooks_publisher\n}\n\nfragment MetaHeaderNavVertical_publisher on Publisher {\n  id\n  ...PublisherAboutLink_publisher\n  ...MetaHeaderNav_publisher\n  ...MetaHeaderNavLink_publisher\n  __typename\n}\n\nfragment MetaHeaderTagline_publisher on Publisher {\n  __typename\n  ... on Collection {\n    tagline\n    __typename\n    id\n  }\n  ... on User {\n    bio\n    __typename\n    id\n  }\n}\n\nfragment MetaHeaderThemeProvider_publisher on Publisher {\n  __typename\n  customStyleSheet {\n    ...MetaHeaderThemeProvider_customStyleSheet\n    __typename\n    id\n  }\n  ... on Collection {\n    colorPalette {\n      ...customDefaultBackgroundTheme_colorPalette\n      __typename\n    }\n    __typename\n    id\n  }\n}\n\nfragment MetaHeaderActions_publisher on Publisher {\n  __typename\n  ...MetaHeaderPubMenu_publisher\n  ...SearchWidget_publisher\n  ... on Collection {\n    id\n    creator {\n      id\n      __typename\n    }\n    customStyleSheet {\n      navigation {\n        navItems {\n          name\n          __typename\n        }\n        __typename\n      }\n      __typename\n      id\n    }\n    ...CollectionAvatar_collection\n    ...CollectionMetabarActionsPopover_collection\n    ...MetaHeaderActions_collection_common\n    __typename\n  }\n  ... on User {\n    id\n    ...UserAvatar_user\n    __typename\n  }\n}\n\nfragment SearchWidget_publisher on Publisher {\n  __typename\n  ... on Collection {\n    id\n    slug\n    name\n    domain\n    __typename\n  }\n  ... on User {\n    id\n    name\n    __typename\n  }\n  ...algoliaSearch_publisher\n}\n\nfragment algoliaSearch_publisher on Publisher {\n  __typename\n  id\n}\n\nfragment CollectionMetabarActionsPopover_collection on Collection {\n  id\n  slug\n  isAuroraEligible\n  isAuroraVisible\n  newsletterV3 {\n    id\n    slug\n    __typename\n  }\n  ...collectionUrl_collection\n  __typename\n}\n\nfragment MetaHeaderActions_collection_common on Collection {\n  creator {\n    id\n    __typename\n  }\n  __typename\n  id\n}\n\nfragment MetaHeaderTop_publisher on Publisher {\n  __typename\n  ... on Collection {\n    slug\n    ...CollectionMetabarActionsPopover_collection\n    ...CollectionAvatar_collection\n    ...MetaHeaderTop_collection\n    __typename\n    id\n  }\n  ... on User {\n    username\n    id\n    __typename\n  }\n}\n\nfragment MetaHeaderTop_collection on Collection {\n  id\n  creator {\n    id\n    __typename\n  }\n  __typename\n}\n\nfragment CollectionNavigationContextProvider_collection on Collection {\n  id\n  domain\n  slug\n  isAuroraVisible\n  __typename\n}\n\nfragment useShouldShowEntityDrivenSubscription_creator on User {\n  id\n  __typename\n}\n"
      }
]
  • id : The User Id corresponding to the account, provided by the follower retrieval Endpoint above

  • homepagePostsFrom : Pagination parameter, use the from value from the response to fetch all paged data

Postman :

Response:

The article list information can be obtained from response[0]["data"]["userResult"]["homepagePostsConnection"]["posts"].

Medium Private API — Fetch Article Content

Next is the most crucial part: scraping the original article content.

Graphql Query Body:

1
2
3
4
5
6
7
8
9
[
      {
        "operationName": "PostViewerEdgeContentQuery",
        "variables": {
          "postId": "c008a9e8ceca"
        },
        "query": "query PostViewerEdgeContentQuery($postId: ID!, $postMeteringOptions: PostMeteringOptions) {\n  post(id: $postId) {\n    ... on Post {\n      id\n      viewerEdge {\n        id\n        fullContent(postMeteringOptions: $postMeteringOptions) {\n          isLockedPreviewOnly\n          validatedShareKey\n          bodyModel {\n            ...PostBody_bodyModel\n            __typename\n          }\n          __typename\n        }\n        __typename\n      }\n      __typename\n    }\n    __typename\n  }\n}\n\nfragment PostBody_bodyModel on RichText {\n  sections {\n    name\n    startIndex\n    textLayout\n    imageLayout\n    backgroundImage {\n      id\n      originalHeight\n      originalWidth\n      __typename\n    }\n    videoLayout\n    backgroundVideo {\n      videoId\n      originalHeight\n      originalWidth\n      previewImageId\n      __typename\n    }\n    __typename\n  }\n  paragraphs {\n    id\n    ...PostBodySection_paragraph\n    __typename\n  }\n  ...normalizedBodyModel_richText\n  __typename\n}\n\nfragment PostBodySection_paragraph on Paragraph {\n  name\n  ...PostBodyParagraph_paragraph\n  __typename\n  id\n}\n\nfragment PostBodyParagraph_paragraph on Paragraph {\n  name\n  type\n  ...ImageParagraph_paragraph\n  ...TextParagraph_paragraph\n  ...IframeParagraph_paragraph\n  ...MixtapeParagraph_paragraph\n  ...CodeBlockParagraph_paragraph\n  __typename\n  id\n}\n\nfragment ImageParagraph_paragraph on Paragraph {\n  href\n  layout\n  metadata {\n    id\n    originalHeight\n    originalWidth\n    focusPercentX\n    focusPercentY\n    alt\n    __typename\n  }\n  ...Markups_paragraph\n  ...ParagraphRefsMapContext_paragraph\n  ...PostAnnotationsMarker_paragraph\n  __typename\n  id\n}\n\nfragment Markups_paragraph on Paragraph {\n  name\n  text\n  hasDropCap\n  dropCapImage {\n    ...MarkupNode_data_dropCapImage\n    __typename\n    id\n  }\n  markups {\n    type\n    start\n    end\n    href\n    anchorType\n    userId\n    linkMetadata {\n      httpStatus\n      __typename\n    }\n    __typename\n  }\n  __typename\n  id\n}\n\nfragment MarkupNode_data_dropCapImage on ImageMetadata {\n  ...DropCap_image\n  __typename\n  id\n}\n\nfragment DropCap_image on ImageMetadata {\n  id\n  originalHeight\n  originalWidth\n  __typename\n}\n\nfragment ParagraphRefsMapContext_paragraph on Paragraph {\n  id\n  name\n  text\n  __typename\n}\n\nfragment PostAnnotationsMarker_paragraph on Paragraph {\n  ...PostViewNoteCard_paragraph\n  __typename\n  id\n}\n\nfragment PostViewNoteCard_paragraph on Paragraph {\n  name\n  __typename\n  id\n}\n\nfragment TextParagraph_paragraph on Paragraph {\n  type\n  hasDropCap\n  codeBlockMetadata {\n    mode\n    lang\n    __typename\n  }\n  ...Markups_paragraph\n  ...ParagraphRefsMapContext_paragraph\n  __typename\n  id\n}\n\nfragment IframeParagraph_paragraph on Paragraph {\n  iframe {\n    mediaResource {\n      id\n      iframeSrc\n      iframeHeight\n      iframeWidth\n      title\n      __typename\n    }\n    __typename\n  }\n  layout\n  ...getEmbedlyCardUrlParams_paragraph\n  ...Markups_paragraph\n  __typename\n  id\n}\n\nfragment getEmbedlyCardUrlParams_paragraph on Paragraph {\n  type\n  iframe {\n    mediaResource {\n      iframeSrc\n      __typename\n    }\n    __typename\n  }\n  __typename\n  id\n}\n\nfragment MixtapeParagraph_paragraph on Paragraph {\n  type\n  mixtapeMetadata {\n    href\n    mediaResource {\n      mediumCatalog {\n        id\n        __typename\n      }\n      __typename\n    }\n    __typename\n  }\n  ...GenericMixtapeParagraph_paragraph\n  __typename\n  id\n}\n\nfragment GenericMixtapeParagraph_paragraph on Paragraph {\n  text\n  mixtapeMetadata {\n    href\n    thumbnailImageId\n    __typename\n  }\n  markups {\n    start\n    end\n    type\n    href\n    __typename\n  }\n  __typename\n  id\n}\n\nfragment CodeBlockParagraph_paragraph on Paragraph {\n  codeBlockMetadata {\n    lang\n    mode\n    __typename\n  }\n  __typename\n  id\n}\n\nfragment normalizedBodyModel_richText on RichText {\n  paragraphs {\n    markups {\n      type\n      __typename\n    }\n    codeBlockMetadata {\n      lang\n      mode\n      __typename\n    }\n    ...getParagraphHighlights_paragraph\n    ...getParagraphPrivateNotes_paragraph\n    __typename\n  }\n  sections {\n    startIndex\n    ...getSectionEndIndex_section\n    __typename\n  }\n  ...getParagraphStyles_richText\n  ...getParagraphSpaces_richText\n  __typename\n}\n\nfragment getParagraphHighlights_paragraph on Paragraph {\n  name\n  __typename\n  id\n}\n\nfragment getParagraphPrivateNotes_paragraph on Paragraph {\n  name\n  __typename\n  id\n}\n\nfragment getSectionEndIndex_section on Section {\n  startIndex\n  __typename\n}\n\nfragment getParagraphStyles_richText on RichText {\n  paragraphs {\n    text\n    type\n    __typename\n  }\n  sections {\n    ...getSectionEndIndex_section\n    __typename\n  }\n  __typename\n}\n\nfragment getParagraphSpaces_richText on RichText {\n  paragraphs {\n    layout\n    metadata {\n      originalHeight\n      originalWidth\n      id\n      __typename\n    }\n    type\n    ...paragraphExtendsImageGrid_paragraph\n    __typename\n  }\n  ...getSeriesParagraphTopSpacings_richText\n  ...getPostParagraphTopSpacings_richText\n  __typename\n}\n\nfragment paragraphExtendsImageGrid_paragraph on Paragraph {\n  layout\n  type\n  __typename\n  id\n}\n\nfragment getSeriesParagraphTopSpacings_richText on RichText {\n  paragraphs {\n    id\n    __typename\n  }\n  sections {\n    startIndex\n    __typename\n  }\n  __typename\n}\n\nfragment getPostParagraphTopSpacings_richText on RichText {\n  paragraphs {\n    layout\n    text\n    codeBlockMetadata {\n      lang\n      mode\n      __typename\n    }\n    __typename\n  }\n  sections {\n    startIndex\n    __typename\n  }\n  __typename\n}\n"
      }
]
  • posdId : Article ID, provided by the API that retrieves the article list above.

Postman :

Response:

Article Source as shown above:

  • response[0]["data"]["post"]["viewerEdge"]["fullContent"]["bodyModel"]["paragraphs"] : The entire article’s paragraphs; combined, they form the full article.

  • ["markups"] : Text styles of the paragraph, such as bold, hyperlinks…

As for how to convert this JSON description format into Markdown, you can directly refer to or use the open-source tool I previously developed — ZMediumToMarkdown

  • If you want to crawl your own paid articles, you need to include the sid and uid login token information (see below).

Medium x Cloudflare Offense and Defense

The second topic of this article is Cloudflare. Starting around the second half of 2025, Medium’s Cloudflare protection reached nearly the highest level, blocking all requests from cloud services (my attempts using Google Apps Script / GitHub Actions were all blocked), causing data scraping to fail.

Blocked Message: 403

1
<!DOCTYPE html><html lang="en-US"><head><title>Just a moment...</title><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">....

This is very frustrating for me because my mirror site ( https://zhgchg.li ) has been running smoothly for several years. Whenever Medium publishes a new article, a script automatically syncs it there regularly (using the Private API GraphQL). If cloud services get blocked, I will have to run the script manually on my local computer.

Add sid, uid to Header Cookies ❌

At first, I added sid and uid in the Header Cookies, which acted as Medium login credentials and worked fine, but after a few months, even this method stopped working.

  • uid : your user ID

  • sid : your access token (keep it confidential)

Cloudflare Worker Proxy Request ✅

After trying everything without success, I had a sudden idea to use Cloudflare’s magic to defeat magic. Using Cloudflare, it surprisingly worked! It was not blocked by Cloudflare Bot protection.

Demo Code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
export default {

  async fetch(request, env, ctx) {

    const url = new URL(request.url);
    const path = url.pathname;

    if (path == "/graphql") {
      let body;
      try {
        body = await request.json();
      } catch {
        return new Response("Invalid JSON body", { status: 400 });
      }

      let apiURL = "https://medium.com/_/graphql";

      const apiResponse = await fetch(apiURL, {
        method: "POST",
        headers: {
          "Accept": "application/json",
          "Content-Type": "application/json",
          "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/142.0.0.0 Safari/537.36 Edg/142.0.0.0",
          "Cookie": request.headers.get("cookie")
        },
        body: JSON.stringify(body),
      });

      const json = await apiResponse.json();
      return new Response(JSON.stringify(json), {
        status: apiResponse.status,
        headers: {
          "Content-Type": "application/json; charset=utf-8",
        },
      });
    }

    return new Response("Not Found", { status: 404 });
  },
};

Request:

Change from https://medium.com/_/graphql to your deployed Cloudflare Worker URL.

Summary

This is my journey battling with the Medium API over the years. Currently, all articles (Markdown files) and images are backed up at https://zhgchg.li, including all attached image files. There is a copy on the GitHub repo and another on my computer hard drive, ensuring complete safety.

I still hope Medium will last for a long time! This content is for experimental reference only; the author assumes no responsibility for its use.

If you have any questions or feedback, feel free to contact me.


🍺 Buy me a beer on PayPal

👉👉👉 Follow Me On Medium! (1,053+ Followers) 👈👈👈

This post was originally published on Medium (View original post), and automatically converted and synced by ZMediumToMarkdown.

Improve this page on Github.

This post is licensed under CC BY 4.0 by the author.