Comment utiliser l'API Hootsuite ?

Ashley Innocent

Ashley Innocent

25 March 2026

Comment utiliser l'API Hootsuite ?

Apidog pour les entreprises

Déploiement sur site

SSO & RBAC

Conforme SOC 2

Découvrir Apidog Enterprise

En bref

L'API Hootsuite permet aux développeurs d'intégrer des flux de travail de gestion des médias sociaux par programmation. Elle utilise l'authentification OAuth 2.0, des points de terminaison RESTful pour les profils, les publications, l'analyse et la gestion d'équipe, avec des limites de débit de 50 à 200 requêtes par minute selon le plan. Ce guide couvre la configuration de l'authentification, la planification des publications, la récupération des analyses, la gestion d'équipe et les stratégies d'intégration en production.

Note : Hootsuite a déprécié son API publique depuis 2024. Ce guide couvre des approches alternatives, y compris les intégrations partenaires de Hootsuite, les webhooks, et les API tierces de gestion des médias sociaux qui offrent des fonctionnalités similaires.

Introduction

Hootsuite gère plus de 30 millions de comptes de médias sociaux pour plus de 200 000 entreprises dans plus de 175 pays. Pour les développeurs qui créent des outils de médias sociaux, des plateformes marketing ou des tableaux de bord analytiques, l'intégration d'API de médias sociaux est essentielle pour atteindre cette vaste audience commerciale.

Voici la réalité : les gestionnaires de médias sociaux qui gèrent plus de 20 comptes perdent 25 à 35 heures par semaine en publication manuelle, suivi de l'engagement et génération de rapports. Une solide intégration d'API de médias sociaux automatise la distribution de contenu, la surveillance de l'engagement, l'analyse des sentiments et les rapports de performance.

button

Statut de l'API Hootsuite et alternatives

Situation actuelle de l'API

Depuis 2024, Hootsuite a déprécié son API publique. Options d'intégration :

Approche Description Idéal pour
API de Plateformes Natives Intégration directe avec Facebook, Twitter, LinkedIn, etc. Contrôle total, solutions personnalisées
Audiense Intelligence d'audience détenue par Hootsuite Analyse d'audience
HeyOrca API de planification de médias sociaux Calendriers de contenu
API Buffer Gestion des médias sociaux Petites équipes
API Sprout Social Gestion sociale d'entreprise Grandes organisations
API Agorapulse CRM de médias sociaux Gestion de communauté

Approche recommandée : API de plateformes natives

Pour la plupart des cas d'utilisation, l'intégration directe avec les plateformes sociales offre la plus grande flexibilité :

Plateforme Nom de l'API Fonctionnalités clés
Facebook/Instagram Graph API Publications, statistiques, commentaires
Twitter/X API v2 Tweets, analyses, flux
LinkedIn Marketing API Publications, pages d'entreprise, publicités
Pinterest API v5 Épingles, tableaux, analyses
TikTok Display API Vidéos, informations utilisateur
YouTube Data API Vidéos, listes de lecture, analyses

Démarrage : Authentification multiplateforme

Étape 1 : Enregistrer les applications de développeur

Créez des comptes développeur pour chaque plateforme :

// Store credentials securely
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, // Uses Facebook Login
    appSecret: process.env.FB_APP_SECRET
  }
};

Étape 2 : Implémenter le flux OAuth 2.0

Gestionnaire OAuth unifié pour plusieurs plateformes :

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()}`;
};

// Handle OAuth callback
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();
};

Étape 3 : Stocker les jetons en toute sécurité

// Database schema for social tokens
const SocialToken = {
  userId: 'user_123',
  platform: 'facebook',
  accessToken: 'encrypted_token_here',
  refreshToken: 'encrypted_refresh_token',
  tokenExpiry: Date.now() + 5183999, // 60 days
  scopes: ['pages_manage_posts', 'pages_read_engagement'],
  pageId: 'page_456', // For Facebook/Instagram
  pageName: 'My Business Page'
};

Planification et publication de posts

Créer un post multiplateforme

Publiez sur plusieurs plateformes simultanément :

const createSocialPost = async (postData) => {
  const results = {};

  // Facebook Page Post
  if (postData.platforms.includes('facebook')) {
    results.facebook = await postToFacebook({
      pageId: postData.facebookPageId,
      message: postData.message,
      link: postData.link,
      photo: postData.photo
    });
  }

  // Twitter Post
  if (postData.platforms.includes('twitter')) {
    results.twitter = await postToTwitter({
      text: postData.message,
      media: postData.photo
    });
  }

  // LinkedIn Post
  if (postData.platforms.includes('linkedin')) {
    results.linkedin = await postToLinkedIn({
      authorUrn: postData.linkedinAuthorUrn,
      text: postData.message,
      contentUrl: postData.link
    });
  }

  // Instagram Post
  if (postData.platforms.includes('instagram')) {
    results.instagram = await postToInstagram({
      igAccountId: postData.igAccountId,
      imageUrl: postData.photo,
      caption: postData.message
    });
  }

  return results;
};

// 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) {
    // Upload media first
    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();

  // Step 1: Create media container
  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();

  // Step 2: Publish
  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();
};

Planification des posts

Implémentez la planification des posts :

const schedulePost = async (postData, scheduledTime) => {
  // Store in database for later execution
  const scheduledPost = await db.scheduledPosts.create({
    message: postData.message,
    platforms: postData.platforms,
    scheduledTime: scheduledTime,
    status: 'pending',
    media: postData.media,
    link: postData.link
  });

  // Set up job queue
  await jobQueue.add('publish-social-post', {
    postId: scheduledPost.id
  }, {
    delay: scheduledTime - Date.now()
  });

  return scheduledPost;
};

// Job processor
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;
  }
});

Analyse et rapports

Récupération d'analyses multiplateformes

Agréguer les métriques de toutes les plateformes :

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)
  };

  // Aggregate metrics
  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 };
};

// 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 Analytics
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 Analytics
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);
}

Gestion d'équipe

Contrôle d'accès basé sur les rôles

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);
};

Limitation de débit

Limites de débit des plateformes

Plateforme Limite Fenêtre
Facebook Graph 200 appels Par heure et par utilisateur
Twitter API v2 300 tweets Par 15 min
LinkedIn 100-500 appels Par jour
Instagram 200 appels Par heure

Implémentation de la gestion des limites de débit

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++;
  }
}

Liste de contrôle de déploiement en production

Avant de passer en direct :

Cas d'utilisation réels

Tableau de bord des médias sociaux

Une agence marketing construit un tableau de bord unifié :

Distribution de contenu automatisée

Un éditeur automatise le partage d'articles :

Conclusion

Bien que l'API publique de Hootsuite soit dépréciée, les API de plateformes natives offrent des capacités complètes de gestion des médias sociaux. Points clés à retenir :

button

Section FAQ

Hootsuite a-t-il toujours une API ?

Hootsuite a déprécié son API publique en 2024. Utilisez les API de plateformes natives ou des plateformes de gestion alternatives comme Buffer, Sprout Social ou Agorapulse.

Comment publier sur plusieurs plateformes à la fois ?

Implémentez OAuth pour chaque plateforme et créez une fonction de publication unifiée qui appelle l'API de chaque plateforme en parallèle.

Quelles sont les limites de débit pour les API de médias sociaux ?

Les limites varient : Facebook (200/heure), Twitter (300/15min), LinkedIn (100-500/jour), Instagram (200/heure).

Comment planifier des posts ?

Stockez les posts dans une base de données avec un `scheduled_time`, puis utilisez une file d'attente de tâches (Bull, Agenda) pour publier à l'heure prévue.

Puis-je obtenir des analyses de toutes les plateformes ?

Oui, chaque plateforme fournit des API d'analyse. Agréguez les données pour des rapports multiplateformes.

Pratiquez le Design-first d'API dans Apidog

Découvrez une manière plus simple de créer et utiliser des API