# Tumblr Tagged Posts Scraper (`automation-lab/tumblr-tagged-posts-scraper`) Actor

Extract public Tumblr tagged-feed posts, creators, media, tags, engagement, reblog context, and classification metadata without a Tumblr login.

- **URL**: https://apify.com/automation-lab/tumblr-tagged-posts-scraper.md
- **Developed by:** [Stas Persiianenko](https://apify.com/automation-lab) (community)
- **Categories:** Social media
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

Pay per event

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/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## Tumblr Tagged Posts Scraper

Extract structured public posts from Tumblr tagged feeds without a Tumblr login.
Provide tags such as `photography` or exact `https://www.tumblr.com/tagged/...` URLs and receive clean dataset rows with posts, creators, public blog metadata, tags, engagement counts, content blocks, media URLs, reblog context, and safety classification.

The Actor is designed for repeatable public tag snapshots.
It does not pretend to scrape private blogs, arbitrary profile pages, dashboards, or login-only content.

### What does Tumblr Tagged Posts Scraper do?

Tumblr Tagged Posts Scraper reads Tumblr's anonymous server-rendered tagged-feed pages and converts their embedded post data into integration-ready JSON.

Use it to:

- monitor public conversations around a topic;
- find creators posting under a niche tag;
- collect image, video, and link metadata for research;
- compare visible note counts between recurring snapshots;
- review public tags and classification signals;
- export Tumblr tagged posts to JSON, CSV, Excel, or another Apify integration.

Each run takes a current snapshot of the initial public feed returned by Tumblr for every supplied tag.
No browser or residential proxy is used.

### Who is this Tumblr scraper for?

#### Social-listening and trend teams

Track posts and creators appearing under campaign, cultural, aesthetic, or community tags.
Save scheduled snapshots and compare them in a warehouse or spreadsheet.

#### Creator discovery and A\&R teams

Find public blogs contributing media to genres, scenes, and visual styles.
Use `blogName`, public blog metadata, tags, content, and note counts to prioritize manual review.

#### Researchers and journalists

Create reproducible snapshots of publicly visible tagged feeds.
Preserve the source tag, source URL, and fetch time with every row.

#### Brand and content analysts

Study public content themes and engagement signals without manually scrolling Tumblr.
Classification fields can support triage, but should not replace human moderation.

### Why use this Actor?

- **Anonymous public source:** no Tumblr account, cookie, or API key is required.
- **Purpose-built output:** the dataset contains post and creator fields instead of raw HTML.
- **Multiple inputs:** use human-friendly tags, exact tagged-feed URLs, or both.
- **Global limit:** one `maxItems` value controls the complete run.
- **Deduplication:** repeated post IDs across supplied feeds are saved once.
- **Media-aware:** normalized content blocks retain useful media variants and dimensions.
- **Fail-closed parsing:** a changed Tumblr page shape raises a visible error instead of silently returning misleading empty output.
- **Low-cost architecture:** direct HTTP avoids browser and proxy overhead.

### What Tumblr data can I extract?

| Field | Description |
| --- | --- |
| `postId` | Tumblr's stable string post ID |
| `postUrl` | Public canonical post URL |
| `blogName` | Creator/blog username |
| `blog` | Public title, URL, description, avatar, adult flag, and selected theme fields |
| `timestamp` | Source Unix timestamp, preserved without reinterpretation |
| `date` | Tumblr's source date string when available |
| `summary` | Public post summary |
| `tags` | Tags attached to the post |
| `noteCount` | Visible total notes |
| `likeCount` | Visible like count when supplied by Tumblr |
| `reblogCount` | Visible reblog count when supplied by Tumblr |
| `replyCount` | Visible reply count when supplied by Tumblr |
| `reblogKey` | Public reblog key when available |
| `postType` | Current Tumblr post format/type |
| `originalType` | Legacy/original post type when available |
| `isNsfw` | Tumblr NSFW boolean |
| `classification` | Public Tumblr classification value |
| `isBrandSafe` | Public brand-safety flag when supplied |
| `content` | Normalized text/media/link content blocks |
| `trail` | Public reblog trail with blog, post, and content context |
| `sourceTag` | Tag that produced the record |
| `sourceUrl` | Canonical tagged-feed URL requested |
| `fetchedAt` | ISO 8601 snapshot time |

Optional fields are omitted when Tumblr does not provide them.
Content is capped at 50 blocks per post, three media variants per block, and 20 trail entries to keep rows safe and manageable.

### Getting started

1. Open the Actor input page.
2. Keep the default `photography` tag or replace it with your own public Tumblr tags.
3. Optionally add exact Tumblr tagged-feed URLs.
4. Choose a global `maxItems` between 1 and 200.
5. Click **Start**.
6. Open the default dataset when the run finishes.
7. Export the rows or connect them to your workflow.

A small first run such as 10–25 posts is best for checking that a tag matches your research goal.

### Input parameters

#### `tags`

An array of tag names.
A leading `#` is optional and removed automatically.
Spaces are supported, for example `digital art` or `outfit inspiration`.

```json
{
  "tags": ["photography", "street photography"],
  "maxItems": 25
}
```

#### `startUrls`

Optional exact public tagged-feed URLs.
Only HTTPS URLs on `www.tumblr.com` with the `/tagged/<tag>` path are accepted.
Profile URLs, individual post URLs, RSS URLs, and arbitrary Tumblr domains fail validation.

```json
{
  "tags": [],
  "startUrls": [
    { "url": "https://www.tumblr.com/tagged/digital%20art" }
  ],
  "maxItems": 25
}
```

#### `maxItems`

The maximum number of unique posts saved across all tags and URLs.
The allowed range is 1–200 and the default is 50.
The Actor stops fetching additional sources once the global limit is reached.

Provide at least one tag or tagged-feed URL.
At most 20 unique sources are accepted in one run.

### Output example

The following abbreviated row reflects the current public `photography` feed shape:

```json
{
  "postId": "798772056005148672",
  "postUrl": "https://www.tumblr.com/princesssokphanny/798772056005148672/a-once-in-a-lifetime-shot-the-moon-perfectly",
  "blogName": "princesssokphanny",
  "blog": {
    "name": "princesssokphanny",
    "title": "Sokphanny Tith",
    "url": "https://www.tumblr.com/princesssokphanny",
    "isAdult": false
  },
  "summary": "A once-in-a-lifetime shot — the moon perfectly framed by a rainbow.",
  "tags": ["aesthetic", "sky", "photography"],
  "noteCount": 125,
  "postType": "blocks",
  "isNsfw": false,
  "classification": "clean",
  "content": [
    { "type": "text", "text": "A once-in-a-lifetime shot..." },
    {
      "type": "image",
      "media": [{ "url": "https://64.media.tumblr.com/...jpg", "type": "image/jpeg", "width": 1365, "height": 2048 }]
    }
  ],
  "trail": [],
  "sourceTag": "photography",
  "sourceUrl": "https://www.tumblr.com/tagged/photography",
  "fetchedAt": "2026-07-28T02:30:00.000Z"
}
```

Counts and feed contents change over time.
Do not use example values as guaranteed current values.

### How much does it cost to scrape Tumblr tagged posts?

The Actor uses pay-per-event pricing:

- a **$0.005 start fee** per run;
- a per-saved-post fee with plan discounts;
- the BRONZE plan price is **$0.000035714 per post**.

At the BRONZE price, approximate Actor charges are:

| Saved posts | BRONZE calculation |
| ---: | --- |
| 10 | $0.005 start + 10 × $0.000035714 |
| 25 | $0.005 start + 25 × $0.000035714 |
| 100 | $0.005 start + 100 × $0.000035714 |

Only successfully normalized posts are charged as item events.
Duplicates, rejected rows, and failed requests are not item events.
Actual billing uses the tier for your Apify plan; check the pricing panel for your active tier.

### Monitoring multiple Tumblr tags

For a recurring trend workflow:

1. group closely related tags in one input;
2. choose a limit that covers the current initial feeds;
3. schedule the Actor hourly, daily, or weekly;
4. export `postId`, `sourceTag`, `noteCount`, and `fetchedAt` to your database;
5. upsert on `postId` while retaining snapshot timestamps;
6. compare first appearance and visible engagement over time.

A post can appear under several queried tags.
The Actor saves it once per run and keeps the source from which it was first accepted.
Run tags separately when per-tag duplicate attribution is required.

### Creator discovery workflow

Use `blogName`, `blog.title`, `blog.description`, `blog.avatarUrl`, and `blog.url` to create a candidate creator table.
Join posts by `blogName`, count appearances, and aggregate visible notes.
Then review the public Tumblr pages manually before outreach or editorial decisions.

Do not infer identity, demographics, ownership, or endorsement from a username or tag alone.

### API usage

Replace `YOUR_APIFY_TOKEN` with a token stored securely outside source control.

#### cURL

```bash
curl -X POST \
  "https://api.apify.com/v2/acts/automation-lab~tumblr-tagged-posts-scraper/runs?token=YOUR_APIFY_TOKEN&waitForFinish=120" \
  -H "Content-Type: application/json" \
  -d '{"tags":["photography"],"maxItems":25}'
```

#### JavaScript

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

const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('automation-lab/tumblr-tagged-posts-scraper').call({
  tags: ['photography', 'street photography'],
  maxItems: 25,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);
```

#### Python

```python
import os
from apify_client import ApifyClient

client = ApifyClient(os.environ['APIFY_TOKEN'])
run = client.actor('automation-lab/tumblr-tagged-posts-scraper').call(run_input={
    'tags': ['digital art'],
    'maxItems': 25,
})
items = client.dataset(run['defaultDatasetId']).list_items().items
print(items)
```

For asynchronous systems, start a run without waiting and poll the run status or use Apify webhooks.
The primary results always live in the run's default dataset.

### Use with Apify MCP

Add this Actor to Claude Code:

```bash
claude mcp add --transport http apify \
  "https://mcp.apify.com?tools=automation-lab/tumblr-tagged-posts-scraper"
```

#### Claude Desktop

Add the following server to your Claude Desktop MCP configuration:

```json
{
  "mcpServers": {
    "apify": {
      "url": "https://mcp.apify.com?tools=automation-lab/tumblr-tagged-posts-scraper"
    }
  }
}
```

#### Cursor

Use the same HTTP MCP URL in Cursor's MCP settings and name the server `apify`.

#### VS Code

Add the same server URL to your VS Code MCP configuration, then select the Tumblr Tagged Posts Scraper tool from the Apify server.

Example prompts:

- “Run Tumblr Tagged Posts Scraper for photography and analog photography, limited to 30 posts.”
- “Extract the current digital art tagged feed and summarize the creators and media types.”
- “Save a snapshot of fashion, streetwear, and outfit inspiration tags for my trend dashboard.”

### Integrations and exports

Use Apify's dataset tools to download JSON, CSV, XML, Excel, or HTML.
You can also connect runs to:

- Google Sheets for lightweight review;
- Make or Zapier for alerts and routing;
- webhooks for downstream processing;
- cloud object storage for archives;
- a SQL warehouse for recurring snapshots;
- AI tools for summaries after applying your own safety and quality controls.

Media URLs point to public Tumblr-hosted resources observed in the source data.
The Actor does not download or rehost media files.

### Limits and reliability

- Version 1 reads only the initial anonymous server-rendered tagged feed.
- It does not paginate through historical archives.
- Tumblr usually exposes a small current set per tag, so a high `maxItems` does not guarantee that many rows.
- Results depend on Tumblr's current public ordering and availability.
- Deleted, private, login-only, age-gated, or geographically unavailable content may not appear.
- RSS feeds, blog profiles, arbitrary posts, search pages, and legacy APIs are unsupported.
- Upstream HTTP 429 and temporary 5xx responses receive bounded retries.
- A missing or changed hydration shape is an error, not a successful empty dataset.
- Media and trail arrays are capped to prevent unusually large records.
- Classification fields are source metadata, not an independent safety assessment.

The Actor uses sequential requests and no automatic residential proxy or browser fallback.
This keeps costs predictable but means a broad Tumblr access change may require a future update.

### Troubleshooting

#### “Provide at least one tag or Tumblr tagged-feed URL”

Add at least one non-empty value to `tags` or one supported URL to `startUrls`.
An empty array in both fields is invalid.

#### “Only Tumblr tagged-feed URLs are supported”

Use a URL such as `https://www.tumblr.com/tagged/photography`.
Blog homepages and individual posts are intentionally outside this Actor's contract.

#### The run returned fewer posts than `maxItems`

`maxItems` is a ceiling, not a promise.
The anonymous initial feed may contain fewer posts, and duplicates across tags are saved once.
Add more distinct tags if that fits your research goal.

#### All tagged feeds failed

Inspect the run log for HTTP status or hydration-shape details.
Confirm the same public tagged URL opens anonymously.
If Tumblr changed its page format, report the run ID so the parser can be updated.

#### A count or classification looks unexpected

The Actor preserves public Tumblr fields.
Counts can change after collection, and classifications can be absent or revised by the source.
Validate sensitive decisions manually.

### Responsible use and legality

Collect only public data you are legally permitted to use.
Follow Tumblr's terms, applicable privacy and database laws, copyright requirements, and your organization's policies.
Do not use this Actor to bypass access controls, identify anonymous people, harass creators, build sensitive-person profiles, or republish copyrighted media without permission.

Minimize retained personal data, define a legitimate purpose, respect deletion and opt-out requests where applicable, and secure exported datasets.
The Actor provides a technical extraction tool, not legal advice.

### Related Automation Lab Actors

- [Instagram Hashtag Scraper](https://apify.com/automation-lab/instagram-hashtag-scraper) for public Instagram hashtag research.
- [TikTok Hashtag Scraper](https://apify.com/automation-lab/tiktok-hashtag-scraper) for TikTok tag discovery and trend workflows.

These are separate sources with different access models and output contracts.
Choose the Actor matching the platform your workflow actually needs.

### FAQ

#### Does this Actor require a Tumblr account?

No.
It uses public anonymous tagged-feed pages only.

#### Can it scrape any Tumblr blog?

No.
Arbitrary blog profiles, RSS endpoints, dashboards, and private or login-only content are outside version 1.

#### Does it download images and video?

No.
It returns useful public media URLs and metadata embedded in Tumblr's post content blocks.

#### Does it retrieve every historical post for a tag?

No.
It snapshots the current initial server-rendered feed and does not promise historical pagination.

#### Can I pass both tags and URLs?

Yes.
The Actor normalizes both routes, removes duplicate source URLs, and applies one global result limit.

#### How are duplicate posts handled?

A stable Tumblr post ID is saved once per run.
Duplicates are not charged as item events.

#### Can I schedule it?

Yes.
Use Apify schedules and store each run's `fetchedAt`, `postId`, and engagement counts for comparisons.

#### Is an empty dataset always an error?

A recognized tagged timeline with no current items is a valid empty snapshot.
A missing hydration script or unrecognized tagged timeline fails visibly because it may indicate an upstream format change.

#### What should I include in a support report?

Share the Actor run URL or run ID, the public tag or tagged URL, expected behavior, and the approximate time of the run.
Do not post private tokens or unrelated personal information.

# Actor input Schema

## `tags` (type: `array`):

Tags to scrape without the leading #, for example photography or digital art.

## `startUrls` (type: `array`):

Optional public URLs in the exact form https://www.tumblr.com/tagged/<tag>. Blog profiles and post URLs are not supported.

## `maxItems` (type: `integer`):

Global maximum number of unique posts saved across all supplied tags and URLs.

## Actor input object example

```json
{
  "tags": [
    "photography"
  ],
  "startUrls": [],
  "maxItems": 20
}
```

# Actor output Schema

## `overview` (type: `string`):

Open the default dataset view containing Tumblr posts, creators, content, engagement, classification, and source provenance.

# 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 = {
    "tags": [
        "photography"
    ],
    "startUrls": [],
    "maxItems": 20
};

// Run the Actor and wait for it to finish
const run = await client.actor("automation-lab/tumblr-tagged-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 = {
    "tags": ["photography"],
    "startUrls": [],
    "maxItems": 20,
}

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

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

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

```

## CLI example

```bash
echo '{
  "tags": [
    "photography"
  ],
  "startUrls": [],
  "maxItems": 20
}' |
apify call automation-lab/tumblr-tagged-posts-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=automation-lab/tumblr-tagged-posts-scraper",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/p5ALwbZtRLzSpdjAW/builds/1SH2eXjnTxdC2H8Ot/openapi.json
