> ## Documentation Index
> Fetch the complete documentation index at: https://docs.thehog.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Find Outreach Hooks from LinkedIn Activity

> Use LinkedIn profile reactions and comments to find recent posts your prospects engaged with, then turn that context into relevant outreach hooks.

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:

```text theme={null} theme={"theme":{"light":"github-light","dark":"github-dark"}}
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.

<Warning>
  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.
</Warning>

## Endpoints used

| Endpoint                                                    | What it returns                              |
| ----------------------------------------------------------- | -------------------------------------------- |
| `POST /api/v1/platform/scrapers/linkedin/profile-reactions` | Public posts a LinkedIn profile reacted to   |
| `POST /api/v1/platform/scrapers/linkedin/profile-comments`  | Public 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`:

```js theme={null} theme={"theme":{"light":"github-light","dark":"github-dark"}}
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:

```bash theme={null} theme={"theme":{"light":"github-light","dark":"github-dark"}}
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`:

```python theme={null} theme={"theme":{"light":"github-light","dark":"github-dark"}}
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:

```bash theme={null} theme={"theme":{"light":"github-light","dark":"github-dark"}}
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

```json theme={null} theme={"theme":{"light":"github-light","dark":"github-dark"}}
{
  "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.
