How to Retrieve Social Media Posts For All Your Users with an API
Are you looking to retrieve all your social media posts programmatically using an API? This guide explains how to use Ayrshare’s API endpoints to retrieve your posts across multiple social platforms for all your user profiles.
For businesses with multiple social media accounts, having comprehensive social media post analytics is a strategic necessity. The ability to retrieve and analyze posts across all user profiles provides valuable insights that can shape your social media strategy. Whether you’re scaling an agency, managing franchise locations, or growing your ambitious lemonade stand business, mastering multi-account post analytics is an important step to understand your success.
In this guide, we’ll walk through how to use the Ayrshare API to efficiently retrieve posts across all your user profiles, and, at the end, begin to see how to turn this data into actionable insights. You can also check out our docs on How to Get All Posts.
Understanding the API Structure
Before diving into the code, let’s do a quick review of how Ayrshare’s profile hierarchy works:
- Your primary profile (business account) has access to all of your user profiles.
- The /profiles endpoint returns a unique refId for each user profile.
- You’ll need to maintain your own mapping of refIds to profile API keys in a database.
- Each user profile’s Profile Key is required to fetch its posts,
- The flow will work like this:
- Get all profile
refIds
from Ayrshare. - Look up each corresponding
Profile-Key
in your database. - Use these profile keys to fetch posts for each profile at two different endpoints.
- Get all profile
Implementation Guide
While we’ll use Node.js for this tutorial, the core concepts and API call structure remain consistent across all programming languages. Let’s begin by examining the complete code implementation before diving into a detailed, step-by-step breakdown that will help you understand each component’s functionality and purpose.
Full Code
import 'dotenv/config';
class AyrshareClient {
constructor(apiKey) {
this.apiKey = apiKey;
this.baseURL = 'https://app.ayrshare.com/api';
this.defaultHeaders = {
'Authorization': `Bearer ${this.apiKey}`,
'Content-Type': 'application/json'
};
}
async makeRequest(endpoint, { method = 'GET', headers = {}, params = {}, path = {}, ...options } = {}) {
// Replace path parameters in endpoint
let urlEndpoint = endpoint;
for (const [key, value] of Object.entries(path)) {
urlEndpoint = urlEndpoint.replace(`:${key}`, value);
}
let url = `${this.baseURL}${urlEndpoint}`;
// Add query parameters to URL if they exist
const queryParams = new URLSearchParams(params).toString();
if (queryParams) {
url = `${url}?${queryParams}`;
}
const response = await fetch(url, {
method,
headers: {
...this.defaultHeaders,
...headers
},
...options
});
if (!response.ok) {
throw new Error(`API request failed: ${response.status} ${response.statusText}`);
}
return response.json();
}
async getAllUserProfiles() {
try {
const data = await this.makeRequest('/profiles', { method: 'GET' });
return data.profiles;
} catch (error) {
console.error('Error fetching profiles:', error.message);
throw error;
}
}
async getPostsForProfile(profileKey) {
try {
const data = await this.makeRequest('/history', {
method: 'GET',
headers: {
'Profile-Key': profileKey
},
params: {
// Example of how to add query parameters if needed
// lastRecords: 10,
// platforms: ['twitter', 'facebook'].join(',')
}
});
return data.history;
} catch (error) {
console.error(`Error fetching posts for profile: ${profileKey}`, error.message);
throw error;
}
}
async getAllPosts(profileKeyMap) {
const profiles = await this.getAllUserProfiles();
const allPosts = [];
for (const profile of profiles) {
// Look up the profile key using the refId
const profileKey = profileKeyMap[profile.refId];
if (!profileKey) {
console.warn(`No profile key found for refId: ${profile.refId}`);
continue;
}
const posts = await this.getPostsForProfile(profileKey);
allPosts.push({
refId: profile.refId,
posts: posts
});
}
return allPosts;
}
async getPostsForPlatform(platform, profileKey) {
try {
const data = await this.makeRequest('/history/:platform', {
method: 'GET',
headers: {
'Profile-Key': profileKey
},
path: {
platform: platform
}
});
return data.posts;
} catch (error) {
console.error(`Error fetching posts for platform: ${platform}`, error.message);
throw error;
}
}
async getAllPostsForPlatform(platform, profileKeyMap) {
const profiles = await this.getAllUserProfiles();
const allPosts = [];
for (const profile of profiles) {
const profileKey = profileKeyMap[profile.refId];
const posts = await this.getPostsForPlatform(platform, profileKey);
allPosts.push({
refId: profile.refId,
posts: posts
});
}
return allPosts;
}
}
// Usage Example
async function fetchSocialMediaPosts() {
const client = new AyrshareClient(process.env.AYRSHARE_API_KEY);
// This would typically come from your internal database
const profileKeyMap = {
'ref123': 'profile_key_123',
'ref456': 'profile_key_456'
// ... more mappings
};
try {
const allPosts = await client.getAllPosts(profileKeyMap);
console.log('Successfully retrieved posts for profiles:',
allPosts.map(profile => ({
refId: profile.refId,
postCount: profile.posts.length
}))
);
const allPostsForPlatform = await client.getAllPostsForPlatform('bluesky', profileKeyMap);
console.log('Successfully retrieved posts for platform:',
allPostsForPlatform.map(profile => ({
refId: profile.refId,
postCount: profile.posts.length
}))
);
return allPosts;
} catch (error) {
console.error('Failed to fetch posts:', error);
throw error;
}
}
fetchSocialMediaPosts();
Code Breakdown
import 'dotenv/config';
For a secure API implementation we’ll use Node.js’s process.env to access environmental variables. Let’s now explore each of the methods inside of the AyrshareClient class.
constructor(apiKey) {
this.apiKey = apiKey;
this.baseURL = 'https://app.ayrshare.com/api';
this.defaultHeaders = {
'Authorization': `Bearer ${this.apiKey}`,
'Content-Type': 'application/json'
};
}
The constructor initializes authentication credentials that will be used in subsequent API requests to Ayrshare.
async makeRequest(endpoint, { method = 'GET', headers = {}, params = {}, path = {}, ...options } = {}) {
// Replace path parameters in endpoint
let urlEndpoint = endpoint;
for (const [key, value] of Object.entries(path)) {
urlEndpoint = urlEndpoint.replace(`:${key}`, value);
}
let url = `${this.baseURL}${urlEndpoint}`;
// Add query parameters to URL if they exist
const queryParams = new URLSearchParams(params).toString();
if (queryParams) {
url = `${url}?${queryParams}`;
}
const response = await fetch(url, {
method,
headers: {
...this.defaultHeaders,
...headers
},
...options
});
if (!response.ok) {
throw new Error(`API request failed: ${response.status} ${response.statusText}`);
}
return response.json();
}
Our makeRequest
method serves as a wrapper for all Ayrshare API interactions. While it defaults to GET
requests, this implementation supports multiple HTTP methods and includes full support for both path and query parameters. In today’s demo, as all our requests will be GET
requests, we’ll focus specifically on utilizing path parameters.
async getAllUserProfiles() {
try {
const data = await this.makeRequest('/profiles', { method: 'GET' });
return data.profiles;
} catch (error) {
console.error('Error fetching profiles:', error.message);
throw error;
}
}
We begin by creating a method to get all user profiles (/profiles) associated with the primary profile. As the primary profile credentials have already been set in the constructor, this method is quite lightweight. Note that this method will only return the refId associated with each user profile. More on how to get the corresponding user profile key later.
async getPostsForProfile(profileKey) {
try {
const data = await this.makeRequest('/history', {
method: 'GET',
headers: {
'Profile-Key': profileKey
},
params: {
// Example of how to add query parameters if needed
// lastRecords: 10,
// platforms: ['twitter', 'facebook'].join(',')
}
});
return data.history;
} catch (error) {
console.error(`Error fetching posts for profile: ${profileKey}`, error.message);
throw error;
}
}
Next, we have a method that will get all posts associated with a user profile key. We are making this call to this /history endpoint.
async getAllPosts(profileKeyMap) {
const profiles = await this.getAllUserProfiles();
const allPosts = [];
for (const profile of profiles) {
// Look up the profile key using the refId
const profileKey = profileKeyMap[profile.refId];
if (!profileKey) {
console.warn(`No profile key found for refId: ${profile.refId}`);
continue;
}
const posts = await this.getPostsForProfile(profileKey);
allPosts.push({
refId: profile.refId,
posts: posts
});
}
return allPosts;
}
This next method for the AyrshareClient
class ties together the getAllUserProfiles(
) and getPostsForProfile(profileKey)
methods. We input a profileKeyMap
that connects reference IDs (refIds) with their corresponding profile keys from your own internal database. This method returns an array of all posts associated with each user profile’s refId.
async getPostsForPlatform(platform, profileKey) {
try {
const data = await this.makeRequest('/history/:platform', {
method: 'GET',
headers: {
'Profile-Key': profileKey
},
path: {
platform: platform
}
});
return data.posts;
} catch (error) {
console.error(`Error fetching posts for platform: ${platform}`, error.message);
throw error;
}
}
Here we have a method for hitting the /history/:platform endpoint. Given the platform and profile key, it returns posts from that platform (both those created via Ayrshare and those created natively on the platform itself).
async getAllPostsForPlatform(platform, profileKeyMap) {
const profiles = await this.getAllUserProfiles();
const allPosts = [];
for (const profile of profiles) {
const profileKey = profileKeyMap[profile.refId];
if (!profileKey) {
console.warn(`No profile key found for refId: ${profile.refId}`);
continue;
}
const posts = await this.getPostsForPlatform(platform, profileKey);
allPosts.push({
refId: profile.refId,
posts: posts
});
}
return allPosts;
}
And our last method is for getting all posts on a particular platform of user profiles associated with our primary account. This is now the combination of using the getAllUserProfiles
and getPostsForPlatform
methods. It makes use of an internal profileKeyMap once more and returns an array of each refId along with their respective platform-specific posts.
// Usage Example
async function fetchSocialMediaPosts() {
const client = new AyrshareClient(process.env.AYRSHARE_API_KEY);
// This would typically come from your internal database
const profileKeyMap = {
'ref123': 'profile_key_123',
'ref456': 'profile_key_456'
// ... more mappings
};
try {
const allPosts = await client.getAllPosts(profileKeyMap);
console.log('Successfully retrieved posts for profiles:',
allPosts.map(profile => ({
refId: profile.refId,
postCount: profile.posts.length
}))
);
const allPostsForPlatform = await client.getAllPostsForPlatform('bluesky', profileKeyMap);
console.log('Successfully retrieved posts for platform:',
allPostsForPlatform.map(profile => ({
refId: profile.refId,
postCount: profile.posts.length
}))
);
return [allPosts, allPostsForPlatform];
} catch (error) {
console.error('Failed to fetch posts:', error);
throw error;
}
}
fetchSocialMediaPosts();
Lastly, here’s the two usage examples at play. After setting up the AyrshareClient
instance and sourcing the profileKeyMap
from your own internal store, we make the call to getAllPosts
. From there, you can see a mapping where we count the number of posts associated with each refId. We follow up with a call to getAllPostsForPlatform
on bluesky
and profileKeyMap
. You’ll see a mapping once again of each refId along with their corresponding post counts.
Best Practices and Considerations
API Key Security
- Never commit API keys to version control (yeah, public GitHub repos, I’m looking at you).
- Use environment variables.
- Regularly rotate API keys for security. This can be done in the Ayrshare dashboard.
Error Handling
- Implement comprehensive error handling.
- Log errors appropriately.
- Consider implementing retry logic for failed requests.
Rate Limiting
- Be mindful of Ayrshare’s API rate limits.
- Implement appropriate delays between requests.
- Consider using a queue system for large data sets (ex: you have a high number of user profiles).
This implementation provides a solid foundation for retrieving posts across all your user profiles. We kept it modular enough so you can easily build on top and maintain your code. Happy coding!