If you're building a brand monitoring tool, a PR dashboard, or a creator discovery platform, you need to search across multiple social networks simultaneously.
But every platform has a different API, different authentication methods, and different rate limits.
- Twitter requires expensive enterprise tiers.
- Instagram's official API doesn't allow broad keyword searches.
- TikTok's API is notoriously difficult to get approved for.
In this tutorial, I'll show you how to bypass these headaches and build a unified, multi-platform search engine using Node.js and a single API provider.
The Architecture
We're going to build an Express.js API that takes a single search query (e.g., "Nike") and simultaneously searches:
- TikTok (Videos)
- Instagram (Posts)
- YouTube (Videos)
- Reddit (Posts)
We'll use Promise.allSettled() to run these searches in parallel, aggregate the results, and return a unified JSON response.
The Tooling
To avoid integrating 4 different APIs, we'll use SociaVault. It's a unified social data API that provides a single interface for 14+ platforms.
Step 1: Setup the Project
Initialize a new Node.js project:
mkdir social-search-engine
cd social-search-engine
npm init -y
npm install express axios cors dotenv
Create an index.js file and a .env file.
In your .env:
SOCIAVAULT_API_KEY=your_api_key_here
PORT=3000
Step 2: Create the Search Functions
Let's create helper functions for each platform. Notice how similar the API calls are—this is the beauty of using a unified API.
const axios = require('axios');
require('dotenv').config();
const API_KEY = process.env.SOCIAVAULT_API_KEY;
const BASE_URL = 'https://api.sociavault.com/v1';
const headers = {
'Authorization': `Bearer ${API_KEY}`,
'Content-Type': 'application/json'
};
// 1. Search TikTok
async function searchTikTok(query) {
try {
const res = await axios.get(`${BASE_URL}/tiktok/search/videos`, {
headers, params: { keyword: query, limit: 5 }
});
return res.data.data.map(item => ({
platform: 'TikTok',
id: item.id,
text: item.description,
author: item.author.username,
url: item.url,
engagement: item.statistics.play_count
}));
} catch (e) {
console.error('TikTok search failed');
return [];
}
}
// 2. Search Instagram
async function searchInstagram(query) {
try {
// Note: IG search usually relies on hashtags
const res = await axios.get(`${BASE_URL}/instagram/hashtag/posts`, {
headers, params: { hashtag: query.replace('#', ''), limit: 5 }
});
return res.data.data.map(item => ({
platform: 'Instagram',
id: item.id,
text: item.caption,
author: item.owner.username,
url: `https://instagram.com/p/${item.shortcode}`,
engagement: item.likes_count
}));
} catch (e) {
console.error('Instagram search failed');
return [];
}
}
// 3. Search YouTube
async function searchYouTube(query) {
try {
const res = await axios.get(`${BASE_URL}/youtube/search`, {
headers, params: { query: query, limit: 5 }
});
return res.data.data.map(item => ({
platform: 'YouTube',
id: item.id,
text: item.title,
author: item.channel_title,
url: `https://youtube.com/watch?v=${item.id}`,
engagement: item.view_count
}));
} catch (e) {
console.error('YouTube search failed');
return [];
}
}
// 4. Search Reddit
async function searchReddit(query) {
try {
const res = await axios.get(`${BASE_URL}/reddit/search`, {
headers, params: { query: query, limit: 5 }
});
return res.data.data.map(item => ({
platform: 'Reddit',
id: item.id,
text: item.title,
author: item.author,
url: `https://reddit.com${item.permalink}`,
engagement: item.score
}));
} catch (e) {
console.error('Reddit search failed');
return [];
}
}
Step 3: Build the Express Server
Now, let's expose an endpoint that runs all these searches concurrently.
const express = require('express');
const cors = require('cors');
const app = express();
app.use(cors());
app.use(express.json());
app.get('/api/search', async (req, res) => {
const { q } = req.query;
if (!q) {
return res.status(400).json({ error: 'Query parameter "q" is required' });
}
console.log(`Searching across platforms for: "${q}"`);
// Run all searches in parallel
const results = await Promise.allSettled([
searchTikTok(q),
searchInstagram(q),
searchYouTube(q),
searchReddit(q)
]);
// Flatten the results
let aggregatedData = [];
results.forEach(result => {
if (result.status === 'fulfilled' && result.value) {
aggregatedData = [...aggregatedData, ...result.value];
}
});
// Sort by engagement (descending)
aggregatedData.sort((a, b) => (b.engagement || 0) - (a.engagement || 0));
res.json({
query: q,
total_results: aggregatedData.length,
data: aggregatedData
});
});
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
console.log(`Multi-platform search engine running on port ${PORT}`);
});
Step 4: Test It Out
Start your server:
node index.js
Make a request:
curl "http://localhost:3000/api/search?q=cyberpunk"
You'll get a beautifully normalized JSON response containing the top posts from TikTok, Instagram, YouTube, and Reddit, all sorted by engagement!
Why This Approach Wins
-
Speed: By using
Promise.allSettled(), the total request time is only as long as the slowest platform. -
Resilience: If TikTok goes down,
allSettledensures you still get results from Instagram, YouTube, and Reddit. - Simplicity: By using SociaVault, we didn't have to manage 4 different OAuth flows, API keys, or pagination cursors.
If you're building a social listening tool, a PR dashboard, or an influencer discovery platform, this is the exact architecture you need.
Get 1,000 free API credits at SociaVault.com and build your search engine today.
Top comments (0)