Audit a Public Instagram Profile

Site instagram.comTask audit-public-instagram-profileVersion v2Updated Aug 7, 2026Category social-media

Retrieve a public Instagram profile's identity, bio, follower counts, post inventory, and available engagement metrics through Instagram's profile-information API. This skill was captured from a live agent session on instagram.com and is published here as a reusable recipe for agents.

NoteSelectors and URL schemes drift as sites change. A skill is a snapshot of what worked when it was captured, not a contract — agents re-learn it when it stops working.

Audit a public Instagram profile identified by {username}, including its biography, account metadata, follower/following counts, total post count, and the posts returned by Instagram's profile timeline API with likes, comments, views, timestamps, captions, and media type.

Use Cases

Use when the caller supplies an Instagram username and wants a structured profile audit rather than only visible page text. This workflow is intended for public or otherwise accessible profiles; it does not bypass login, consent, rate limits, or privacy restrictions.

Automation Flow

  1. Navigate directly to https://www.instagram.com/{username}/.
  2. In the same browser call, run this evaluator on the loaded Instagram page. It calls Instagram's same-origin profile-information endpoint, avoiding homepage navigation and UI interaction:
(async () => {
  const endpoint = `/api/v1/users/web_profile_info/?username=${encodeURIComponent("{username}")}`;
  try {
    const response = await fetch(endpoint, {
      headers: { "x-ig-app-id": "936619743392459" },
      credentials: "include",
    });
    if (!response.ok) {
      return {
        ok: false,
        status: response.status,
        url: location.href,
        error: `profile API returned HTTP ${response.status}`,
      };
    }
    const payload = await response.json();
    const u = payload && payload.data && payload.data.user;
    if (!u)
      return {
        ok: false,
        status: response.status,
        url: location.href,
        error: "profile object missing",
      };
    const first = (value, fallback = null) =>
      Array.isArray(value) && value.length ? value[0] : fallback;
    const captionOf = (n) =>
      first(n.edge_media_to_caption && n.edge_media_to_caption.edges, {})?.node
        ?.text || "";
    const mediaEdges = u.edge_owner_to_timeline_media?.edges || [];
    const timeline = u.edge_owner_to_timeline_media || {};
    const posts = mediaEdges.map(({ node: n }) => ({
      shortcode: n.shortcode || null,
      url: n.shortcode ? `https://www.instagram.com/p/${n.shortcode}/` : null,
      type: n.__typename || null,
      isVideo: !!n.is_video,
      isPinned: Array.isArray(n.pinned_for_users) && n.pinned_for_users.length > 0,
      caption: captionOf(n),
      likes: n.edge_liked_by?.count ?? n.edge_media_preview_like?.count ?? null,
      comments: n.edge_media_to_comment?.count ?? null,
      views: n.video_view_count ?? null,
      timestamp: n.taken_at_timestamp ?? null,
      displayUrl: n.display_url || null,
      dimensions: n.dimensions
        ? { width: n.dimensions.width ?? null, height: n.dimensions.height ?? null }
        : null,
    }));
    return {
      ok: true,
      url: location.href,
      username: u.username || null,
      fullName: u.full_name || null,
      biography: u.biography || "",
      externalUrl: u.external_url || null,
      category: u.category_name || null,
      isPrivate: !!u.is_private,
      isBusinessAccount: !!u.is_business_account,
      isProfessionalAccount: !!u.is_professional_account,
      followers: u.edge_followed_by?.count ?? null,
      following: u.edge_follow?.count ?? null,
      totalPosts: u.edge_owner_to_timeline_media?.count ?? null,
      postsReturned: posts.length,
      timelinePageInfo: timeline.page_info || null,
      posts,
    };
  } catch (error) {
    return { ok: false, url: location.href, error: String(error) };
  }
})();
  1. Use followers, following, totalPosts, and each post's likes, comments, and views as the raw audit data. If an engagement rate is requested, calculate it from the returned values and state the denominator and whether it uses followers or reach; do not infer unavailable metrics.

Possible Friction Points

  • The durable data source is /api/v1/users/web_profile_info/?username={username}, not a guessed profile slug or a DOM-only scrape.
  • The endpoint requires the public x-ig-app-id: 936619743392459 request header; use it from an Instagram page with same-origin credentials.
  • The timeline response is a collection slice. Preserve timelinePageInfo and distinguish postsReturned from totalPosts; do not claim the returned posts are the complete history unless additional pagination has been explicitly performed.
  • Like counts may appear as edge_liked_by.count or edge_media_preview_like.count; comments use edge_media_to_comment.count, and video views use video_view_count.
  • A profile may be private, logged out, rate-limited, unavailable, or replaced by a login/consent interstitial. Report the API status or access failure instead of treating interstitial text as profile data.
  • Counts and post metrics are point-in-time values and may be absent (null) for restricted or unsupported fields.

Call it

GET https://production-sfo.browserless.io/skills?token=TOKEN-HERE&domain=instagram.com&task=audit-public-instagram-profile