# Tumblr Blog Posts Scraper (`scrapingmonkey/tumblr-blog-posts-scraper`) Actor

Extract posts from public Tumblr blogs with text, tags, media, reblog trails and engagement counts.

- **URL**: https://apify.com/scrapingmonkey/tumblr-blog-posts-scraper.md
- **Developed by:** [ScrapingMonkey](https://apify.com/scrapingmonkey) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.00 / 1,000 results

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

Collect public posts from selected Tumblr blogs with pagination. **Tumblr Blog Posts Scraper** saves each post as a separate row with its text, tags, media references, dates, visible engagement and reblog context.

Build a publication log for known sources while retaining the original links and the content needed for later analysis.

| At a glance | Details |
|---|---|
| 📥 Input | Public Tumblr blog names or blog homepage URLs. |
| 📤 Output | One post per success row, with source input retained |
| 📄 Pagination | pagesPerBlog limits result pages separately for each blog. The number of posts on a page varies because the website can include non-post modules and repeated items. |
| 🔐 Login required | No |
| ⚡ Processing | Up to 5 HTTP requests concurrently with automatic retries |
| 💾 Delivery | One Apify dataset view, useful flat columns and complete nested JSON |

### What the Tumblr Blog Posts scraper collects 📦

The Actor collects the public feed of each supplied blog. Different post formats share one schema, and available media and reblog content remain within each post row.

Data can include:

- Post IDs, canonical links, source blog, publication dates and tags
- Available text, summaries, content blocks
- Image variants, video references and link previews when present
- Visible note, like, reblog and reply counts when supplied
- Original and parent reblog references, with the available reblog trail

### How to collect blog posts from Tumblr 🚀

1. Enter one or more supported inputs in `inputList`.
2. Set the result-page budget for each input.
3. Start the Actor.
4. Open the **Posts** dataset view and review the individual records.
5. Export the dataset or retrieve it from your application.

```json
{
  "inputList": [
    "staff"
  ],
  "pagesPerBlog": 1
}
```

pagesPerBlog limits result pages separately for each blog. The number of posts on a page varies because the website can include non-post modules and repeated items.

### Tumblr blog posts data and complete output 📦

| Field | Type | Meaning |
|---|---|---|
| `status` | string | Result status: success or failed. |
| `input` | string | Original submitted input. |
| `id` | string or null | Identifier of this object, preserved as a string. |
| `url` | string or null | Public source URL for this object. |
| `blog_name` | string or null | Name of the blog associated with this post or trail entry. |
| `blog_uuid` | string or null | UUID of the blog associated with this post or trail entry. |
| `blog_title` | string or null | Available title of the source blog. |
| `blog_url` | string or null | Public URL of the source blog. |
| `blog_avatar_url` | string or null | Available avatar URL of the source blog. |
| `post_type` | string or null | Post type supplied by Tumblr; content blocks describe the actual components. |
| `original_type` | string or null | Original post-type value when supplied by Tumblr. |
| `summary` | string or null | Public post summary returned by Tumblr. |
| `text` | string or null | Combined available text from the reblog trail and the current post. |
| `tags` | array or null | Available tag values associated with the post or interaction. |
| `published_at` | string or null | Publication time in an ISO-formatted date string when supplied. |
| `timestamp` | integer or null | Source Unix timestamp in seconds; fractional precision is retained when supplied. |
| `note_count` | integer or null | Public combined note count; not a guarantee of retrievable interaction records. |
| `like_count` | integer or null | Public like count supplied for the post. |
| `reblog_count` | integer or null | Public reblog count supplied for the post. |
| `reply_count` | integer or null | Public reply count supplied for the post. |
| `is_nsfw` | boolean or null | Source NSFW flag when supplied. |
| `is_blazed` | boolean or null | Source flag indicating that the post is marked as blazed. |
| `media` | array or null | Available media renditions and posters from the post and its reblog trail. |
| `media[].type` | string or null | Object or content type supplied or normalized for this record. |
| `media[].role` | string or null | Media role: a main media rendition or a poster image. |
| `media[].url` | string or null | Public source URL for this object. |
| `media[].width` | integer or null | Available image or media width in pixels. |
| `media[].height` | integer or null | Available image or media height in pixels. |
| `media[].mime_type` | string or null | Source media MIME type when supplied. |
| `content` | array or null | Available structured content blocks retained in the parent record. |
| `content[].type` | string or null | Object or content type supplied or normalized for this record. |
| `content[].text` | string or null | Available text retained for this record. |
| `content[].subtype` | string or null | Content-block subtype when supplied, such as a text presentation style. |
| `content[].url` | string or null | Public source URL for this object. |
| `content[].data_json` | string or null | Complete source content block serialized as a JSON string. |
| `trail` | array or null | Available reblog-trail entries, preserving blog, post and content references. |
| `trail[].blog_name` | string or null | Name of the blog associated with this post or trail entry. |
| `trail[].blog_uuid` | string or null | UUID of the blog associated with this post or trail entry. |
| `trail[].blog_url` | string or null | Public URL of the source blog. |
| `trail[].post_id` | string or null | Source post ID associated with this interaction or trail entry. |
| `trail[].text` | string or null | Available text retained for this record. |
| `trail[].content` | array or null | Available structured content blocks retained in the parent record. |
| `trail[].content[].type` | string or null | Object or content type supplied or normalized for this record. |
| `trail[].content[].text` | string or null | Available text retained for this record. |
| `trail[].content[].subtype` | string or null | Content-block subtype when supplied, such as a text presentation style. |
| `trail[].content[].url` | string or null | Public source URL for this object. |
| `trail[].content[].data_json` | string or null | Complete source content block serialized as a JSON string. |
| `reblogged_from_id` | string or null | Immediate source-post ID of the reblog when supplied. |
| `reblogged_from_name` | string or null | Immediate source blog name of the reblog when supplied. |
| `reblogged_from_url` | string or null | Immediate source-post URL of the reblog when supplied. |
| `reblogged_root_id` | string or null | Root or original post ID of the reblog when supplied. |
| `reblogged_root_name` | string or null | Root or original blog name of the reblog when supplied. |
| `reblogged_root_url` | string or null | Root or original post URL of the reblog when supplied. |

`text` combines available text from the reblog trail and the current post. The `content` array preserves individual content blocks; each `data_json` string contains the complete source block, including type-specific image, video, link or poll data. The `media` array keeps available renditions and posters with their source context. IDs remain strings so large Tumblr identifiers retain their exact digits.

Every top-level output field appears in these complete examples. The success example is normalized from a public response; its values are a snapshot and can change. Nested arrays remain inside their parent result.

Complete representative success result:

```json
{
  "status": "success",
  "input": "staff",
  "id": "822057428507049984",
  "url": "https://staff.tumblr.com/post/822057428507049984/in-case-youre-looking-for-a-blog-thats-gone",
  "blog_name": "staff",
  "blog_uuid": "t:0aY0xL2Fi1OFJg4YxpmegQ",
  "blog_title": "Tumblr Staff",
  "blog_url": "https://staff.tumblr.com/",
  "blog_avatar_url": "https://64.media.tumblr.com/dbc619ed53b0b1f9da04189686cb10e7/e72ec0c8ebd4ace0-49/s512x512u_c1/81e5a61444bd4691042dff4f16c1240cb65d4642.pnj",
  "post_type": "blocks",
  "original_type": "regular",
  "summary": "Deleted accounts can now be recovered up to 30 days later",
  "text": "Deleted accounts can now be recovered up to 30 days later\n\nWe’re making a big change to how account deletion works on Tumblr, and we’re really excited about it, because this is something that some of you have been requesting for… well… a literal decade.\n\nBefore today, when you deleted your Tumblr account, it was immediate and permanent. Occasionally, this resulted in Very Sad Times. Even though we’ve tried to make it super difficult to accidentally delete your account, this is something that still happens a lot. Like, a lot. There’s also plenty of folks who delete their account on purpose, but then regret it shortly afterward. Worst of all, if your account was hacked, and then deleted by the hacker, there was no way to get it back. \n\nAll of these problems are *poof* no more. As of today, when you delete your account, we will keep your data for 30 days. Your account will remain recoverable during that time, and you can contact us within that 30 day window if you’d like us to restore your account.\n\nEventually, we hope to make this process a bit easier, and allow you to restore your account with a single click of a button. For right now, though, you’ll need to contact us via tumblr.com/support and choose the category “Account Access” > “I have deleted my account or blog by accident”. \n\nFAQs\n\nHow do I delete my account? Does that process look different now?\n\nYou can follow the steps here to delete your account on the web or through the mobile app, which works pretty much the same way as before. You’ll notice we’ve updated the confirmation screen to reflect the new process, though.\n\nDoes a deleted account still appear on Tumblr during this 30 day window?\n\nNope. As soon as you submit the request to delete your account, all of your blogs will no longer be accessible (they’ll 404), no one will be able to message you, your posts will no longer appear in search results, and you won’t be able to log in anymore. This happens right away, not 30 days later. Deleted accounts still behave exactly as they always have.\n\nWhat about my email address and username? Will those become available again immediately after account deletion, like they did before?\n\nNotably, no, they will not. In order to make it possible for the account to be restored during the 30 day window, the username and email address must remain associated with the account during that time. So they won’t be available to register again until 30 days after you’ve deleted your account.\n\nIf you’re deleting your account, and you already know that you’d like to use the same username or email address on a new account immediately afterward, we recommend that you change your username and email address before deleting the account. That way, they will become available right away, instead of being on hold for 30 days. \n\nWhat if I’ve accidentally deleted one of my sideblogs, but not my entire account?\n\nIf you delete a sideblog, it will be deleted right away, and cannot be restored. We can only restore an entire account (which will restore all of its blogs along with it). \n\nIs this feature retroactive? Can you restore the account I deleted two years ago?\n\nAs much as we would like this to be possible, the answer is no. We still haven’t perfected the art of time travel, so all accounts deleted before today are still deleted for good. This new change will only apply to accounts which are deleted after this announcement is posted.\n\nWhere can I learn more about the account deletion process?\n\nYou can check out our support documentation and Privacy Policy. Both have been updated to reflect these changes.\n\nIn case you’re looking for a blog that’s gone missing on Tumblr and didn’t see this recent update.\n\n\nA missing blog without “-deactivated” isn’t necessarily a sign of a suspension, it might just mean that someone deleted their own account and may still bring it back within 30 days.",
  "tags": [
    "tumblr"
  ],
  "published_at": "2026-07-13T20:37:36Z",
  "timestamp": 1783975056,
  "note_count": 12266,
  "like_count": 9361,
  "reblog_count": 2081,
  "reply_count": 824,
  "is_nsfw": false,
  "is_blazed": false,
  "media": [],
  "content": [
    {
      "type": "text",
      "text": "In case you’re looking for a blog that’s gone missing on Tumblr and didn’t see this recent update.",
      "subtype": null,
      "url": null,
      "data_json": "{\"type\":\"text\",\"text\":\"In case you’re looking for a blog that’s gone missing on Tumblr and didn’t see this recent update.\"}"
    },
    {
      "type": "text",
      "text": "\nA missing blog without “-deactivated” isn’t necessarily a sign of a suspension, it might just mean that someone deleted their own account and may still bring it back within 30 days.",
      "subtype": null,
      "url": null,
      "data_json": "{\"type\":\"text\",\"text\":\"\\nA missing blog without “-deactivated” isn’t necessarily a sign of a suspension, it might just mean that someone deleted their own account and may still bring it back within 30 days.\"}"
    }
  ],
  "trail": [
    {
      "blog_name": "changes",
      "blog_uuid": "t:WX5xItRbCiJH_GJDsIdhAQ",
      "blog_url": "https://changes.tumblr.com/",
      "post_id": "818409292753436672",
      "text": "Deleted accounts can now be recovered up to 30 days later\n\nWe’re making a big change to how account deletion works on Tumblr, and we’re really excited about it, because this is something that some of you have been requesting for… well… a literal decade.\n\nBefore today, when you deleted your Tumblr account, it was immediate and permanent. Occasionally, this resulted in Very Sad Times. Even though we’ve tried to make it super difficult to accidentally delete your account, this is something that still happens a lot. Like, a lot. There’s also plenty of folks who delete their account on purpose, but then regret it shortly afterward. Worst of all, if your account was hacked, and then deleted by the hacker, there was no way to get it back. \n\nAll of these problems are *poof* no more. As of today, when you delete your account, we will keep your data for 30 days. Your account will remain recoverable during that time, and you can contact us within that 30 day window if you’d like us to restore your account.\n\nEventually, we hope to make this process a bit easier, and allow you to restore your account with a single click of a button. For right now, though, you’ll need to contact us via tumblr.com/support and choose the category “Account Access” > “I have deleted my account or blog by accident”. \n\nFAQs\n\nHow do I delete my account? Does that process look different now?\n\nYou can follow the steps here to delete your account on the web or through the mobile app, which works pretty much the same way as before. You’ll notice we’ve updated the confirmation screen to reflect the new process, though.\n\nDoes a deleted account still appear on Tumblr during this 30 day window?\n\nNope. As soon as you submit the request to delete your account, all of your blogs will no longer be accessible (they’ll 404), no one will be able to message you, your posts will no longer appear in search results, and you won’t be able to log in anymore. This happens right away, not 30 days later. Deleted accounts still behave exactly as they always have.\n\nWhat about my email address and username? Will those become available again immediately after account deletion, like they did before?\n\nNotably, no, they will not. In order to make it possible for the account to be restored during the 30 day window, the username and email address must remain associated with the account during that time. So they won’t be available to register again until 30 days after you’ve deleted your account.\n\nIf you’re deleting your account, and you already know that you’d like to use the same username or email address on a new account immediately afterward, we recommend that you change your username and email address before deleting the account. That way, they will become available right away, instead of being on hold for 30 days. \n\nWhat if I’ve accidentally deleted one of my sideblogs, but not my entire account?\n\nIf you delete a sideblog, it will be deleted right away, and cannot be restored. We can only restore an entire account (which will restore all of its blogs along with it). \n\nIs this feature retroactive? Can you restore the account I deleted two years ago?\n\nAs much as we would like this to be possible, the answer is no. We still haven’t perfected the art of time travel, so all accounts deleted before today are still deleted for good. This new change will only apply to accounts which are deleted after this announcement is posted.\n\nWhere can I learn more about the account deletion process?\n\nYou can check out our support documentation and Privacy Policy. Both have been updated to reflect these changes.",
      "content": [
        {
          "type": "text",
          "text": "Deleted accounts can now be recovered up to 30 days later",
          "subtype": "heading1",
          "url": null,
          "data_json": "{\"type\":\"text\",\"text\":\"Deleted accounts can now be recovered up to 30 days later\",\"subtype\":\"heading1\"}"
        },
        {
          "type": "text",
          "text": "We’re making a big change to how account deletion works on Tumblr, and we’re really excited about it, because this is something that some of you have been requesting for… well… a literal decade.",
          "subtype": null,
          "url": null,
          "data_json": "{\"type\":\"text\",\"text\":\"We’re making a big change to how account deletion works on Tumblr, and we’re really excited about it, because this is something that some of you have been requesting for… well… a literal decade.\"}"
        },
        {
          "type": "text",
          "text": "Before today, when you deleted your Tumblr account, it was immediate and permanent. Occasionally, this resulted in Very Sad Times. Even though we’ve tried to make it super difficult to accidentally delete your account, this is something that still happens a lot. Like, a lot. There’s also plenty of folks who delete their account on purpose, but then regret it shortly afterward. Worst of all, if your account was hacked, and then deleted by the hacker, there was no way to get it back. ",
          "subtype": null,
          "url": null,
          "data_json": "{\"type\":\"text\",\"text\":\"Before today, when you deleted your Tumblr account, it was immediate and permanent. Occasionally, this resulted in Very Sad Times. Even though we’ve tried to make it super difficult to accidentally delete your account, this is something that still happens a lot. Like, a lot. There’s also plenty of folks who delete their account on purpose, but then regret it shortly afterward. Worst of all, if your account was hacked, and then deleted by the hacker, there was no way to get it back. \",\"formatting\":[{\"type\":\"italic\",\"start\":269,\"end\":275}]}"
        },
        {
          "type": "text",
          "text": "All of these problems are *poof* no more. As of today, when you delete your account, we will keep your data for 30 days. Your account will remain recoverable during that time, and you can contact us within that 30 day window if you’d like us to restore your account.",
          "subtype": null,
          "url": null,
          "data_json": "{\"type\":\"text\",\"text\":\"All of these problems are *poof* no more. As of today, when you delete your account, we will keep your data for 30 days. Your account will remain recoverable during that time, and you can contact us within that 30 day window if you’d like us to restore your account.\",\"formatting\":[{\"type\":\"italic\",\"start\":26,\"end\":32},{\"type\":\"link\",\"start\":188,\"end\":198,\"url\":\"http://tumblr.com/support\"}]}"
        },
        {
          "type": "text",
          "text": "Eventually, we hope to make this process a bit easier, and allow you to restore your account with a single click of a button. For right now, though, you’ll need to contact us via tumblr.com/support and choose the category “Account Access” > “I have deleted my account or blog by accident”. ",
          "subtype": null,
          "url": null,
          "data_json": "{\"type\":\"text\",\"text\":\"Eventually, we hope to make this process a bit easier, and allow you to restore your account with a single click of a button. For right now, though, you’ll need to contact us via tumblr.com/support and choose the category “Account Access” > “I have deleted my account or blog by accident”. \",\"formatting\":[{\"type\":\"link\",\"start\":179,\"end\":197,\"url\":\"http://tumblr.com/support\"}]}"
        },
        {
          "type": "text",
          "text": "FAQs",
          "subtype": "heading1",
          "url": null,
          "data_json": "{\"type\":\"text\",\"text\":\"FAQs\",\"subtype\":\"heading1\"}"
        },
        {
          "type": "text",
          "text": "How do I delete my account? Does that process look different now?",
          "subtype": "heading2",
          "url": null,
          "data_json": "{\"type\":\"text\",\"text\":\"How do I delete my account? Does that process look different now?\",\"subtype\":\"heading2\"}"
        },
        {
          "type": "text",
          "text": "You can follow the steps here to delete your account on the web or through the mobile app, which works pretty much the same way as before. You’ll notice we’ve updated the confirmation screen to reflect the new process, though.",
          "subtype": null,
          "url": null,
          "data_json": "{\"type\":\"text\",\"text\":\"You can follow the steps here to delete your account on the web or through the mobile app, which works pretty much the same way as before. You’ll notice we’ve updated the confirmation screen to reflect the new process, though.\",\"formatting\":[{\"type\":\"link\",\"start\":25,\"end\":29,\"url\":\"https://help.tumblr.com/knowledge-base/delete-your-account-or-blog/\"}]}"
        },
        {
          "type": "text",
          "text": "Does a deleted account still appear on Tumblr during this 30 day window?",
          "subtype": "heading2",
          "url": null,
          "data_json": "{\"type\":\"text\",\"text\":\"Does a deleted account still appear on Tumblr during this 30 day window?\",\"subtype\":\"heading2\"}"
        },
        {
          "type": "text",
          "text": "Nope. As soon as you submit the request to delete your account, all of your blogs will no longer be accessible (they’ll 404), no one will be able to message you, your posts will no longer appear in search results, and you won’t be able to log in anymore. This happens right away, not 30 days later. Deleted accounts still behave exactly as they always have.",
          "subtype": null,
          "url": null,
          "data_json": "{\"type\":\"text\",\"text\":\"Nope. As soon as you submit the request to delete your account, all of your blogs will no longer be accessible (they’ll 404), no one will be able to message you, your posts will no longer appear in search results, and you won’t be able to log in anymore. This happens right away, not 30 days later. Deleted accounts still behave exactly as they always have.\"}"
        },
        {
          "type": "text",
          "text": "What about my email address and username? Will those become available again immediately after account deletion, like they did before?",
          "subtype": "heading2",
          "url": null,
          "data_json": "{\"type\":\"text\",\"text\":\"What about my email address and username? Will those become available again immediately after account deletion, like they did before?\",\"subtype\":\"heading2\"}"
        },
        {
          "type": "text",
          "text": "Notably, no, they will not. In order to make it possible for the account to be restored during the 30 day window, the username and email address must remain associated with the account during that time. So they won’t be available to register again until 30 days after you’ve deleted your account.",
          "subtype": null,
          "url": null,
          "data_json": "{\"type\":\"text\",\"text\":\"Notably, no, they will not. In order to make it possible for the account to be restored during the 30 day window, the username and email address must remain associated with the account during that time. So they won’t be available to register again until 30 days after you’ve deleted your account.\",\"formatting\":[{\"type\":\"bold\",\"start\":9,\"end\":26}]}"
        },
        {
          "type": "text",
          "text": "If you’re deleting your account, and you already know that you’d like to use the same username or email address on a new account immediately afterward, we recommend that you change your username and email address before deleting the account. That way, they will become available right away, instead of being on hold for 30 days. ",
          "subtype": null,
          "url": null,
          "data_json": "{\"type\":\"text\",\"text\":\"If you’re deleting your account, and you already know that you’d like to use the same username or email address on a new account immediately afterward, we recommend that you change your username and email address before deleting the account. That way, they will become available right away, instead of being on hold for 30 days. \",\"formatting\":[{\"type\":\"italic\",\"start\":213,\"end\":219}]}"
        },
        {
          "type": "text",
          "text": "What if I’ve accidentally deleted one of my sideblogs, but not my entire account?",
          "subtype": "heading2",
          "url": null,
          "data_json": "{\"type\":\"text\",\"text\":\"What if I’ve accidentally deleted one of my sideblogs, but not my entire account?\",\"subtype\":\"heading2\"}"
        },
        {
          "type": "text",
          "text": "If you delete a sideblog, it will be deleted right away, and cannot be restored. We can only restore an entire account (which will restore all of its blogs along with it). ",
          "subtype": null,
          "url": null,
          "data_json": "{\"type\":\"text\",\"text\":\"If you delete a sideblog, it will be deleted right away, and cannot be restored. We can only restore an entire account (which will restore all of its blogs along with it). \",\"formatting\":[{\"type\":\"bold\",\"start\":26,\"end\":80},{\"type\":\"bold\",\"start\":104,\"end\":118}]}"
        },
        {
          "type": "text",
          "text": "Is this feature retroactive? Can you restore the account I deleted two years ago?",
          "subtype": "heading2",
          "url": null,
          "data_json": "{\"type\":\"text\",\"text\":\"Is this feature retroactive? Can you restore the account I deleted two years ago?\",\"subtype\":\"heading2\"}"
        },
        {
          "type": "text",
          "text": "As much as we would like this to be possible, the answer is no. We still haven’t perfected the art of time travel, so all accounts deleted before today are still deleted for good. This new change will only apply to accounts which are deleted after this announcement is posted.",
          "subtype": null,
          "url": null,
          "data_json": "{\"type\":\"text\",\"text\":\"As much as we would like this to be possible, the answer is no. We still haven’t perfected the art of time travel, so all accounts deleted before today are still deleted for good. This new change will only apply to accounts which are deleted after this announcement is posted.\",\"formatting\":[{\"type\":\"italic\",\"start\":242,\"end\":247}]}"
        },
        {
          "type": "text",
          "text": "Where can I learn more about the account deletion process?",
          "subtype": "heading2",
          "url": null,
          "data_json": "{\"type\":\"text\",\"text\":\"Where can I learn more about the account deletion process?\",\"subtype\":\"heading2\"}"
        },
        {
          "type": "text",
          "text": "You can check out our support documentation and Privacy Policy. Both have been updated to reflect these changes.",
          "subtype": null,
          "url": null,
          "data_json": "{\"type\":\"text\",\"text\":\"You can check out our support documentation and Privacy Policy. Both have been updated to reflect these changes.\",\"formatting\":[{\"type\":\"link\",\"start\":8,\"end\":43,\"url\":\"https://help.tumblr.com/knowledge-base/delete-your-account-or-blog/\"},{\"type\":\"link\",\"start\":48,\"end\":62,\"url\":\"https://www.tumblr.com/privacy/en\"}]}"
        }
      ]
    }
  ],
  "reblogged_from_id": "818409292753436672",
  "reblogged_from_name": "",
  "reblogged_from_url": "https://changes.tumblr.com/post/818409292753436672/deleted-accounts-can-now-be-recovered-up-to-30",
  "reblogged_root_id": "818409292753436672",
  "reblogged_root_name": "changes",
  "reblogged_root_url": "https://changes.tumblr.com/post/818409292753436672/deleted-accounts-can-now-be-recovered-up-to-30"
}
```

Complete failed result:

```json
{
  "status": "failed",
  "input": "invalid input",
  "id": null,
  "url": null,
  "blog_name": null,
  "blog_uuid": null,
  "blog_title": null,
  "blog_url": null,
  "blog_avatar_url": null,
  "post_type": null,
  "original_type": null,
  "summary": null,
  "text": null,
  "tags": null,
  "published_at": null,
  "timestamp": null,
  "note_count": null,
  "like_count": null,
  "reblog_count": null,
  "reply_count": null,
  "is_nsfw": null,
  "is_blazed": null,
  "media": null,
  "content": null,
  "trail": null,
  "reblogged_from_id": null,
  "reblogged_from_name": null,
  "reblogged_from_url": null,
  "reblogged_root_id": null,
  "reblogged_root_name": null,
  "reblogged_root_url": null
}
```

A failed row preserves `input`, sets `status` to `failed`, and sets every other top-level field to `null`. The run log records the reason. Optional successful fields can be null or empty when Tumblr does not supply them. Object fields are exposed through useful columns in the single **Posts** view; arrays are not expanded into extra result rows.

### Input requirements and pagination settings ⚙️

| Parameter | Type | Required | Default | Rules |
|---|---|---|---|---|
| `inputList` | array of strings | Yes | None | Public Tumblr blog names or blog homepage URLs. At least `1` item. |
| `pagesPerBlog` | integer | No | `1` | Maximum result pages per input. Setup requests do not count as pages. Stops when the source has no next page or repeats a continuation. Actual rows per page can vary. Minimum `1`. |

Enter supported Tumblr blog names or blog URLs. Choose pages rather than an exact post count.

Supported examples include `staff`, `@staff`, `https://www.tumblr.com/staff`, `https://staff.tumblr.com/` and `https://www.tumblr.com/blog/view/staff`. Use a blog homepage for these actors; post links are separate inputs for Post Scraper.

Duplicate normalized inputs are processed once. Within the collection for one source input, repeated records are removed while distinct interactions or objects remain separate. The same object returned for different source inputs retains its source relationship.

The first result page counts as page 1. Public-page preparation and metadata lookups do not consume result pages. Collection stops at your page budget or the end of the available list. A short page alone does not mean that the list has ended.

### Tumblr blog posts use cases 🎯

#### Announcement logs

Collect a selected blog’s titles, text, dates and links for an editorial publication log.

#### Format and media inventories

Inspect available text, image, video and link content from a known source in one consistent dataset.

#### Reblog research

Keep source and reblog-trail references to study how material appears in a selected blog’s public feed.

### Pricing and saved-result behavior 💰

Check the Actor’s **Pricing** tab for the active pricing model and current rate. Store settings can change, so this README does not claim a fixed price or runtime.

Under dataset-item pricing:

- Each successful result represents one post for its source input.
- An invalid or unavailable input, an input with no accessible results, or an exhausted request can produce a `failed` row.
- Retry attempts and supporting requests do not create extra dataset rows by themselves.
- Nested media, profile information and other arrays remain part of their parent row.
- A normal empty continuation after earlier successes creates no additional row.
- Saved failed rows are not assumed to be free; check their treatment in the active pricing configuration.

More inputs and larger page budgets can produce more saved rows. Start with a small run and check actual usage before increasing the workload.

### Tumblr blog posts API 🔌

Replace `$ACTOR_ID` with the identifier shown in this Actor’s **API** tab and `$APIFY_TOKEN` with your Apify token.

```bash
curl -X POST "https://api.apify.com/v2/acts/$ACTOR_ID/runs?token=$APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"inputList":["staff"],"pagesPerBlog":1}'
```

Download the dataset in JSON, CSV, Excel or other formats available in the Console, or retrieve it through the Apify API. Use schedules, webhooks and Apify integrations to connect results to Google Sheets, Make, Zapier, cloud storage or your own application. These connections are configured separately by the user.

### Reliability, retries, and public-data limits ⚠️

Collection uses pure HTTP with up to five concurrent requests. Invalid syntax and confirmed missing, removed or unavailable targets stop without unnecessary retries. Temporary network or proxy failures, timeouts, blocking responses, malformed data, throttling and server errors allow up to five total attempts per request.

Successful earlier pages remain saved if a later request fails. A normal end after saved results is not retried. An input with no accessible results can receive a failed row; that alone does not prove that its underlying source does not exist. An exhausted later request can add a failed row while preserving previous output.

The available post formats include text, images, video, links and poll metadata. Poll vote totals and audio coverage are not promised. A reblog can have no new text while its content remains in the reblog trail. Media references are returned when available; media files are not downloaded and their links can expire. Blog feeds can contain pinned posts and need not be strictly chronological. A page budget does not guarantee full blog history.

Tumblr controls public availability, ranking and optional fields. Result counts can be affected by duplicates, removed content and changes during a run. A page budget is a collection limit, not a promise of exhaustive coverage.

An invalid string within a valid input list does not stop other inputs. Invalid overall configuration, such as a non-string list item or a wrong page-count type, exits before source requests. Startup failures, unavailable dataset storage or an unrecoverable result-save error can still stop the whole run. A failed save is not retried as a new scraping request.

### Frequently asked questions ❓

#### Can I request an exact number of posts?

You choose the number of result pages to attempt. Page size, duplicate items and public availability determine the final unique row count.

#### Does it keep the content of reblogs?

Yes. Available content and reblog-trail data remain in the parent post record. A post can legitimately have no new text of its own.

#### Does it download images and videos?

It returns available media references and metadata. It does not download the media files or guarantee that a link will remain available.

#### Can it collect poll results?

It can retain public poll questions, choices and settings when returned. Vote totals are not a supported promise.

#### Does it require a Tumblr account or personal cookies?

No. You do not need to provide a Tumblr account, password or personal session cookie. Collection uses HTTP without opening a browser.

#### What happens to invalid or unavailable inputs?

Invalid individual inputs are recorded as failed without a source request. Confirmed missing or unavailable targets stop without unnecessary retries. Temporary failures allow up to five total attempts per request; other inputs and earlier saved results remain available.

#### Can I export results or run the same input again?

Yes. Export the default dataset or retrieve it through the Apify API. You can create an Apify schedule and connect completed runs to your own workflow.

### Support, responsible use, and related actors 🛟

For a reproducible issue, use the Actor’s **Issues** tab and provide the run ID, approximate time, a safe public input, expected behavior and actual result. Include the mode or page budget when relevant. Never share access tokens, personal cookies or proxy credentials.

Use public data responsibly and follow applicable privacy, copyright, contractual and platform requirements before storing, analyzing or redistributing collected information.

# Actor input Schema

## `inputList` (type: `array`):

Public Tumblr blog names or blog homepage URLs.

## `pagesPerBlog` (type: `integer`):

Maximum result pages per input. Setup requests do not count as pages. Stops when the source has no next page or repeats a continuation. Actual rows per page can vary.

## Actor input object example

```json
{
  "inputList": [
    "staff"
  ],
  "pagesPerBlog": 1
}
```

# Actor output Schema

## `posts` (type: `string`):

One dataset row per public result. Check success or failed status.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "inputList": [
        "staff"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("scrapingmonkey/tumblr-blog-posts-scraper").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = { "inputList": ["staff"] }

# Run the Actor and wait for it to finish
run = client.actor("scrapingmonkey/tumblr-blog-posts-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "inputList": [
    "staff"
  ]
}' |
apify call scrapingmonkey/tumblr-blog-posts-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,scrapingmonkey/tumblr-blog-posts-scraper"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/AGfMSqjM9UKY4Gtb9/builds/FWXswuyZhJnAw13C1/openapi.json
