Back to Blog
Tutorial

Export Instagram Data to Google Sheets Automatically

January 5, 2026
6 min read
S
By SociaVault Team
InstagramGoogle SheetsAutomationNo-CodeData Export

Export Instagram Data to Google Sheets

You want Instagram data in a spreadsheet. Follower counts, engagement rates, post performance—updated automatically.

Google Sheets is perfect for this:

  • Share with your team
  • Create charts and dashboards
  • Set up alerts with conditional formatting
  • No database required

Here's how to set it up.

Need Instagram data? Get started at sociavault.com/free/social-media-api.

What We're Building

A Google Sheet that:

  1. Pulls Instagram profile data
  2. Tracks posts and engagement
  3. Updates automatically (daily/hourly)
  4. Calculates engagement rates

Method 1: Google Apps Script (Best)

Step 1: Create the Spreadsheet

  1. Go to sheets.google.com
  2. Create a new spreadsheet
  3. Name it "Instagram Tracker"

Create these sheets/tabs:

  • Profiles - Account metrics
  • Posts - Individual post data
  • Config - Settings and API key

Step 2: Add Apps Script

  1. Go to Extensions > Apps Script
  2. Delete any existing code
  3. Paste this:
// Config
const API_KEY = PropertiesService.getScriptProperties().getProperty('SOCIAVAULT_API_KEY');
const API_BASE = 'https://api.sociavault.com/v1/scrape/instagram';

// Main function to update all data
function updateAllData() {
  updateProfiles();
  updatePosts();
  SpreadsheetApp.getActiveSpreadsheet().toast('Data updated!', 'Success', 3);
}

// Fetch Instagram profile
function fetchProfile(username) {
  const url = `${API_BASE}/profile?username=${encodeURIComponent(username)}`;
  
  const options = {
    method: 'get',
    headers: {
      'Authorization': `Bearer ${API_KEY}`
    },
    muteHttpExceptions: true
  };
  
  const response = UrlFetchApp.fetch(url, options);
  const data = JSON.parse(response.getContentText());
  
  if (!data.success) {
    throw new Error(data.error?.message || 'API error');
  }
  
  return data.data;
}

// Fetch user's posts
function fetchPosts(username, count = 20) {
  const url = `${API_BASE}/posts?username=${encodeURIComponent(username)}&count=${count}`;
  
  const options = {
    method: 'get',
    headers: {
      'Authorization': `Bearer ${API_KEY}`
    },
    muteHttpExceptions: true
  };
  
  const response = UrlFetchApp.fetch(url, options);
  const data = JSON.parse(response.getContentText());
  
  if (!data.success) {
    throw new Error(data.error?.message || 'API error');
  }
  
  return data.data.posts;
}

// Update Profiles sheet
function updateProfiles() {
  const ss = SpreadsheetApp.getActiveSpreadsheet();
  const configSheet = ss.getSheetByName('Config');
  const profilesSheet = ss.getSheetByName('Profiles');
  
  // Get usernames from Config sheet
  const usernamesRange = configSheet.getRange('A2:A');
  const usernames = usernamesRange.getValues()
    .flat()
    .filter(u => u !== '');
  
  // Clear existing data (keep headers)
  const lastRow = profilesSheet.getLastRow();
  if (lastRow > 1) {
    profilesSheet.getRange(2, 1, lastRow - 1, 10).clearContent();
  }
  
  // Fetch and write data
  const data = [];
  const timestamp = new Date();
  
  for (const username of usernames) {
    try {
      const profile = fetchProfile(username);
      
      data.push([
        profile.username,
        profile.full_name,
        profile.followers,
        profile.following,
        profile.posts_count,
        profile.bio,
        profile.is_verified,
        profile.external_url,
        calculateEngagementRate(profile),
        timestamp
      ]);
      
      Utilities.sleep(500); // Rate limiting
    } catch (error) {
      data.push([username, 'ERROR', error.message, '', '', '', '', '', '', timestamp]);
    }
  }
  
  if (data.length > 0) {
    profilesSheet.getRange(2, 1, data.length, data[0].length).setValues(data);
  }
}

// Update Posts sheet
function updatePosts() {
  const ss = SpreadsheetApp.getActiveSpreadsheet();
  const configSheet = ss.getSheetByName('Config');
  const postsSheet = ss.getSheetByName('Posts');
  
  // Get usernames from Config
  const usernames = configSheet.getRange('A2:A').getValues()
    .flat()
    .filter(u => u !== '');
  
  // Clear existing data
  const lastRow = postsSheet.getLastRow();
  if (lastRow > 1) {
    postsSheet.getRange(2, 1, lastRow - 1, 10).clearContent();
  }
  
  const data = [];
  const timestamp = new Date();
  
  for (const username of usernames) {
    try {
      const posts = fetchPosts(username, 12); // Last 12 posts
      
      for (const post of posts) {
        data.push([
          username,
          post.post_id,
          post.caption ? post.caption.substring(0, 200) : '',
          post.like_count,
          post.comment_count,
          post.media_type,
          post.timestamp,
          post.url,
          (post.like_count + post.comment_count),
          timestamp
        ]);
      }
      
      Utilities.sleep(500);
    } catch (error) {
      data.push([username, 'ERROR', error.message, '', '', '', '', '', '', timestamp]);
    }
  }
  
  if (data.length > 0) {
    postsSheet.getRange(2, 1, data.length, data[0].length).setValues(data);
  }
}

// Calculate engagement rate
function calculateEngagementRate(profile) {
  // This is approximate - would need recent posts for accurate calculation
  if (profile.followers === 0) return 0;
  // Placeholder - real calculation would average recent post engagement
  return 'N/A';
}

// Set up triggers for automatic updates
function setupTriggers() {
  // Remove existing triggers
  const triggers = ScriptApp.getProjectTriggers();
  triggers.forEach(trigger => ScriptApp.deleteTrigger(trigger));
  
  // Add daily trigger
  ScriptApp.newTrigger('updateAllData')
    .timeBased()
    .everyDays(1)
    .atHour(9)
    .create();
}

// Menu for manual updates
function onOpen() {
  const ui = SpreadsheetApp.getUi();
  ui.createMenu('Instagram Tracker')
    .addItem('Update All Data', 'updateAllData')
    .addItem('Update Profiles Only', 'updateProfiles')
    .addItem('Update Posts Only', 'updatePosts')
    .addSeparator()
    .addItem('Setup Daily Updates', 'setupTriggers')
    .addToUi();
}

Step 3: Set Up Your API Key

  1. In Apps Script, go to Project Settings (gear icon)
  2. Scroll to Script Properties
  3. Click Add Script Property
  4. Name: SOCIAVAULT_API_KEY
  5. Value: Your API key from SociaVault

Step 4: Set Up the Sheets

Config Sheet:

A (Usernames)
natgeo
nike
nasa

Profiles Sheet (headers in row 1):

UsernameNameFollowersFollowingPostsBioVerifiedWebsiteEng RateUpdated

Posts Sheet (headers in row 1):

UsernamePost IDCaptionLikesCommentsTypePostedURLTotal EngUpdated

Step 5: Run It

  1. Reload your spreadsheet
  2. Click Instagram Tracker > Update All Data
  3. Authorize the script when prompted
  4. Data will populate!

Step 6: Set Up Automatic Updates

Click Instagram Tracker > Setup Daily Updates

This creates a trigger that runs every day at 9 AM.

Method 2: Zapier/Make (No-Code)

If you prefer no-code tools:

With Zapier

  1. Create a Zap: Webhook > Google Sheets
  2. Use Zapier's webhook to call SociaVault API
  3. Map response fields to columns

With Make (Integromat)

Trigger: Schedule (daily)
HTTP Request: GET SociaVault API
JSON Parser: Parse response
Google Sheets: Add/Update Row

Advanced: Dashboard Sheet

Create a Dashboard sheet with formulas:

=QUERY(Profiles!A:J, "SELECT A, C, E ORDER BY C DESC LIMIT 5")

This shows your top 5 accounts by followers.

=SPARKLINE(FILTER(Posts!D:D, Posts!A:A = "natgeo"))

Shows a mini chart of likes over time.

Conditional Formatting

  1. Select the Followers column
  2. Format > Conditional formatting
  3. Color scale from red (low) to green (high)

Tracking Engagement Over Time

To track historical data, modify the script to append rather than replace:

function appendProfileHistory() {
  const ss = SpreadsheetApp.getActiveSpreadsheet();
  const historySheet = ss.getSheetByName('History') || ss.insertSheet('History');
  const configSheet = ss.getSheetByName('Config');
  
  const usernames = configSheet.getRange('A2:A').getValues()
    .flat()
    .filter(u => u !== '');
  
  const timestamp = new Date();
  
  for (const username of usernames) {
    try {
      const profile = fetchProfile(username);
      
      historySheet.appendRow([
        timestamp,
        profile.username,
        profile.followers,
        profile.following,
        profile.posts_count
      ]);
      
      Utilities.sleep(500);
    } catch (error) {
      historySheet.appendRow([timestamp, username, 'ERROR', error.message]);
    }
  }
}

Then create a chart from the History sheet to visualize follower growth.

Tips

1. Stay Within Rate Limits

Add delays between API calls:

Utilities.sleep(500); // 500ms delay

2. Handle Errors

Always wrap API calls in try/catch:

try {
  const data = fetchProfile(username);
} catch (error) {
  Logger.log(`Error for ${username}: ${error.message}`);
}

3. Optimize for Large Lists

If tracking 50+ accounts, consider:

  • Running updates in batches
  • Using caching
  • Spreading updates throughout the day

4. Protect Your API Key

Never put your API key directly in the code. Use Script Properties.


Ready to track Instagram data in Google Sheets?

Get your API key at sociavault.com with 50 free credits.


Related:

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.