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

# Get Profile Reactions

> Fetch posts that a professional profile has reacted to

## Endpoint

```
GET /api/v1/profile/reactions
```

## Authentication

Include your API key in the request header:

```bash theme={null}
X-API-Key: your-api-key-here
```

## Parameters

<ParamField query="profileUrlOrUrn" type="string" required>
  The professional profile whose reactions to fetch. Accepts any of:

  * **Profile URN**, recommended for consistency: a profile's public identifier (slug) can change over time, the URN does not. Example: `urn:li:fsd_profile:ACoAAA8BYqEBCGLg_vT_ca6mMEqkpp9nVffJ3hc`
  * **Public identifier (slug)**, also fine. Example: `williamhgates`
  * **Profile URL**. Example: `https://www.linkedin.com/in/williamhgates` (a trailing slash makes no difference)

  The slug is the last path segment of a profile URL (`linkedin.com/in/<slug>`). Pass just the slug, not the `/in/` prefix.
</ParamField>

<ParamField query="count" type="integer" default="10">
  Number of reactions to fetch per page.

  * Minimum: 1
  * Maximum: 50
  * Default: 10
</ParamField>

<ParamField query="start" type="integer" default="0">
  Offset for pagination.

  * Default: 0
</ParamField>

<ParamField query="paginationToken" type="string">
  Token for fetching the next page of reactions. Returned from previous request when more reactions are available.
</ParamField>

## Response

<ResponseField name="reactions" type="array">
  Array of reactions, each containing the reaction type and the post that was reacted to

  <Expandable title="Reaction object">
    <ResponseField name="reactionType" type="string">
      The type of reaction the profile made. One of: `LIKE`, `EMPATHY` (Love), `ENTERTAINMENT` (Funny), `INTEREST` (Insightful), `PRAISE` (Celebrate), `APPRECIATION` (Support).
    </ResponseField>

    <ResponseField name="post" type="object">
      The post that was reacted to. Same shape as items from `GET /api/v1/posts`.

      <Expandable title="Post object">
        <ResponseField name="id" type="string">
          Unique post identifier (URN format)
        </ResponseField>

        <ResponseField name="content" type="string">
          Post content/text
        </ResponseField>

        <ResponseField name="date" type="string">
          ISO 8601 timestamp of when the post was published
        </ResponseField>

        <ResponseField name="reactionCount" type="integer">
          Total reactions count (likes, etc.)
        </ResponseField>

        <ResponseField name="commentCount" type="integer">
          Total comments count
        </ResponseField>

        <ResponseField name="imageUrl" type="string">
          URL of post image (if present)
        </ResponseField>

        <ResponseField name="videoUrl" type="string">
          URL of post video (if present)
        </ResponseField>

        <ResponseField name="carouselPdfUrl" type="string">
          URL of PDF document (if the post is a carousel/document post)
        </ResponseField>

        <ResponseField name="profile" type="object" required>
          Information about the post author. All fields are always present.

          <Expandable title="Profile object">
            <ResponseField name="urn" type="string" required>
              Professional profile URN of the post author
            </ResponseField>

            <ResponseField name="name" type="string" required>
              Full name of the post author
            </ResponseField>

            <ResponseField name="headline" type="string" required>
              Professional headline of the post author
            </ResponseField>

            <ResponseField name="url" type="string" required>
              Professional profile URL of the post author
            </ResponseField>

            <ResponseField name="imageUrl" type="string" required>
              Profile picture URL of the post author
            </ResponseField>
          </Expandable>
        </ResponseField>
      </Expandable>
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="paginationToken" type="string">
  Token for fetching the next page of reactions. Only present when more reactions are available.
</ResponseField>

<ResponseField name="hasMore" type="boolean">
  Indicates whether there are more reactions to fetch.
</ResponseField>

## Example Request

<CodeGroup>
  ```bash cURL theme={null}
  curl -X GET "https://api.fetchin.io/api/v1/profile/reactions?profileUrlOrUrn=https://www.linkedin.com/in/williamhgates&count=5" \
    -H "X-API-Key: your-api-key-here"
  ```

  ```javascript JavaScript theme={null}
  const response = await fetch(
    'https://api.fetchin.io/api/v1/profile/reactions?profileUrlOrUrn=https://www.linkedin.com/in/williamhgates&count=5',
    {
      headers: {
        'X-API-Key': 'your-api-key-here'
      }
    }
  );

  const data = await response.json();
  console.log(data.reactions);
  ```

  ```python Python theme={null}
  import requests

  headers = {
      'X-API-Key': 'your-api-key-here'
  }

  params = {
      'profileUrlOrUrn': 'https://www.linkedin.com/in/williamhgates',
      'count': 5
  }

  response = requests.get(
      'https://api.fetchin.io/api/v1/profile/reactions',
      headers=headers,
      params=params
  )

  data = response.json()
  print(data['reactions'])
  ```

  ```php PHP theme={null}
  <?php

  $apiKey = 'your-api-key-here';
  $profileUrl = 'https://www.linkedin.com/in/williamhgates';
  $count = 5;

  $url = "https://api.fetchin.io/api/v1/profile/reactions?profileUrlOrUrn=" . urlencode($profileUrl) . "&count=" . $count;

  $ch = curl_init();
  curl_setopt($ch, CURLOPT_URL, $url);
  curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
  curl_setopt($ch, CURLOPT_HTTPHEADER, [
      'X-API-Key: ' . $apiKey
  ]);

  $response = curl_exec($ch);
  $data = json_decode($response, true);

  curl_close($ch);
  print_r($data['reactions']);
  ?>
  ```
</CodeGroup>

## Example Response

<ResponseExample>
  ```json 200 Success theme={null}
  {
    "reactions": [
      {
        "reactionType": "LIKE",
        "post": {
          "id": "urn:li:activity:7422911506511486976",
          "content": "One annoying discovery I made when I started selling Borumi is that refunds are not free...",
          "date": "2025-02-01T10:30:00Z",
          "reactionCount": 25,
          "commentCount": 11,
          "imageUrl": "https://media.licdn.com/dms/image/...",
          "videoUrl": null,
          "carouselPdfUrl": null,
          "profile": {
            "urn": "urn:li:fsd_profile:ACoAACHFUsoBILf",
            "name": "Federico Terzi",
            "headline": "Founder @ Borumi.com",
            "url": "https://www.linkedin.com/in/federico-terzi",
            "imageUrl": "https://media.licdn.com/dms/image/..."
          }
        }
      },
      {
        "reactionType": "EMPATHY",
        "post": {
          "id": "urn:li:activity:7409540219328344064",
          "content": "At 30, Thibaud Elziere was selling his company for 800M to Adobe...",
          "date": "2025-01-20T14:20:00Z",
          "reactionCount": 635,
          "commentCount": 59,
          "imageUrl": null,
          "videoUrl": null,
          "carouselPdfUrl": null,
          "profile": {
            "urn": "urn:li:fsd_profile:ACoAADGS3aIB50y",
            "name": "Guillaume Moubeche",
            "headline": "Founder @ lemlist",
            "url": "https://www.linkedin.com/in/guillaume-moubeche-a026541b2",
            "imageUrl": "https://media.licdn.com/dms/image/..."
          }
        }
      },
      {
        "reactionType": "ENTERTAINMENT",
        "post": {
          "id": "urn:li:activity:7402610232759058433",
          "content": "Friday Developers Fun. Explain to me Tech debt as I'm 5.",
          "date": "2025-01-05T09:00:00Z",
          "reactionCount": 4084,
          "commentCount": 78,
          "imageUrl": "https://media.licdn.com/dms/image/...",
          "videoUrl": null,
          "carouselPdfUrl": null,
          "profile": {
            "urn": "urn:li:fsd_profile:ACoAAAC60lcBKfZ",
            "name": "Dr Milan Milanovic",
            "headline": "Helping 400K+ engineers and leaders grow",
            "url": "https://www.linkedin.com/in/milanmilanovic",
            "imageUrl": "https://media.licdn.com/dms/image/..."
          }
        }
      }
    ],
    "paginationToken": "dXJuOmxpOmFjdGl2aXR5Ojc0MDI5Njk4NzAyODU1NjU5NTItMTc2NTAwNTU1NzUzOA==",
    "hasMore": true
  }
  ```

  ```json 400 Bad Request theme={null}
  {
    "error": "Missing profileUrlOrUrn parameter",
    "code": "MISSING_PARAMETER"
  }
  ```

  ```json 401 Unauthorized theme={null}
  {
    "error": "Invalid API key",
    "code": "INVALID_API_KEY"
  }
  ```

  ```json 404 Not Found theme={null}
  {
    "error": "LinkedIn profile not found",
    "code": "PROFILE_NOT_FOUND"
  }
  ```

  ```json 402 Payment Required theme={null}
  {
    "error": "Quota exceeded. Upgrade your plan or wait for renewal.",
    "code": "QUOTA_EXHAUSTED"
  }
  ```

  ```json 500 Internal Server Error theme={null}
  {
    "error": "Internal server error",
    "code": "INTERNAL_ERROR"
  }
  ```

  ```json 503 Service Unavailable theme={null}
  {
    "error": "Service temporarily unable to serve this request. Please retry.",
    "code": "SERVICE_UNAVAILABLE"
  }
  ```
</ResponseExample>

## Errors

See [Error Handling](/concepts/error-handling) for the full list of error codes and recommended handling.

* `400` `MISSING_PARAMETER` / `INVALID_URN`
* `401` `INVALID_API_KEY`
* `404` `PROFILE_NOT_FOUND`
* `402` `QUOTA_EXHAUSTED`
* `429` `RATE_LIMITED`
* `500` `INTERNAL_ERROR`
* `503` `SERVICE_UNAVAILABLE`

## Pagination

To fetch all reactions from a profile, use pagination:

1. Make an initial request without `paginationToken`
2. If `hasMore` is `true`, use the returned `paginationToken` in your next request
3. Continue until `hasMore` is `false`

```javascript theme={null}
async function fetchAllReactions(profileUrl) {
  const allReactions = [];
  let paginationToken = null;
  let hasMore = true;

  while (hasMore) {
    const params = new URLSearchParams({
      profileUrlOrUrn: profileUrl,
      count: '20'
    });
    if (paginationToken) {
      params.set('paginationToken', paginationToken);
    }

    const response = await fetch(
      `https://api.fetchin.io/api/v1/profile/reactions?${params}`,
      { headers: { 'X-API-Key': 'your-api-key-here' } }
    );

    const data = await response.json();
    allReactions.push(...data.reactions);
    paginationToken = data.paginationToken;
    hasMore = data.hasMore;
  }

  return allReactions;
}
```

## Reaction Types

| Value           | Platform Label | Description                   |
| --------------- | -------------- | ----------------------------- |
| `LIKE`          | Like           | Standard like reaction        |
| `EMPATHY`       | Love           | Heart/love reaction           |
| `ENTERTAINMENT` | Funny          | Laughing face reaction        |
| `INTEREST`      | Insightful     | Lightbulb/insightful reaction |
| `PRAISE`        | Celebrate      | Clapping/celebrate reaction   |
| `APPRECIATION`  | Support        | Hands/support reaction        |

## Notes

<Info>
  This endpoint consumes 1 credit from your monthly quota per API call, regardless of the `count` parameter value. Failed requests (errors) do not count against your quota.
</Info>

<Warning>
  Reactions are returned in reverse chronological order (most recent reactions first). The `post` object within each reaction has the same shape as items from `GET /api/v1/posts`, so you can reuse the same types in your client code.
</Warning>

<Tip>
  Use the `paginationToken` to efficiently paginate through a profile's reaction history without re-fetching already retrieved reactions.
</Tip>

## Use Cases

<CardGroup cols={2}>
  <Card title="Competitive intelligence" icon="chart-line">
    Monitor what content your competitors are engaging with
  </Card>

  <Card title="Interest analysis" icon="heart">
    Understand a prospect's interests based on the posts they react to
  </Card>

  <Card title="Content research" icon="magnifying-glass">
    Discover trending content in your industry by analyzing reactions of key influencers
  </Card>

  <Card title="Lead scoring" icon="star">
    Enrich lead profiles with engagement activity data
  </Card>
</CardGroup>


## OpenAPI

````yaml GET /api/v1/profile/reactions
openapi: 3.1.0
info:
  title: Fetchin API
  version: 1.0.0
  description: Public B2B data API for fetching posts and profile information
servers:
  - url: https://api.fetchin.io
    description: Production server
security:
  - ApiKeyAuth: []
paths:
  /api/v1/profile/reactions:
    get:
      summary: Get posts a profile has reacted to
      description: >-
        Fetch posts that a professional profile has reacted to (liked, loved,
        etc.) with the reaction type and full post details. The `post` object in
        each reaction has the same shape as items returned by `GET
        /api/v1/posts`.
      parameters:
        - name: profileUrlOrUrn
          in: query
          required: true
          description: >-
            The professional profile to fetch. Accepts a profile URN
            (recommended for consistency, since a profile's public identifier
            can change over time while the URN does not; example
            `urn:li:fsd_profile:ACoAAA8BYqEBCGLg_vT_ca6mMEqkpp9nVffJ3hc`), a
            public identifier/slug (also fine; example `williamhgates`), or a
            full profile URL (example
            `https://www.linkedin.com/in/williamhgates`; a trailing slash is
            ignored). The slug is the last path segment of a profile URL, so
            pass just the slug, not the `/in/` prefix.
          schema:
            type: string
            example: urn:li:fsd_profile:ACoAAA8BYqEBCGLg_vT_ca6mMEqkpp9nVffJ3hc
        - name: count
          in: query
          required: false
          description: 'Number of reactions to fetch (default: 10)'
          schema:
            type: integer
            minimum: 1
            maximum: 50
            default: 10
        - name: start
          in: query
          required: false
          description: 'Offset for pagination (default: 0)'
          schema:
            type: integer
            minimum: 0
            default: 0
        - name: paginationToken
          in: query
          required: false
          description: >-
            Token for fetching the next page of reactions. Use the
            paginationToken from the previous response.
          schema:
            type: string
      responses:
        '200':
          description: Successfully fetched profile reactions
          content:
            application/json:
              schema:
                type: object
                properties:
                  reactions:
                    type: array
                    items:
                      type: object
                      properties:
                        reactionType:
                          type: string
                          enum:
                            - LIKE
                            - EMPATHY
                            - ENTERTAINMENT
                            - INTEREST
                            - PRAISE
                            - APPRECIATION
                          description: >-
                            The type of reaction: LIKE (Like), EMPATHY (Love),
                            ENTERTAINMENT (Funny), INTEREST (Insightful), PRAISE
                            (Celebrate), APPRECIATION (Support)
                        post:
                          type: object
                          description: >-
                            The post that was reacted to. Same shape as items
                            from GET /api/v1/posts.
                          properties:
                            id:
                              type: string
                              example: urn:li:activity:1234567890
                              description: >-
                                Activity URN. References the post in the
                                `urn:li:activity:*` namespace.
                            shareUrn:
                              type: string
                              example: urn:li:share:7123456789012345678
                              description: >-
                                Share URN. References the same post as `id` but
                                in the `urn:li:share:*` namespace.
                            content:
                              type: string
                              example: This is a post content...
                            date:
                              type: string
                              format: date-time
                            reactionCount:
                              type: integer
                            commentCount:
                              type: integer
                            sharesCount:
                              type: integer
                              description: Number of times the post was reshared.
                            imageUrl:
                              type: string
                            videoUrl:
                              type: string
                            carouselPdfUrl:
                              type: string
                            profile:
                              type: object
                              required:
                                - urn
                                - name
                                - headline
                                - url
                                - imageUrl
                              properties:
                                urn:
                                  type: string
                                  example: urn:li:fsd_profile:ACoAAABCDEF
                                name:
                                  type: string
                                  example: John Doe
                                headline:
                                  type: string
                                  example: Software Engineer at Tech Company
                                url:
                                  type: string
                                  example: https://www.linkedin.com/in/johndoe
                                imageUrl:
                                  type: string
                                  example: https://media.licdn.com/dms/image/...
                  paginationToken:
                    type: string
                    description: Token for fetching the next page
                  hasMore:
                    type: boolean
                    description: Whether more reactions are available
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '402':
          $ref: '#/components/responses/PaymentRequired'
        '404':
          $ref: '#/components/responses/NotFound'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
components:
  responses:
    BadRequest:
      description: Bad request - a required parameter is missing or a value is invalid.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          examples:
            missingParameter:
              value:
                error: Missing profileUrlOrUrn parameter
                code: MISSING_PARAMETER
            invalidParameter:
              value:
                error: limit must be a number between 1 and 100
                code: INVALID_PARAMETER
            invalidUrn:
              value:
                error: 'Invalid URN format: foo'
                code: INVALID_URN
    Unauthorized:
      description: Unauthorized - the X-API-Key header is missing or invalid.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          examples:
            missingApiKey:
              value:
                error: Missing API key. Include X-API-Key header.
                code: UNAUTHENTICATED
            invalidApiKey:
              value:
                error: Invalid API key
                code: INVALID_API_KEY
    PaymentRequired:
      description: >-
        Payment required - your monthly credit quota is exhausted
        (QUOTA_EXHAUSTED). Upgrade your plan or wait for renewal; retrying will
        not help and no Retry-After is sent. Distinct from the per-second rate
        limit, which is a 429 (RATE_LIMITED).
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          examples:
            quotaExhausted:
              value:
                error: Quota exceeded. Upgrade your plan or wait for renewal.
                code: QUOTA_EXHAUSTED
    NotFound:
      description: >-
        Not found - the request was served successfully but the requested
        professional entity does not exist.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          examples:
            profileNotFound:
              value:
                error: LinkedIn profile not found
                code: PROFILE_NOT_FOUND
            postNotFound:
              value:
                error: Unable to find post from url
                code: POST_NOT_FOUND
            companyNotFound:
              value:
                error: Unable to find company slug from urn
                code: COMPANY_NOT_FOUND
    TooManyRequests:
      description: >-
        Too many requests - your per-second rate limit (RATE_LIMITED) was
        exceeded. Back off and retry, honoring the Retry-After header. (Monthly
        credit quota exhaustion is a separate 402 PaymentRequired /
        QUOTA_EXHAUSTED.)
      headers:
        Retry-After:
          description: Number of seconds to wait before retrying the request.
          schema:
            type: integer
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          examples:
            rateLimited:
              value:
                error: Rate limit exceeded. Try again later.
                code: RATE_LIMITED
    InternalError:
      description: >-
        Internal server error - an unexpected error occurred in our API. Safe to
        retry; contact support if it persists.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          examples:
            internalError:
              value:
                error: Internal server error
                code: INTERNAL_ERROR
    ServiceUnavailable:
      description: >-
        Service unavailable - our API is temporarily unable to serve this
        request (capacity exhausted or overloaded). This is on our side, not
        yours and not an upstream service outage. Retry with backoff, honoring
        the Retry-After header.
      headers:
        Retry-After:
          description: Number of seconds to wait before retrying the request.
          schema:
            type: integer
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          examples:
            serviceUnavailable:
              value:
                error: >-
                  Service temporarily unable to serve this request. Please
                  retry.
                code: SERVICE_UNAVAILABLE
  schemas:
    Error:
      type: object
      required:
        - error
        - code
      properties:
        error:
          type: string
          description: >-
            Human-readable description of what went wrong. For display/logging;
            do not branch on this string.
        code:
          type: string
          enum:
            - MISSING_PARAMETER
            - INVALID_PARAMETER
            - INVALID_URN
            - UNAUTHENTICATED
            - INVALID_API_KEY
            - FORBIDDEN
            - NOT_FOUND
            - PROFILE_NOT_FOUND
            - POST_NOT_FOUND
            - COMPANY_NOT_FOUND
            - RATE_LIMITED
            - QUOTA_EXHAUSTED
            - INTERNAL_ERROR
            - UPSTREAM_ERROR
            - SERVICE_UNAVAILABLE
            - UPSTREAM_TIMEOUT
          description: >-
            Stable, machine-readable error code. Branch your integration on this
            value, not on the HTTP status alone or the message text.
        details:
          type: object
          additionalProperties: true
          description: Optional structured context (e.g. creditsNeeded on quota errors).
  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      in: header
      name: X-API-Key

````