Search and discover content through tags, public feeds, and explore blog social connections like likes and followers.
Get posts from across Tumblr that are tagged with specific tags.
/**
* Get posts tagged with the specified tag
* @param tag - The tag on the posts you'd like to retrieve
* @param params - Additional filtering and pagination parameters
* @returns Promise resolving to tagged posts from across Tumblr
*/
taggedPosts(tag: string, params?: TaggedPostsParams): Promise<any>;Usage Examples:
// Get recent posts with a specific tag
const catPosts = await client.taggedPosts('cats');
console.log(`Found ${catPosts.response.length} cat posts`);
// Get tagged posts with additional parameters
const photoPost = await client.taggedPosts('photography', {
before: 1461979830, // Unix timestamp
limit: 20,
filter: 'text'
});
// Discover trending content
const trendingPosts = await client.taggedPosts('tumblr', {
limit: 50
});
trendingPosts.response.forEach(post => {
console.log(`${post.blog_name}: ${post.summary}`);
console.log(`Tags: ${post.tags.join(', ')}`);
console.log(`Notes: ${post.note_count}`);
});Get the posts that a specific blog has liked (if publicly visible).
/**
* Get the likes for a blog
* @param blogIdentifier - Blog name or URL
* @param params - Pagination parameters for blog likes
* @returns Promise resolving to posts liked by the blog
*/
blogLikes(blogIdentifier: string, params?: BlogLikesParams): Promise<any>;Usage Examples:
// Get posts liked by a blog
const blogLikes = await client.blogLikes('staff');
console.log(`Staff blog has liked ${blogLikes.liked_posts.length} posts`);
// Paginate through blog likes
const moreLikes = await client.blogLikes('staff', {
limit: 20,
offset: 20
});
// Get likes before/after specific time
const recentLikes = await client.blogLikes('staff', {
after: 1461979830,
limit: 10
});
// Discover content through curator blogs
const curatorLikes = await client.blogLikes('museumsblog');
curatorLikes.liked_posts.forEach(post => {
console.log(`Curated post from ${post.blog_name}: ${post.summary}`);
});Get the list of blogs following a specific blog (if publicly visible).
/**
* Get the followers for a blog
* @param blogIdentifier - Blog name or URL
* @param params - Pagination parameters for followers list
* @returns Promise resolving to blogs following the specified blog
*/
blogFollowers(blogIdentifier: string, params?: FollowersParams): Promise<any>;Usage Examples:
// Get followers of a blog
const followers = await client.blogFollowers('popular-blog');
console.log(`Found ${followers.users.length} followers`);
followers.users.forEach(follower => {
console.log(`${follower.name}: ${follower.url}`);
if (follower.updated) {
console.log(` Last active: ${new Date(follower.updated * 1000)}`);
}
});
// Paginate through followers
const moreFollowers = await client.blogFollowers('popular-blog', {
limit: 20,
offset: 20
});
// Find potential blogs to follow based on who follows interesting blogs
const photoFollowers = await client.blogFollowers('photography');
const activeFollowers = photoFollowers.users.filter(user => {
const weekAgo = Date.now() / 1000 - (7 * 24 * 60 * 60);
return user.updated > weekAgo;
});
console.log(`${activeFollowers.length} active followers of photography blog`);interface TaggedPostsParams {
/** Return posts before this timestamp */
before?: number;
/** Number of posts to return (1-20) */
limit?: number;
/** Post format filter */
filter?: PostFormatFilter;
}
type PostFormatFilter = 'text' | 'raw';interface BlogLikesParams {
/** Number of results to return (1-20) */
limit?: number;
/** Liked post number to start at */
offset?: number;
/** Return posts liked before this timestamp */
before?: number;
/** Return posts liked after this timestamp */
after?: number;
}interface FollowersParams {
/** Number of results to return (1-20) */
limit?: number;
/** Follower number to start at */
offset?: number;
}{
response: [
{
id: "12345",
type: "photo",
blog_name: "photography-blog",
timestamp: 1461979830,
date: "2016-04-29 22:23:50 GMT",
tags: ["photography", "nature", "landscape"],
summary: "Beautiful sunset over the mountains",
note_count: 156,
photos: [
{
caption: "",
original_size: {
url: "https://example.com/photo.jpg",
width: 1280,
height: 720
}
}
]
}
// ... more posts
]
}{
liked_posts: [
{
id: "67890",
type: "text",
blog_name: "writer-blog",
timestamp: 1461979830,
liked_timestamp: 1461980000,
title: "On Writing",
body: "Some thoughts about the creative process...",
tags: ["writing", "creativity", "inspiration"],
note_count: 89
}
// ... more liked posts
],
liked_count: 1234
}{
users: [
{
name: "follower-blog",
url: "https://follower-blog.tumblr.com/",
updated: 1461979830
},
{
name: "another-follower",
url: "https://another-follower.tumblr.com/",
updated: 1461979700
}
// ... more followers
],
total_users: 5678
}async function exploreTag(tag, depth = 3) {
console.log(`Exploring tag: ${tag}`);
const posts = await client.taggedPosts(tag, { limit: 20 });
// Analyze posting patterns
const blogFrequency = {};
const relatedTags = new Set();
posts.response.forEach(post => {
// Track which blogs post about this tag
blogFrequency[post.blog_name] = (blogFrequency[post.blog_name] || 0) + 1;
// Collect related tags
post.tags.forEach(t => {
if (t !== tag) relatedTags.add(t);
});
});
// Find most active blogs for this tag
const topBlogs = Object.entries(blogFrequency)
.sort(([,a], [,b]) => b - a)
.slice(0, 5);
console.log('Top blogs posting about', tag, ':', topBlogs);
console.log('Related tags:', Array.from(relatedTags).slice(0, 10));
return {
posts: posts.response,
topBlogs,
relatedTags: Array.from(relatedTags)
};
}async function findSimilarBlogs(targetBlog, maxSuggestions = 10) {
try {
// Get what the target blog likes
const likes = await client.blogLikes(targetBlog, { limit: 20 });
// Find blogs that appear frequently in their likes
const likedBlogs = {};
likes.liked_posts.forEach(post => {
likedBlogs[post.blog_name] = (likedBlogs[post.blog_name] || 0) + 1;
});
// Get followers of the target blog
const followers = await client.blogFollowers(targetBlog, { limit: 20 });
const suggestions = Object.entries(likedBlogs)
.sort(([,a], [,b]) => b - a)
.slice(0, maxSuggestions)
.map(([blogName, count]) => ({
name: blogName,
reason: `Liked ${count} times by ${targetBlog}`,
url: `https://${blogName}.tumblr.com/`
}));
return suggestions;
} catch (error) {
console.error(`Cannot analyze ${targetBlog}:`, error.message);
return [];
}
}
// Usage
const similar = await findSimilarBlogs('photography');
similar.forEach(blog => {
console.log(`${blog.name}: ${blog.reason}`);
});async function findTrendingContent(tags = ['tumblr', 'viral', 'trending']) {
const trendingPosts = [];
for (const tag of tags) {
const posts = await client.taggedPosts(tag, { limit: 10 });
// Filter for posts with high engagement
const highEngagement = posts.response.filter(post =>
post.note_count > 100
);
trendingPosts.push(...highEngagement);
}
// Sort by engagement and recency
trendingPosts.sort((a, b) => {
const scoreA = a.note_count * (a.timestamp / 1000000);
const scoreB = b.note_count * (b.timestamp / 1000000);
return scoreB - scoreA;
});
return trendingPosts.slice(0, 20);
}
// Usage
const trending = await findTrendingContent();
trending.forEach(post => {
console.log(`${post.blog_name}: ${post.summary} (${post.note_count} notes)`);
});async function buildCustomFeed(interests = []) {
const feedPosts = [];
// Get posts for each interest
for (const interest of interests) {
try {
const posts = await client.taggedPosts(interest, { limit: 5 });
// Add interest category to posts
posts.response.forEach(post => {
post.category = interest;
});
feedPosts.push(...posts.response);
// Add delay to avoid rate limiting
await new Promise(resolve => setTimeout(resolve, 500));
} catch (error) {
console.error(`Failed to get posts for ${interest}:`, error.message);
}
}
// Sort by timestamp (most recent first)
feedPosts.sort((a, b) => b.timestamp - a.timestamp);
return feedPosts;
}
// Usage
const customFeed = await buildCustomFeed([
'photography', 'art', 'technology', 'cats'
]);
customFeed.forEach(post => {
console.log(`[${post.category}] ${post.blog_name}: ${post.summary}`);
});// Tagged posts are always public
const publicPosts = await client.taggedPosts('photography');
// Blog likes may be private
try {
const likes = await client.blogLikes('private-blog');
} catch (error) {
if (error.message.includes('404')) {
console.log('Blog likes are private or blog does not exist');
}
}
// Blog followers may be private
try {
const followers = await client.blogFollowers('private-blog');
} catch (error) {
if (error.message.includes('403')) {
console.log('Followers list is private');
}
}async function respectfulContentDiscovery(tags, delayMs = 1000) {
const results = [];
for (const tag of tags) {
try {
console.log(`Discovering content for: ${tag}`);
const posts = await client.taggedPosts(tag, { limit: 10 });
results.push({ tag, posts: posts.response });
// Wait between requests
await new Promise(resolve => setTimeout(resolve, delayMs));
} catch (error) {
if (error.message.includes('429')) {
console.log('Rate limit hit, waiting longer...');
await new Promise(resolve => setTimeout(resolve, 30000));
} else {
console.error(`Error discovering ${tag}:`, error.message);
}
}
}
return results;
}taggedPosts() - Public tagged content across TumblrblogLikes() - Enhanced rate limits for blog likesblogFollowers() - Enhanced rate limits for followersUnlike social interactions, content discovery methods work without user authentication, making them ideal for public content exploration and research.