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

# Person Activity Signal

> Get notified when the LinkedIn people you track react to or comment on any post, with the post, its author, and their comment text.

# Person Activity Signal

The `person_activity` signal tells you when a person you track **reacts to or comments on anything** on LinkedIn: their likes and other reactions, their comments, and their replies to comments, on anyone's post.

Use it to see what a champion, prospect, or competitor's executive is paying attention to, and to reach out while it is fresh.

<Note>
  `person_activity` is the opposite direction from [`person_engagement`](/api-reference/endpoints/signal-person-engagement):

  * **person\_activity**: what the tracked person does. *"Satya liked a post by Ryan Roslansky."*
  * **person\_engagement**: who engages with the tracked person's content. *"Taylor commented on Satya's post."*
</Note>

You can run **several** `person_activity` signals, for example one for champions and one for churned customers. Each is identified by its `signal_id` and can carry a `name` for display. A person tracked by two signals triggers alerts from both.

***

## How it works

1. **First run: baseline.** For each profile, the signal records the person's current activity and reports nothing. You receive one `baseline` webhook listing the profiles now being tracked.
2. **Every run after that:** each reaction, comment, and reply the person made since the last run is reported **once**, oldest first.
3. **Runs follow the signal's schedule** (`frequency`, default once a day). See [Create Signal](/api-reference/endpoints/signal-create#schedule-and-name-all-signal-types).

`occurred_at` on each item is when the person reacted or commented, not when the post was published.

***

## Create a person activity signal

`POST https://api.datamagnet.co/api/v1/signal/create`

### Request

<ParamField body="signal_type" type="string" required>
  Must be `"person_activity"`.
</ParamField>

<ParamField body="profile_urls" type="array" required>
  LinkedIn profile URLs of the people to track.

  ```json theme={null}
  ["https://www.linkedin.com/in/satyanadella", "https://www.linkedin.com/in/williamhgates"]
  ```
</ParamField>

<ParamField body="activity_types" type="array" default="[&#x22;reactions&#x22;, &#x22;comments&#x22;]">
  What to report. `"reactions"`, `"comments"`, or both. Replies to comments count as comments.

  Each type is a separate check per profile per run, so tracking only one halves the cost of each run.
</ParamField>

<ParamField body="name" type="string">
  A display name for this signal, such as `"Champions"`. Optional; defaults to `"Person Activity Monitor"`. Change it later with the `rename` action.
</ParamField>

<ParamField body="new_signal" type="boolean" default="false">
  Set to `true` to create another `person_activity` signal when you already have one. Without it, profiles are added to your existing signal. See [Several signals of one type](/api-reference/endpoints/signal-create#several-signals-of-one-type).
</ParamField>

<ParamField body="signal_id" type="string">
  Add these profiles to an existing `person_activity` signal instead of creating one.
</ParamField>

<ParamField body="frequency" type="string" default="every_day">
  How often the signal runs: `"every_hour"`, `"every_2hr"`, `"every_day"`, or `"every_week"`.
</ParamField>

<ParamField body="additional_emails" type="array">
  Extra email addresses to notify. Your account email is always included.
</ParamField>

<ParamField body="webhook_url" type="string">
  URL to receive activity via `POST`. See [Webhook payload](#webhook-payload) below.
</ParamField>

<ParamField body="webhook_secret" type="string">
  HMAC secret for signing webhook payloads. See [Verifying webhook signatures](/api-reference/webhooks#verifying-webhook-signatures).
</ParamField>

```json Request theme={null}
{
  "signal_type": "person_activity",
  "name": "Champions",
  "profile_urls": ["https://www.linkedin.com/in/satyanadella"],
  "activity_types": ["reactions", "comments"],
  "frequency": "every_day",
  "webhook_url": "https://yourapp.com/webhooks/signals",
  "webhook_secret": "your-hmac-secret"
}
```

### Response

<ResponseExample>
  ```json Response theme={null}
  {
    "message": {
      "signal_id": "a1b2c3d4-5e6f-4a7b-8c9d-0e1f2a3b4c5d",
      "signal_type": "person_activity",
      "name": "Champions",
      "status": "active",
      "profile_urls": ["https://www.linkedin.com/in/satyanadella"],
      "activity_types": ["reactions", "comments"],
      "email_recipients": ["user@example.com"],
      "webhook_url": "https://yourapp.com/webhooks/signals"
    },
    "credit_used": 1
  }
  ```
</ResponseExample>

<ResponseField name="signal_id" type="string">
  Unique identifier for this signal. **Save this**: use it to update, add profiles to, or delete this signal.
</ResponseField>

<ResponseField name="name" type="string">
  The signal's display name.
</ResponseField>

<ResponseField name="profile_urls" type="array">
  All profiles this signal tracks.
</ResponseField>

<ResponseField name="activity_types" type="array">
  What the signal reports: `"reactions"`, `"comments"`, or both.
</ResponseField>

***

## Credits

* **Creating a signal or adding profiles:** `1` credit per profile added.
* **Each run:** one [Person Activity](/api-reference/endpoints/people-activity) request per profile per activity type, billed at that endpoint's rate. Tracking both reactions and comments is two requests per profile per run. A very active person can need an extra page, which is one more request, capped at 3 pages per type per run.

Credits are charged to the API key the signal was created with.

***

## Webhook payload

Each delivery is a single `POST` with a JSON body. `job_id` is the signal's `signal_id`, and `job_name` is its name, so you can tell your signals apart.

### Baseline

Sent once per run in which profiles were tracked for the first time.

```json baseline theme={null}
{
  "event": "baseline",
  "user_email": "user@example.com",
  "signal_type": "person_activity",
  "job_id": "a1b2c3d4-5e6f-4a7b-8c9d-0e1f2a3b4c5d",
  "job_name": "Champions",
  "profiles": [
    { "profile_url": "https://www.linkedin.com/in/satyanadella", "profile_name": "Satya Nadella" }
  ]
}
```

### New activity

One entry per reaction, comment, or reply, oldest first.

```json person_activity theme={null}
{
  "event": "person_activity",
  "user_email": "user@example.com",
  "signal_type": "person_activity",
  "job_id": "a1b2c3d4-5e6f-4a7b-8c9d-0e1f2a3b4c5d",
  "job_name": "Champions",
  "changes": [
    {
      "event_id": "5b0c9d7e-2f4a-4c1b-9e3d-7a8b6c5d4e3f",
      "profile_url": "https://www.linkedin.com/in/satyanadella",
      "profile_name": "Satya Nadella",
      "signal_type": "reaction",
      "change_summary": "Liked a post by Ryan Roslansky",
      "confidence": null,
      "detected_at": "2026-09-18T08:00:12.204518+00:00",
      "change_data": {
        "activity_type": "reaction",
        "occurred_at": "2026-09-17T18:30:42.168Z",
        "reaction_type": "LIKE",
        "target": "post",
        "target_comment_author": null,
        "target_comment_url": null,
        "post_url": "https://www.linkedin.com/posts/ryanroslansky_ai-activity-7506405584091541505-fa6g",
        "post_urn": "urn:li:activity:7506405584091541505",
        "post_text": "AI is helping mathematicians make real progress on Navier-Stokes…",
        "post_author": {
          "name": "Ryan Roslansky",
          "url": "https://www.linkedin.com/in/ryanroslansky",
          "headline": "Executive Vice President at Microsoft"
        }
      }
    },
    {
      "event_id": "8e1f0a2b-3c4d-4e5f-a6b7-c8d9e0f1a2b3",
      "profile_url": "https://www.linkedin.com/in/satyanadella",
      "profile_name": "Satya Nadella",
      "signal_type": "comment",
      "change_summary": "Commented on a post by Kevin Scott: “Congratulations to the whole team on this milestone.”",
      "confidence": null,
      "detected_at": "2026-09-18T08:00:12.204518+00:00",
      "change_data": {
        "activity_type": "comment",
        "occurred_at": "2026-09-17T21:04:10.512Z",
        "comment_text": "Congratulations to the whole team on this milestone.",
        "comment_url": "https://www.linkedin.com/feed/update/urn:li:activity:7506512345678901234?commentUrn=urn%3Ali%3Acomment%3A%28activity%3A7506512345678901234%2C7506598765432109876%29",
        "comment_urn": "urn:li:comment:(activity:7506512345678901234,7506598765432109876)",
        "post_url": "https://www.linkedin.com/posts/kevinscott_milestone-activity-7506512345678901234-ab12",
        "post_urn": "urn:li:activity:7506512345678901234",
        "post_text": "Today we shipped…",
        "post_author": {
          "name": "Kevin Scott",
          "url": "https://www.linkedin.com/in/kevinscott",
          "headline": "CTO at Microsoft"
        }
      }
    }
  ]
}
```

### Fields

<ResponseField name="changes[].event_id" type="string">
  Unique ID of this item. Use it to de-duplicate on your side.
</ResponseField>

<ResponseField name="changes[].signal_type" type="string">
  `"reaction"`, `"comment"`, or `"reply"`.
</ResponseField>

<ResponseField name="changes[].change_summary" type="string">
  One line describing the activity, such as `Liked a post by Ryan Roslansky` or `Replied to a comment on a post by Kevin Scott: "…"`. Comments and replies quote the start of the comment.
</ResponseField>

<ResponseField name="changes[].change_data" type="object">
  <Expandable title="All activity types">
    <ResponseField name="activity_type" type="string">`"reaction"`, `"comment"`, or `"reply"`.</ResponseField>
    <ResponseField name="occurred_at" type="string">ISO 8601 time the person reacted or commented, to the millisecond.</ResponseField>
    <ResponseField name="post_url" type="string">The post the activity is on.</ResponseField>
    <ResponseField name="post_urn" type="string | null">The post's LinkedIn URN.</ResponseField>
    <ResponseField name="post_text" type="string | null">The first 300 characters of the post.</ResponseField>
    <ResponseField name="post_author" type="object | null">The post's author: `name`, `url`, `headline`.</ResponseField>
  </Expandable>

  <Expandable title="Reactions">
    <ResponseField name="reaction_type" type="string">`LIKE` · `EMPATHY` · `PRAISE` · `APPRECIATION` · `INTEREST` · `ENTERTAINMENT`</ResponseField>
    <ResponseField name="target" type="string">`"post"`, or `"comment"` when the person reacted to a comment on the post.</ResponseField>
    <ResponseField name="target_comment_author" type="string | null">Author of the comment reacted to, when `target` is `"comment"`.</ResponseField>
    <ResponseField name="target_comment_url" type="string | null">Link to the comment reacted to, when `target` is `"comment"`.</ResponseField>
  </Expandable>

  <Expandable title="Comments and replies">
    <ResponseField name="comment_text" type="string | null">The person's comment, up to 2,000 characters.</ResponseField>
    <ResponseField name="comment_url" type="string | null">Direct link to the comment.</ResponseField>
    <ResponseField name="comment_urn" type="string | null">The comment's LinkedIn URN.</ResponseField>
  </Expandable>
</ResponseField>

`confidence` is always `null` for this signal.

***

## Managing the signal

Use [Update Signal](/api-reference/endpoints/signal-update) with `signal_type: "person_activity"`. Pass `signal_id` to choose the signal; it can be left out only when you have exactly one.

| Action                             | What it does                                                                |
| ---------------------------------- | --------------------------------------------------------------------------- |
| `add_profiles` / `remove_profiles` | Change the tracked people. New profiles take a baseline on their first run. |
| `update_activity_types`            | Switch between reactions, comments, or both. Requires `activity_types`.     |
| `rename`                           | Change the display name. Requires `name`.                                   |
| `pause` / `resume`                 | Stop and restart the signal.                                                |
| `update_webhook` / `update_emails` | Change where alerts go.                                                     |

To remove a signal completely, use [Delete Signal](/api-reference/endpoints/signal-delete).
