Skip to main content
When you already know a prospect’s LinkedIn profile, you can use The Hog to inspect recent public posts they reacted to or commented on. This is useful when you want outreach to reference something timely instead of starting from a generic persona template. This guide uses one profile as an example:
https://www.linkedin.com/in/paulonasc

What you will build

The script below:
  1. Fetches recent posts the profile reacted to.
  2. Fetches recent posts the profile commented on.
  3. Merges both signals by LinkedIn post.
  4. Prints concise outreach hook ideas you can review before using.
Use this to personalize legitimate business outreach from public activity. Always review the generated hooks, avoid sensitive inferences, and respect unsubscribe and outreach rules in your market.

Endpoints used

EndpointWhat it returns
POST /api/v1/platform/scrapers/linkedin/profile-reactionsPublic posts a LinkedIn profile reacted to
POST /api/v1/platform/scrapers/linkedin/profile-commentsPublic posts a LinkedIn profile commented on
Both endpoints accept:
  • profiles: LinkedIn /in/ profile URLs or public usernames
  • maxItems: maximum rows to return per profile
  • postedLimit: one of any, 24h, week, month, 3months, 6months, year

JavaScript example

Create linkedin-hooks.mjs:
const API_BASE_URL = "https://developer.thehog.ai";
const ACCESS_KEY = process.env.HOG_API_ACCESS_KEY;
const SECRET_KEY = process.env.HOG_API_SECRET_KEY;

const profile = process.argv[2] ?? "https://www.linkedin.com/in/paulonasc";

if (!ACCESS_KEY || !SECRET_KEY) {
  throw new Error("Set HOG_API_ACCESS_KEY and HOG_API_SECRET_KEY");
}

async function post(path, body) {
  const response = await fetch(`${API_BASE_URL}${path}`, {
    method: "POST",
    headers: {
      "X-Access-Key": ACCESS_KEY,
      "X-Secret-Key": SECRET_KEY,
      "Content-Type": "application/json",
    },
    body: JSON.stringify(body),
  });

  if (!response.ok) {
    const text = await response.text();
    throw new Error(`${path} failed with ${response.status}: ${text}`);
  }

  return response.json();
}

function postKey(item) {
  return item.post?.postUrl ?? item.post?.postId ?? item.sourceUrl;
}

function summarizePost(post) {
  const text = post?.text?.replace(/\s+/g, " ").trim();
  if (!text) return "a recent LinkedIn post";
  return text.length > 180 ? `${text.slice(0, 177)}...` : text;
}

function makeHooks(reactions, comments) {
  const byPost = new Map();

  for (const reaction of reactions) {
    const key = postKey(reaction);
    if (!key) continue;
    const row = byPost.get(key) ?? {
      post: reaction.post,
      reactions: [],
      comments: [],
    };
    row.reactions.push(reaction);
    byPost.set(key, row);
  }

  for (const comment of comments) {
    const key = postKey(comment);
    if (!key) continue;
    const row = byPost.get(key) ?? {
      post: comment.post,
      reactions: [],
      comments: [],
    };
    row.comments.push(comment);
    byPost.set(key, row);
  }

  return [...byPost.values()]
    .sort((a, b) => b.comments.length - a.comments.length)
    .slice(0, 10)
    .map((row) => {
      const author = row.post?.authorName ?? "someone in their network";
      const postSummary = summarizePost(row.post);
      const comment = row.comments[0]?.commentText;

      return {
        postUrl: row.post?.postUrl,
        signal:
          row.comments.length > 0
            ? `commented on ${author}'s post`
            : `reacted to ${author}'s post`,
        hook: comment
          ? `They commented: "${comment}". Reference the discussion around "${postSummary}".`
          : `They reacted to a post about "${postSummary}". Use that topic as a light opener.`,
      };
    });
}

const request = {
  profiles: [profile],
  maxItems: 20,
  postedLimit: "month",
};

const [reactionResponse, commentResponse] = await Promise.all([
  post("/api/v1/platform/scrapers/linkedin/profile-reactions", request),
  post("/api/v1/platform/scrapers/linkedin/profile-comments", request),
]);

const hooks = makeHooks(reactionResponse.data ?? [], commentResponse.data ?? []);

console.log(JSON.stringify({ profile, hooks }, null, 2));
Run it:
export HOG_API_ACCESS_KEY="ak_xxxxxxxxxxxxxxxx"
export HOG_API_SECRET_KEY="sk_xxxxxxxxxxxxxxxx"

node linkedin-hooks.mjs https://www.linkedin.com/in/paulonasc

Python example

Create linkedin_hooks.py:
import json
import os
import sys
import requests

API_BASE_URL = "https://developer.thehog.ai"
ACCESS_KEY = os.environ["HOG_API_ACCESS_KEY"]
SECRET_KEY = os.environ["HOG_API_SECRET_KEY"]

profile = sys.argv[1] if len(sys.argv) > 1 else "https://www.linkedin.com/in/paulonasc"


def post(path, body):
    response = requests.post(
        f"{API_BASE_URL}{path}",
        headers={
            "X-Access-Key": ACCESS_KEY,
            "X-Secret-Key": SECRET_KEY,
            "Content-Type": "application/json",
        },
        json=body,
        timeout=120,
    )
    response.raise_for_status()
    return response.json()


def post_key(item):
    post = item.get("post") or {}
    return post.get("postUrl") or post.get("postId") or item.get("sourceUrl")


def summarize_post(post):
    text = " ".join((post.get("text") or "").split())
    if not text:
        return "a recent LinkedIn post"
    return text[:177] + "..." if len(text) > 180 else text


request_body = {
    "profiles": [profile],
    "maxItems": 20,
    "postedLimit": "month",
}

reactions = post(
    "/api/v1/platform/scrapers/linkedin/profile-reactions",
    request_body,
).get("data", [])

comments = post(
    "/api/v1/platform/scrapers/linkedin/profile-comments",
    request_body,
).get("data", [])

by_post = {}

for reaction in reactions:
    key = post_key(reaction)
    if not key:
        continue
    by_post.setdefault(key, {"post": reaction.get("post") or {}, "reactions": [], "comments": []})
    by_post[key]["reactions"].append(reaction)

for comment in comments:
    key = post_key(comment)
    if not key:
        continue
    by_post.setdefault(key, {"post": comment.get("post") or {}, "reactions": [], "comments": []})
    by_post[key]["comments"].append(comment)

hooks = []
for row in sorted(by_post.values(), key=lambda value: len(value["comments"]), reverse=True)[:10]:
    post_body = row["post"]
    author = post_body.get("authorName") or "someone in their network"
    summary = summarize_post(post_body)
    comment_text = row["comments"][0].get("commentText") if row["comments"] else None

    hooks.append(
        {
            "postUrl": post_body.get("postUrl"),
            "signal": (
                f"commented on {author}'s post"
                if row["comments"]
                else f"reacted to {author}'s post"
            ),
            "hook": (
                f'They commented: "{comment_text}". Reference the discussion around "{summary}".'
                if comment_text
                else f'They reacted to a post about "{summary}". Use that topic as a light opener.'
            ),
        }
    )

print(json.dumps({"profile": profile, "hooks": hooks}, indent=2))
Run it:
export HOG_API_ACCESS_KEY="ak_xxxxxxxxxxxxxxxx"
export HOG_API_SECRET_KEY="sk_xxxxxxxxxxxxxxxx"

python linkedin_hooks.py https://www.linkedin.com/in/paulonasc

Example output

{
  "profile": "https://www.linkedin.com/in/paulonasc",
  "hooks": [
    {
      "postUrl": "https://www.linkedin.com/feed/update/urn:li:activity:123",
      "signal": "commented on someone in their network's post",
      "hook": "They commented: \"Great breakdown.\" Reference the discussion around \"a recent LinkedIn post\"."
    },
    {
      "postUrl": "https://www.linkedin.com/feed/update/urn:li:activity:456",
      "signal": "reacted to someone in their network's post",
      "hook": "They reacted to a post about \"AI agents for sales workflows\". Use that topic as a light opener."
    }
  ]
}

Production tips

  • Keep maxItems small for interactive workflows; increase it only for batch jobs.
  • Prefer postedLimit: "month" or shorter for timely hooks.
  • Store the returned postUrl with your CRM activity so reps can review the source context.
  • Use comments first when available: they usually reveal stronger intent than a reaction alone.
  • De-duplicate hooks across prospects before generating outreach sequences.