TL;DR
Die Hootsuite API ist ab 2024 nicht mehr öffentlich verfügbar. Für Social-Media-Management-Workflows empfehlen sich jetzt native Plattform-APIs oder spezialisierte Drittanbieter (Buffer, Sprout Social usw.). In diesem Guide findest du praxisorientierte Ansätze für Authentifizierung, Beitragsplanung, Analyse und Teammanagement mit Multi-Plattform-Support.
Hinweis: Hootsuite hat seine öffentliche API ab 2024 eingestellt. Im Folgenden findest du Alternativen wie native Plattform-APIs, Partnerintegrationen und Drittanbieter-APIs mit ähnlichem Funktionsumfang.
Einleitung
Hootsuite verwaltet weltweit über 30 Millionen Social-Media-Konten. Für Entwickler, die Automatisierung im Marketing & Social Media bauen, ist die Anbindung an Social-Media-Plattformen entscheidend.
Die Realität: Social-Media-Manager verlieren wöchentlich 25-35 Stunden durch manuelle Prozesse. Eine API-basierte Integration automatisiert Inhaltsverteilung, Engagement-Tracking und Performance-Reporting.
Hootsuite API Status und Alternativen
Aktuelle API-Situation
Ab 2024 ist die öffentliche Hootsuite API nicht mehr verfügbar. Folgende Alternativen sind relevant:
| Ansatz | Beschreibung | Am besten geeignet für |
|---|---|---|
| Native Plattform-APIs | Direkte Integration mit Facebook, Twitter, LinkedIn etc. | Volle Kontrolle, Custom-Lösungen |
| Audiense | Zielgruppenanalyse (Hootsuite-eigen) | Zielgruppenanalyse |
| HeyOrca | Social Media Scheduling API | Inhaltskalender |
| Buffer API | Social Media Management | Kleine Teams |
| Sprout Social API | Enterprise Social Management | Große Organisationen |
| Agorapulse API | Social Media CRM | Community-Management |
Empfohlener Ansatz: Native Plattform-APIs
Direkte API-Anbindung an Social Networks ist flexibel und zukunftssicher:
| Plattform | API-Name | Hauptfunktionen |
|---|---|---|
| Facebook/Instagram | Graph API | Beiträge, Insights, Kommentare |
| Twitter/X | API v2 | Tweets, Analysen, Streams |
| Marketing API | Beiträge, Unternehmensseiten, Anzeigen | |
| API v5 | Pins, Boards, Analysen | |
| TikTok | Display API | Videos, User-Infos |
| YouTube | Data API | Videos, Playlists, Analysen |
Erste Schritte: Multi-Plattform-Authentifizierung
Schritt 1: Entwickler-Apps registrieren
Lege für jede Plattform eine Entwickler-App an und halte die Zugangsdaten sicher:
// Zugangsdaten sicher speichern
const SOCIAL_CREDENTIALS = {
facebook: {
appId: process.env.FB_APP_ID,
appSecret: process.env.FB_APP_SECRET,
redirectUri: process.env.FB_REDIRECT_URI
},
twitter: {
apiKey: process.env.TWITTER_API_KEY,
apiSecret: process.env.TWITTER_API_SECRET,
redirectUri: process.env.TWITTER_REDIRECT_URI
},
linkedin: {
clientId: process.env.LINKEDIN_CLIENT_ID,
clientSecret: process.env.LINKEDIN_CLIENT_SECRET,
redirectUri: process.env.LINKEDIN_REDIRECT_URI
},
instagram: {
appId: process.env.FB_APP_ID, // Verwendet Facebook Login
appSecret: process.env.FB_APP_SECRET
}
};
Schritt 2: OAuth 2.0-Flow implementieren
Setze einen flexiblen OAuth-Handler für mehrere Plattformen um:
const getAuthUrl = (platform, state) => {
const configs = {
facebook: {
url: 'https://www.facebook.com/v18.0/dialog/oauth',
params: {
client_id: SOCIAL_CREDENTIALS.facebook.appId,
redirect_uri: SOCIAL_CREDENTIALS.facebook.redirectUri,
scope: 'pages_manage_posts,pages_read_engagement,instagram_basic,instagram_content_publish',
state
}
},
twitter: {
url: 'https://twitter.com/i/oauth2/authorize',
params: {
client_id: SOCIAL_CREDENTIALS.twitter.apiKey,
redirect_uri: SOCIAL_CREDENTIALS.twitter.redirectUri,
scope: 'tweet.read tweet.write users.read offline.access',
state,
response_type: 'code'
}
},
linkedin: {
url: 'https://www.linkedin.com/oauth/v2/authorization',
params: {
client_id: SOCIAL_CREDENTIALS.linkedin.clientId,
redirect_uri: SOCIAL_CREDENTIALS.linkedin.redirectUri,
scope: 'w_member_social r_basicprofile',
state,
response_type: 'code'
}
}
};
const config = configs[platform];
const params = new URLSearchParams(config.params);
return `${config.url}?${params.toString()}`;
};
// OAuth-Callback verarbeiten
const handleOAuthCallback = async (platform, code) => {
const tokenEndpoints = {
facebook: 'https://graph.facebook.com/v18.0/oauth/access_token',
twitter: 'https://api.twitter.com/2/oauth2/token',
linkedin: 'https://www.linkedin.com/oauth/v2/accessToken'
};
const response = await fetch(tokenEndpoints[platform], {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
body: new URLSearchParams({
client_id: SOCIAL_CREDENTIALS[platform].apiKey || SOCIAL_CREDENTIALS[platform].appId || SOCIAL_CREDENTIALS[platform].clientId,
client_secret: SOCIAL_CREDENTIALS[platform].appSecret || SOCIAL_CREDENTIALS[platform].apiSecret,
redirect_uri: SOCIAL_CREDENTIALS[platform].redirectUri,
code,
grant_type: 'authorization_code'
})
});
return response.json();
};
Schritt 3: Tokens sicher speichern
Speichere Tokens verschlüsselt und mit Metadaten:
// Datenbankschema für soziale Tokens
const SocialToken = {
userId: 'user_123',
platform: 'facebook',
accessToken: 'encrypted_token_here',
refreshToken: 'encrypted_refresh_token',
tokenExpiry: Date.now() + 5183999, // 60 Tage
scopes: ['pages_manage_posts', 'pages_read_engagement'],
pageId: 'page_456', // Für Facebook/Instagram
pageName: 'Meine Unternehmensseite'
};
Beitragsplanung und -veröffentlichung
Einen Multi-Plattform-Beitrag erstellen
Stelle sicher, dass dein Posting-Service auf allen gewünschten Plattformen parallel posten kann:
const createSocialPost = async (postData) => {
const results = {};
// Facebook Seitenbeitrag
if (postData.platforms.includes('facebook')) {
results.facebook = await postToFacebook({
pageId: postData.facebookPageId,
message: postData.message,
link: postData.link,
photo: postData.photo
});
}
// Twitter Beitrag
if (postData.platforms.includes('twitter')) {
results.twitter = await postToTwitter({
text: postData.message,
media: postData.photo
});
}
// LinkedIn Beitrag
if (postData.platforms.includes('linkedin')) {
results.linkedin = await postToLinkedIn({
authorUrn: postData.linkedinAuthorUrn,
text: postData.message,
contentUrl: postData.link
});
}
// Instagram Beitrag
if (postData.platforms.includes('instagram')) {
results.instagram = await postToInstagram({
igAccountId: postData.igAccountId,
imageUrl: postData.photo,
caption: postData.message
});
}
return results;
};
Beispielimplementierungen für Plattformen:
// Facebook-Posting
const postToFacebook = async (postData) => {
const token = await getFacebookPageToken(postData.pageId);
const params = new URLSearchParams({
message: postData.message,
access_token: token
});
if (postData.link) {
params.append('link', postData.link);
}
if (postData.photo) {
params.append('photo', postData.photo);
}
const response = await fetch(
`https://graph.facebook.com/v18.0/${postData.pageId}/feed?${params.toString()}`,
{ method: 'POST' }
);
return response.json();
};
// Twitter-Posting
const postToTwitter = async (postData) => {
const token = await getTwitterToken();
let mediaIds = [];
if (postData.media) {
// Medien zuerst hochladen
const mediaUpload = await uploadTwitterMedia(postData.media, token);
mediaIds = [mediaUpload.media_id_string];
}
const response = await fetch('https://api.twitter.com/2/tweets', {
method: 'POST',
headers: {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
text: postData.text,
media: mediaIds.length > 0 ? { media_ids: mediaIds } : undefined
})
});
return response.json();
};
// LinkedIn-Posting
const postToLinkedIn = async (postData) => {
const token = await getLinkedInToken();
const post = {
author: postData.authorUrn,
lifecycleState: 'PUBLISHED',
specificContent: {
'com.linkedin.ugc.ShareContent': {
shareCommentary: {
text: postData.text
},
shareMediaCategory: postData.contentUrl ? 'ARTICLE' : 'NONE',
media: postData.contentUrl ? [{
status: 'READY',
media: postData.contentUrn,
description: { text: postData.text }
}] : []
}
},
visibility: {
'com.linkedin.ugc.MemberNetworkVisibility': 'PUBLIC'
}
};
const response = await fetch('https://api.linkedin.com/v2/ugcPosts', {
method: 'POST',
headers: {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json',
'X-Restli-Protocol-Version': '2.0.0'
},
body: JSON.stringify(post)
});
return response.json();
};
// Instagram-Posting
const postToInstagram = async (postData) => {
const token = await getInstagramToken();
// Schritt 1: Mediencontainer erstellen
const containerResponse = await fetch(
`https://graph.facebook.com/v18.0/${postData.igAccountId}/media`,
{
method: 'POST',
headers: { 'Authorization': `Bearer ${token}` },
body: JSON.stringify({
image_url: postData.imageUrl,
caption: postData.caption
})
}
);
const container = await containerResponse.json();
// Schritt 2: Veröffentlichen
const publishResponse = await fetch(
`https://graph.facebook.com/v18.0/${postData.igAccountId}/media_publish`,
{
method: 'POST',
headers: { 'Authorization': `Bearer ${token}` },
body: JSON.stringify({ creation_id: container.id })
}
);
return publishResponse.json();
};
Beiträge planen
Nutze eine Job-Warteschlange (z.B. Bull, Agenda), um Beiträge zeitgesteuert zu veröffentlichen:
const schedulePost = async (postData, scheduledTime) => {
// In der Datenbank zur späteren Ausführung speichern
const scheduledPost = await db.scheduledPosts.create({
message: postData.message,
platforms: postData.platforms,
scheduledTime: scheduledTime,
status: 'pending',
media: postData.media,
link: postData.link
});
// Job-Warteschlange einrichten
await jobQueue.add('publish-social-post', {
postId: scheduledPost.id
}, {
delay: scheduledTime - Date.now()
});
return scheduledPost;
};
// Job-Prozessor
jobQueue.process('publish-social-post', async (job) => {
const post = await db.scheduledPosts.findById(job.data.postId);
try {
const result = await createSocialPost(post);
await db.scheduledPosts.update(post.id, {
status: 'published',
publishedAt: new Date(),
results: result
});
return result;
} catch (error) {
await db.scheduledPosts.update(post.id, {
status: 'failed',
error: error.message
});
throw error;
}
});
Analysen und Berichterstattung
Abrufen von plattformübergreifenden Analysen
Sammle und aggregiere Metriken aller relevanten Plattformen:
const getSocialAnalytics = async (accountId, dateRange) => {
const analytics = {
facebook: await getFacebookAnalytics(accountId.facebook, dateRange),
twitter: await getTwitterAnalytics(accountId.twitter, dateRange),
linkedin: await getLinkedInAnalytics(accountId.linkedin, dateRange),
instagram: await getInstagramAnalytics(accountId.instagram, dateRange)
};
// Metriken aggregieren
const totals = {
impressions: sum(analytics, 'impressions'),
engagement: sum(analytics, 'engagement'),
clicks: sum(analytics, 'clicks'),
shares: sum(analytics, 'shares'),
comments: sum(analytics, 'comments'),
newFollowers: sum(analytics, 'newFollowers')
};
return { analytics, totals };
};
Plattformspezifische Beispiel-Implementierungen:
// Facebook Insights
const getFacebookAnalytics = async (pageId, dateRange) => {
const token = await getFacebookPageToken(pageId);
const metrics = [
'page_impressions_unique',
'page_engaged_users',
'page_post_engagements',
'page_clicks',
'page_fan_adds'
];
const params = new URLSearchParams({
metric: metrics.join(','),
since: dateRange.from,
until: dateRange.until,
access_token: token
});
const response = await fetch(
`https://graph.facebook.com/v18.0/${pageId}/insights?${params.toString()}`
);
return response.json();
};
// Twitter-Analysen
const getTwitterAnalytics = async (userId, dateRange) => {
const token = await getTwitterToken();
const response = await fetch(
`https://api.twitter.com/2/users/${userId}/metrics/private`,
{
headers: { 'Authorization': `Bearer ${token}` }
}
);
return response.json();
};
// LinkedIn-Analysen
const getLinkedInAnalytics = async (organizationId, dateRange) => {
const token = await getLinkedInToken();
const response = await fetch(
`https://api.linkedin.com/v2/organizationalEntityFollowerStatistics?q=organizationalEntity&organizationalEntity=${organizationId}`,
{
headers: { 'Authorization': `Bearer ${token}` }
}
);
return response.json();
};
// Instagram Insights
const getInstagramAnalytics = async (igAccountId, dateRange) => {
const token = await getInstagramToken();
const metrics = [
'impressions',
'reach',
'engagement',
'profile_views',
'follower_count'
];
const params = new URLSearchParams({
metric: metrics.join(','),
period: 'day',
since: dateRange.from,
until: dateRange.until
});
const response = await fetch(
`https://graph.facebook.com/v18.0/${igAccountId}/insights?${params.toString()}`,
{
headers: { 'Authorization': `Bearer ${token}` }
}
);
return response.json();
};
function sum(analytics, metric) {
return Object.values(analytics).reduce((total, platform) => {
return total + (platform.data?.[metric] || 0);
}, 0);
}
Teammanagement
Rollenbasierte Zugriffskontrolle
Definiere Rollen und Berechtigungen für dein Teammanagement:
const TEAM_ROLES = {
ADMIN: 'admin',
MANAGER: 'manager',
CONTRIBUTOR: 'contributor',
VIEWER: 'viewer'
};
const ROLE_PERMISSIONS = {
[TEAM_ROLES.ADMIN]: ['create', 'read', 'update', 'delete', 'manage_team', 'billing'],
[TEAM_ROLES.MANAGER]: ['create', 'read', 'update', 'approve_posts'],
[TEAM_ROLES.CONTRIBUTOR]: ['create', 'read'],
[TEAM_ROLES.VIEWER]: ['read']
};
const checkPermission = (userRole, requiredPermission) => {
const permissions = ROLE_PERMISSIONS[userRole] || [];
return permissions.includes(requiredPermission);
};
Ratenbegrenzung
Plattform-Ratenbegrenzungen
| Plattform | Limit | Fenster |
|---|---|---|
| Facebook Graph | 200 Anrufe | Pro Stunde pro Benutzer |
| Twitter API v2 | 300 Tweets | Pro 15 Min. |
| 100-500 Anrufe | Pro Tag | |
| 200 Anrufe | Pro Stunde |
Implementierung der Ratenbegrenzungsbehandlung
Nutze einen eigenen Rate-Limiter für API-Requests:
class SocialMediaRateLimiter {
constructor() {
this.limits = {
facebook: { limit: 200, window: 3600000 },
twitter: { limit: 300, window: 900000 },
linkedin: { limit: 500, window: 86400000 },
instagram: { limit: 200, window: 3600000 }
};
this.counters = {};
}
async request(platform, endpoint, options) {
await this.waitForCapacity(platform);
const response = await fetch(endpoint, options);
this.incrementCounter(platform);
return response;
}
async waitForCapacity(platform) {
const limit = this.limits[platform];
const counter = this.counters[platform] || { count: 0, resetTime: Date.now() };
if (Date.now() > counter.resetTime + limit.window) {
counter.count = 0;
counter.resetTime = Date.now();
}
if (counter.count >= limit.limit) {
const waitTime = counter.resetTime + limit.window - Date.now();
await new Promise(resolve => setTimeout(resolve, waitTime));
}
this.counters[platform] = counter;
}
incrementCounter(platform) {
if (!this.counters[platform]) {
this.counters[platform] = { count: 0, resetTime: Date.now() };
}
this.counters[platform].count++;
}
}
Checkliste für die Produktionsbereitstellung
Vor dem Go-Live:
- [ ] OAuth 2.0 für alle Plattformen implementieren
- [ ] Tokens sicher mit Verschlüsselung speichern
- [ ] Automatische Token-Aktualisierung einrichten
- [ ] Ratenbegrenzung pro Plattform implementieren
- [ ] Umfassende Fehlerbehandlung hinzufügen
- [ ] Protokollierung für alle API-Aufrufe einrichten
- [ ] Beitragsgenehmigungs-Workflows erstellen
- [ ] Inhaltsmoderation implementieren
- [ ] Analyseaggregation einrichten
- [ ] Backup-Posting-Mechanismen erstellen
Praktische Anwendungsfälle
Social Media Dashboard
Use Case: Marketingagentur verwaltet >50 Kundenkonten.
- Herausforderung: Multi-Plattform-Management
- Lösung: Zentrales Dashboard mit Multi-Plattform-Posting
- Ergebnis: 60% Zeitersparnis, konsistente Markenpräsenz
Automatisierte Inhaltsverteilung
Use Case: Verlag automatisiert Artikel-Distribution.
- Herausforderung: Manuelles Teilen neuer Inhalte
- Lösung: Automatisches Posting neuer Artikel auf allen Plattformen
- Ergebnis: Sofortige Verteilung, 3x Social-Traffic
Fazit
Auch ohne öffentliche Hootsuite API kannst du mit nativen Plattform-APIs oder spezialisierten Tools Social-Media-Management effizient automatisieren.
Key Takeaways:
- OAuth 2.0 pro Plattform implementieren
- Ratenlimits je Plattform berücksichtigen
- Vereinheitlichtes Posting = plattformspezifische Endpunkte
- Analyseaggregation für Cross-Plattform-Insights nutzen
- Apidog vereinfacht API-Tests und Teamwork
FAQ-Bereich
Hat Hootsuite noch eine API?
Nein, Hootsuite hat die öffentliche API 2024 eingestellt. Nutze native Plattform-APIs oder Alternativen wie Buffer, Sprout Social oder Agorapulse.
Wie poste ich gleichzeitig auf mehreren Plattformen?
Implementiere OAuth für jede Plattform und nutze eine zentrale Posting-Funktion, die die jeweiligen APIs parallel anspricht.
Was sind die Ratenbegrenzungen für Social Media APIs?
Beispiel-Limits: Facebook (200/Stunde), Twitter (300/15min), LinkedIn (100-500/Tag), Instagram (200/Stunde).
Wie plane ich Beiträge?
Lege Beiträge mit scheduled_time in der Datenbank ab und nutze eine Job-Warteschlange (z.B. Bull, Agenda) für zeitgesteuertes Posting.
Kann ich Analysen von allen Plattformen erhalten?
Ja, alle Plattformen bieten Analyse-APIs. Aggregiere die Daten für umfassende plattformübergreifende Reports.
Top comments (0)