Back to Blog
Agency

Automate Cross-Platform Social Media Reports for Clients

December 20, 2025
5 min read
S
By SociaVault Team
ReportingAutomationAgencyAnalytics

Automate Cross-Platform Social Media Reports for Clients

If you run social for clients, you know the monthly ritual: open five dashboards, copy numbers into a deck, screenshot some charts, repeat per client. It's hours of mechanical work that adds no insight — and it's the first thing worth automating. The good news is the data you need for a high-level report is all public and pullable in one script.

This guide builds a cross-platform report generator that pulls headline metrics from YouTube, TikTok, and Instagram into one clean summary you can drop into a PDF. Code in JavaScript. (Honest scope note: this covers public vanity metrics — followers, views, post counts — which are exactly what most exec summaries lead with. For private metrics like reach and impressions, you'd still pull from each platform's native analytics.)

Step 1: A metrics collector

The key is reading each platform's fields correctly — they all differ. Here's the collector with the right paths and defensive fallbacks:

const API_KEY = process.env.SOCIAVAULT_API_KEY;
const BASE = "https://api.sociavault.com/v1/scrape";
const headers = { "x-api-key": API_KEY };

async function collect(client) {
  const metrics = { youtube: {}, tiktok: {}, instagram: {} };

  // YouTube — channel returns text-formatted counts
  try {
    const yt = await (
      await fetch(`${BASE}/youtube/channel?handle=${client.youtube}`, {
        headers,
      })
    ).json();
    const d = yt.data || {};
    metrics.youtube = {
      subscribers: d.subscriberCountText,
      views: d.viewCountText,
    };
  } catch {
    /* skip on failure */
  }

  // TikTok — profile returns { user, stats }
  try {
    const tt = await (
      await fetch(`${BASE}/tiktok/profile?handle=${client.tiktok}`, { headers })
    ).json();
    const s = tt.data?.stats || {};
    metrics.tiktok = { followers: s.followerCount, likes: s.heartCount };
  } catch {
    /* skip */
  }

  // Instagram — profile; follower count is nested under edge_followed_by
  try {
    const ig = await (
      await fetch(`${BASE}/instagram/profile?handle=${client.instagram}`, {
        headers,
      })
    ).json();
    const d = ig.data || {};
    metrics.instagram = {
      followers: d.edge_followed_by?.count,
      posts: d.edge_owner_to_timeline_media?.count,
    };
  } catch {
    /* skip */
  }

  return metrics;
}

The field paths are the part worth getting right: TikTok stats live at data.stats.followerCount/heartCount, Instagram followers at data.edge_followed_by.count, and YouTube counts come as display text (subscriberCountText). Wrapping each platform in its own try/catch means one platform failing doesn't sink the whole report.

Step 2: Render the report

A simple console summary first, so you can see the shape:

async function report(client) {
  const m = await collect(client);
  console.log(`\n=== ${client.name}${new Date().toLocaleDateString()} ===`);
  console.log(
    `YouTube:   ${m.youtube.subscribers ?? "n/a"} subs · ${m.youtube.views ?? "n/a"} views`,
  );
  console.log(
    `TikTok:    ${(m.tiktok.followers ?? 0).toLocaleString()} followers · ${(m.tiktok.likes ?? 0).toLocaleString()} likes`,
  );
  console.log(
    `Instagram: ${(m.instagram.followers ?? 0).toLocaleString()} followers · ${m.instagram.posts ?? "n/a"} posts`,
  );
}

report({
  name: "TechStart Inc.",
  youtube: "@TechStart",
  tiktok: "techstart_official",
  instagram: "techstart.io",
});

Step 3: Turn it into a PDF

For a client-facing deliverable, pipe the metrics into a PDF with a library like pdfkit:

import PDFDocument from "pdfkit";
import fs from "fs";

function toPdf(client, m) {
  const doc = new PDFDocument({ margin: 50 });
  doc.pipe(
    fs.createWriteStream(`${client.name.replace(/\s+/g, "-")}-report.pdf`),
  );

  doc.fontSize(20).text(`${client.name} — Social Report`, { align: "center" });
  doc
    .moveDown()
    .fontSize(12)
    .text(new Date().toLocaleDateString(), { align: "center" });
  doc.moveDown();

  doc.fontSize(14).text("YouTube");
  doc
    .fontSize(11)
    .text(`Subscribers: ${m.youtube.subscribers ?? "n/a"}`)
    .text(`Views: ${m.youtube.views ?? "n/a"}`);
  doc.moveDown();
  doc.fontSize(14).text("TikTok");
  doc
    .fontSize(11)
    .text(`Followers: ${(m.tiktok.followers ?? 0).toLocaleString()}`);
  doc.moveDown();
  doc.fontSize(14).text("Instagram");
  doc
    .fontSize(11)
    .text(`Followers: ${(m.instagram.followers ?? 0).toLocaleString()}`);
  doc.end();
}

Schedule the whole thing on the first of each month, loop over your client list, and email out the PDFs — the monthly report ritual goes from hours to a cron job.

Make it useful, not just automated

A pile of numbers isn't a report. To make clients actually value it, store each month's snapshot and show the delta ("+12% TikTok followers vs last month") rather than a static count. Month-over-month change is the number clients care about, and you already have the data to compute it once you're capturing snapshots.

Frequently Asked Questions

Can I automate social media reports across platforms?

Yes. Pull each platform's public metrics via API, normalize the differing field names into one structure, and render a summary or PDF — as this guide does for YouTube, TikTok, and Instagram. Schedule it monthly and the manual dashboard-copying disappears.

What metrics can I include?

Public vanity metrics like followers, total views, likes, and post counts, which are exactly what most executive summaries lead with. Private metrics such as reach and impressions aren't in public data — pull those from each platform's native analytics if your report needs them.

Why do the field names differ per platform?

Each platform structures its data differently — TikTok nests stats under stats, Instagram puts followers under edge_followed_by.count, YouTube returns counts as display text. Reading each correctly (and wrapping each in error handling) is the main work in a reliable multi-platform report.

How do I make the report a PDF?

Pipe the collected metrics into a PDF library like pdfkit, laying out a section per platform. The code above shows a basic version; you can add charts, branding, and month-over-month deltas for a polished client deliverable.

How do I show growth instead of just totals?

Store each month's metrics and compute the difference against the prior snapshot. Showing "+12% vs last month" is far more meaningful to clients than a raw follower count, and it only requires persisting the numbers you already collect.

Can one platform failing break the whole report?

Not if you wrap each platform's fetch in its own try/catch, as shown. That way a temporary failure on, say, TikTok just leaves that section blank instead of aborting the entire report — important for an unattended scheduled job.

The bottom line

Monthly client reporting is mechanical work begging to be automated. Pull the public metrics with correct field paths, render them to a branded PDF, schedule it monthly, and add month-over-month deltas so the report delivers insight, not just numbers.

Want to automate your reporting? Start free with SociaVault with 50 credits.

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.