Travel & Hotel Social Media Analytics: Review & Mention Monitoring
Social media has replaced travel brochures. Travelers scroll TikTok for destination inspiration, check Instagram for hotel aesthetics, and read Reddit for honest reviews. A single viral TikTok of a hotel room can generate thousands of bookings — or a single negative post can cancel them.
If you're a hotel, resort, travel agency, or tourism board, monitoring your social presence isn't optional. Here's how to do it with data.
Monitor Your Hotel/Brand Mentions
Track what people are saying about your property across platforms:
const API_KEY = process.env.SOCIAVAULT_API_KEY;
const BASE = 'https://api.sociavault.com/v1/scrape';
const headers = { 'X-API-Key': API_KEY };
async function monitorHotelMentions(hotelName) {
const mentions = { twitter: [], threads: [], reddit: [] };
// Twitter mentions
const twRes = await fetch(
`${BASE}/twitter/search?query=${encodeURIComponent(hotelName)}`,
{ headers }
);
mentions.twitter = (await twRes.json()).data || [];
await new Promise(r => setTimeout(r, 1000));
// Threads mentions
const thRes = await fetch(
`${BASE}/threads/search?query=${encodeURIComponent(hotelName)}`,
{ headers }
);
mentions.threads = (await thRes.json()).data || [];
await new Promise(r => setTimeout(r, 1000));
// Reddit mentions
const rdRes = await fetch(
`${BASE}/reddit/search?query=${encodeURIComponent(hotelName)}`,
{ headers }
);
mentions.reddit = (await rdRes.json()).data || [];
// Sentiment analysis
const positiveWords = ['amazing', 'beautiful', 'incredible', 'loved', 'perfect', 'stunning', 'recommend', 'best hotel'];
const negativeWords = ['terrible', 'dirty', 'rude', 'overpriced', 'disappointing', 'worst', 'never again', 'avoid'];
const allTexts = [];
mentions.twitter.forEach(t => allTexts.push(t.legacy?.full_text || t.full_text || ''));
mentions.threads.forEach(t => allTexts.push(t.caption?.text || ''));
mentions.reddit.forEach(r => allTexts.push((r.title || '') + ' ' + (r.selftext || '')));
let positive = 0, negative = 0;
for (const text of allTexts) {
const lower = text.toLowerCase();
if (positiveWords.some(w => lower.includes(w))) positive++;
if (negativeWords.some(w => lower.includes(w))) negative++;
}
const total = allTexts.length;
console.log(`\nMention Report: "${hotelName}"`);
console.log(` Twitter: ${mentions.twitter.length} mentions`);
console.log(` Threads: ${mentions.threads.length} mentions`);
console.log(` Reddit: ${mentions.reddit.length} mentions`);
console.log(` Total: ${total}`);
console.log(`\n Sentiment: ${positive} positive, ${negative} negative, ${total - positive - negative} neutral`);
return { hotelName, mentions, sentiment: { positive, negative, neutral: total - positive - negative } };
}
monitorHotelMentions('Four Seasons');
Track Competitor Hotels
Compare your social presence against competitor properties:
async function compareHotels(hotels) {
const results = [];
for (const hotel of hotels) {
// Instagram presence
const igRes = await fetch(
`${BASE}/instagram/profile?handle=${encodeURIComponent(hotel.instagram)}`,
{ headers }
);
const ig = (await igRes.json()).data;
// Recent posts
const postsRes = await fetch(
`${BASE}/instagram/posts?handle=${encodeURIComponent(hotel.instagram)}`,
{ headers }
);
const posts = (await postsRes.json()).data || [];
const avgLikes = posts.reduce((sum, p) => sum + (p.like_count || 0), 0) / Math.max(posts.length, 1);
results.push({
name: hotel.name,
handle: hotel.instagram,
followers: ig?.follower_count || 0,
posts: ig?.media_count || 0,
avgLikes: Math.round(avgLikes),
verified: ig?.is_verified || false,
engRate: ((avgLikes / Math.max(ig?.follower_count, 1)) * 100).toFixed(2)
});
await new Promise(r => setTimeout(r, 1500));
}
results.sort((a, b) => b.followers - a.followers);
console.log('\nHotel Social Media Comparison:');
console.table(results.map(r => ({
Hotel: r.name,
Followers: r.followers.toLocaleString(),
'Avg Likes': r.avgLikes.toLocaleString(),
'ER %': r.engRate,
Verified: r.verified ? '✓' : ''
})));
return results;
}
compareHotels([
{ name: 'Four Seasons', instagram: 'fourseasons' },
{ name: 'Marriott', instagram: 'marriotthotels' },
{ name: 'Ritz-Carlton', instagram: 'ritzcarlton' },
{ name: 'Hilton', instagram: 'hilton' },
]);
Discover Destination Trends
Track which destinations are trending on TikTok — essential for tourism boards and travel agencies:
async function trackDestinationTrends(destinations) {
const trends = [];
for (const destination of destinations) {
const res = await fetch(
`${BASE}/tiktok/search/videos?query=${encodeURIComponent(destination + ' travel')}`,
{ headers }
);
const videos = (await res.json()).data || [];
const totalViews = videos.reduce((sum, v) => sum + (v.stats?.playCount || 0), 0);
const totalLikes = videos.reduce((sum, v) => sum + (v.stats?.diggCount || 0), 0);
trends.push({
destination,
videoCount: videos.length,
totalViews,
totalLikes,
avgViews: Math.round(totalViews / Math.max(videos.length, 1))
});
await new Promise(r => setTimeout(r, 1000));
}
trends.sort((a, b) => b.totalViews - a.totalViews);
console.log('\nDestination Trend Report:');
console.table(trends.map(t => ({
Destination: t.destination,
Videos: t.videoCount,
'Total Views': t.totalViews.toLocaleString(),
'Total Likes': t.totalLikes.toLocaleString()
})));
return trends;
}
trackDestinationTrends([
'Bali', 'Tulum', 'Santorini', 'Tokyo', 'Dubai',
'Maldives', 'Portugal', 'Croatia', 'Iceland', 'Thailand'
]);
Find Travel Influencers
Discover travel creators for partnered content and property reviews:
async function findTravelInfluencers(destination) {
const searchTerms = [
`${destination} travel vlog`,
`${destination} hotel review`,
`best ${destination} restaurant`
];
const creators = [];
const seen = new Set();
for (const term of searchTerms) {
const res = await fetch(
`${BASE}/tiktok/search/users?query=${encodeURIComponent(term)}`,
{ headers }
);
const users = (await res.json()).data || [];
for (const user of users.slice(0, 5)) {
const handle = user.uniqueId || user.unique_id;
if (seen.has(handle)) continue;
seen.add(handle);
const profileRes = await fetch(
`${BASE}/tiktok/profile?handle=${encodeURIComponent(handle)}`,
{ headers }
);
const profile = (await profileRes.json()).data;
if (!profile || !profile.stats?.followerCount) continue;
creators.push({
handle,
name: profile.user?.nickname,
followers: profile.stats.followerCount,
likes: profile.stats.heartCount,
videos: profile.stats.videoCount,
bio: profile.user?.signature || ''
});
await new Promise(r => setTimeout(r, 800));
}
}
creators.sort((a, b) => b.followers - a.followers);
console.log(`\nTravel Influencers — ${destination}:`);
creators.forEach(c => {
const likesRatio = (c.likes / Math.max(c.followers, 1)).toFixed(1);
console.log(` @${c.handle} — ${c.followers.toLocaleString()} followers (${likesRatio}x engagement)`);
});
return creators;
}
findTravelInfluencers('Bali');
Travel Influencer Collaboration Tiers
| Tier | Followers | Best For | Typical Collaboration |
|---|---|---|---|
| Nano (1K–10K) | Budget properties, local tours | Comped stay + social posts | |
| Micro (10K–50K) | Boutique hotels, experiences | Comped stay + $200-500 | |
| Mid (50K–250K) | Mid-range hotels, destinations | Comped stay + $1,000-3,000 | |
| Macro (250K+) | Luxury resorts, tourism boards | $3,000-15,000 + trip package |
UGC Discovery for Hotels
Find user-generated content mentioning your property:
import os
import requests
import time
API_KEY = os.environ["SOCIAVAULT_API_KEY"]
BASE = "https://api.sociavault.com/v1/scrape"
HEADERS = {"X-API-Key": API_KEY}
def find_hotel_ugc(hotel_hashtag, hotel_name):
"""Find UGC posts about a hotel on Instagram"""
# Search hashtag
r = requests.get(
f"{BASE}/instagram/hashtag",
headers=HEADERS,
params={"hashtag": hotel_hashtag}
)
posts = r.json().get("data", [])
print(f"\nUGC Discovery: #{hotel_hashtag}")
print(f" Posts found: {len(posts)}")
if not posts:
return []
# Analyze UGC quality
high_quality = []
for post in posts:
likes = post.get("like_count", 0)
comments = post.get("comment_count", 0)
owner = post.get("owner", {}).get("username") or post.get("user", {}).get("username", "")
caption = post.get("caption", {})
caption_text = caption.get("text", "") if isinstance(caption, dict) else str(caption)
# High-quality UGC: good engagement, not from your own account
if likes > 50:
high_quality.append({
"username": owner,
"likes": likes,
"comments": comments,
"caption_preview": caption_text[:100],
})
high_quality.sort(key=lambda x: x["likes"], reverse=True)
print(f" High-quality UGC posts: {len(high_quality)}")
for post in high_quality[:5]:
print(f" @{post['username']} — {post['likes']} likes, {post['comments']} comments")
print(f" \"{post['caption_preview']}\"")
return high_quality
find_hotel_ugc("fourseasons", "Four Seasons")
Review Monitoring Pipeline
Set up automated monitoring that catches negative reviews early:
async function reviewMonitorPipeline(properties) {
const results = [];
for (const property of properties) {
const entry = { name: property.name, alerts: [] };
// Search Twitter for complaints
const tweetsRes = await fetch(
`${BASE}/twitter/search?query=${encodeURIComponent(property.name + ' hotel')}`,
{ headers }
);
const tweets = (await tweetsRes.json()).data || [];
const complaintKeywords = [
'terrible', 'worst', 'dirty', 'rude', 'overpriced', 'cockroach',
'bed bugs', 'mold', 'never again', 'disgusting', 'complaint'
];
for (const tweet of tweets) {
const text = (tweet.legacy?.full_text || tweet.full_text || '').toLowerCase();
if (complaintKeywords.some(kw => text.includes(kw))) {
entry.alerts.push({
platform: 'twitter',
text: text.substring(0, 200),
author: tweet.core?.screen_name || tweet.legacy?.screen_name || 'unknown',
likes: tweet.legacy?.favorite_count || 0
});
}
}
// Search Reddit
const redditRes = await fetch(
`${BASE}/reddit/search?query=${encodeURIComponent(property.name + ' hotel review')}`,
{ headers }
);
const redditPosts = (await redditRes.json()).data || [];
for (const post of redditPosts) {
const text = ((post.title || '') + ' ' + (post.selftext || '')).toLowerCase();
if (complaintKeywords.some(kw => text.includes(kw))) {
entry.alerts.push({
platform: 'reddit',
text: post.title?.substring(0, 200),
subreddit: post.subreddit,
score: post.score || 0
});
}
}
results.push(entry);
await new Promise(r => setTimeout(r, 1500));
}
// Report
for (const entry of results) {
if (entry.alerts.length > 0) {
console.log(`\n⚠ ${entry.name} — ${entry.alerts.length} negative mentions:`);
entry.alerts.forEach(a => {
if (a.platform === 'twitter') {
console.log(` [Twitter] @${a.author}: "${a.text}"`);
} else {
console.log(` [Reddit] r/${a.subreddit}: "${a.text}"`);
}
});
} else {
console.log(`\n✅ ${entry.name} — No negative mentions detected`);
}
}
return results;
}
reviewMonitorPipeline([
{ name: 'Marriott Waikiki' },
{ name: 'Hilton Times Square' },
]);
Seasonal Content Analysis
Know what travel content performs best in each season:
| Season | Top Content Types | Best Platform |
|---|---|---|
| Winter | Ski resorts, tropical escapes, holiday travel | TikTok, Instagram |
| Spring | Cherry blossoms, Europe trip planning, road trips | Pinterest, Instagram |
| Summer | Beach, family travel, adventure activities | TikTok, YouTube |
| Fall | Foliage trips, wine country, off-season deals | Instagram, Pinterest |
Track seasonal keywords quarterly to stay ahead of booking trends.
Key Metrics for Travel & Hospitality
| Metric | Why It Matters | How to Track |
|---|---|---|
| Brand mention volume | Overall awareness | Keyword search across platforms |
| Sentiment ratio | Guest satisfaction signal | Sentiment analysis on mentions |
| UGC volume | Organic advocacy | Hashtag monitoring |
| Competitor follower growth | Market share | Weekly profile tracking |
| Influencer reach | Campaign ROI | Profile data for tagged creators |
| Review response time | Reputation management | Monitor and alert |
Get Started
Sign up free — start monitoring your hotel and travel brand's social presence today.
Related Reading
Found this helpful?
Share it with others who might benefit
Ready to Try SociaVault?
Start extracting social media data with our powerful API. No credit card required.