> ## 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 Post Engagement

> Fetch a post's comments and reactions in a single call

## Endpoint

```
GET /api/v1/post/engagement
```

Returns both the **comments** and the **reactions** of a professional post in one
request. Use this instead of calling `/post/comments` and `/post/reactions`
separately when you need both.

<Info>
  This endpoint bills **2 credits** and counts as **2 units** against your
  per-second rate limit. It is **all-or-nothing**: if either half cannot be
  fetched, the whole request returns an error and **0 credits** are charged.
  Because it costs 2 rate-limit units, your plan's per-second limit must be at
  least 2 to call it.
</Info>

## Authentication

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

## Parameters

<ParamField query="postUrlOrUrn" type="string" required>
  Professional post URL or URN.

  Examples:

  * `https://www.linkedin.com/posts/username_some-post-slug-1234567890-abcd`
  * `urn:li:activity:7287782484287606784`
  * `urn:li:ugcPost:7287782484287606784`
</ParamField>

<ParamField query="commentCount" type="integer" default="100">
  Number of comments to fetch (1–100).
</ParamField>

<ParamField query="commentStart" type="integer" default="0">
  Comments offset (kept for parity; comments primarily paginate by token).
</ParamField>

<ParamField query="commentPaginationToken" type="string">
  Token from a previous response used to fetch the next page of comments.
</ParamField>

<ParamField query="reactionCount" type="integer" default="100">
  Number of reactions to fetch (1–100).
</ParamField>

<ParamField query="reactionStart" type="integer" default="0">
  Reactions offset for pagination.
</ParamField>

## Response

<ResponseField name="post" type="string">
  The resolved post identifier you passed in.
</ResponseField>

<ResponseField name="comments" type="array">
  Array of comments (same object shape as [Get Post Comments](/api-reference/endpoint/get-post-comments)).
</ResponseField>

<ResponseField name="commentsPaginationToken" type="string">
  Token to fetch the next page of comments. Absent when there are no more.
</ResponseField>

<ResponseField name="commentsHasMore" type="boolean">
  Whether more comments are available.
</ResponseField>

<ResponseField name="reactions" type="array">
  Array of reactions (same object shape as [Get Post Reactions](/api-reference/endpoint/get-post-reactions)).
</ResponseField>

<ResponseField name="reactionsHasMore" type="boolean">
  Whether more reactions are available.
</ResponseField>

## Example Request

<CodeGroup>
  ```bash cURL theme={null}
  curl -X GET "https://api.fetchin.io/api/v1/post/engagement?postUrlOrUrn=urn:li:activity:7287782484287606784" \
    -H "X-API-Key: your-api-key-here"
  ```

  ```javascript JavaScript theme={null}
  const response = await fetch(
    'https://api.fetchin.io/api/v1/post/engagement?postUrlOrUrn=urn:li:activity:7287782484287606784',
    { headers: { 'X-API-Key': 'your-api-key-here' } }
  );

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

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

  response = requests.get(
      'https://api.fetchin.io/api/v1/post/engagement',
      headers={'X-API-Key': 'your-api-key-here'},
      params={'postUrlOrUrn': 'urn:li:activity:7287782484287606784'},
  )

  print(response.json())
  ```
</CodeGroup>

## Example Response

<ResponseExample>
  ```json 200 Success theme={null}
  {
    "post": "urn:li:activity:7287782484287606784",
    "comments": [
      {
        "urn": "urn:li:comment:(ugcPost:7287782484287606784,7287957733851484162)",
        "text": "Great post!",
        "createdAt": "2024-01-22T14:22:07.458Z",
        "reactionCount": 5,
        "author": {
          "id": "urn:li:fsd_profile:ACoAABCDEFG",
          "name": "Jane Doe",
          "headline": "Software Engineer",
          "profileUrl": "https://www.linkedin.com/in/janedoe"
        },
        "replies": []
      }
    ],
    "commentsPaginationToken": "MTAtMTcwNjAwMDAwMDAwMA==",
    "commentsHasMore": true,
    "reactions": [
      {
        "reactionType": "LIKE",
        "actor": {
          "urn": "urn:li:fsd_profile:ACoAABBfDXAB9eK9V6vEHbzfQXZ-wcjke_QuT7g",
          "name": "Kevin Piacentini",
          "headline": "Lead Engineer",
          "profileUrl": "https://www.linkedin.com/in/ACoAABBfDXAB9eK9V6vEHbzfQXZ-wcjke_QuT7g",
          "profilePictureUrl": "https://media.licdn.com/dms/image/..."
        }
      }
    ],
    "reactionsHasMore": false
  }
  ```

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

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

  ```json 404 Not Found theme={null}
  {
    "error": "Unable to find post from url",
    "code": "POST_NOT_FOUND"
  }
  ```

  ```json 429 Too Many Requests theme={null}
  {
    "error": "This endpoint costs 2 RPS units but your plan allows 1 request(s) per second. Upgrade your plan to use it.",
    "code": "RATE_LIMITED"
  }
  ```

  ```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` — `POST_NOT_FOUND`
* `402` — `QUOTA_EXHAUSTED`
* `429` — `RATE_LIMITED` (also returned when the endpoint's 2-unit cost exceeds your per-second limit)
* `500` — `INTERNAL_ERROR`
* `503` — `SERVICE_UNAVAILABLE`

## Pagination

The two lists paginate independently:

* **Comments** paginate by token: pass `commentPaginationToken` from the previous
  response, and stop when `commentsHasMore` is `false`.
* **Reactions** paginate by offset: increment `reactionStart` by `reactionCount`,
  and stop when `reactionsHasMore` is `false`.

Every call to `/post/engagement` bills 2 credits and 2 rate-limit units, so if you
only need to deep-paginate one of the two lists, use the dedicated
`/post/comments` or `/post/reactions` endpoint (1 credit each) instead.

## Notes

<Info>
  Billing is all-or-nothing: 2 credits when both lists are returned, 0 credits if
  the request errors. There is no partial result.
</Info>


## OpenAPI

````yaml GET /api/v1/post/engagement
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/post/engagement:
    get:
      summary: Get Post Engagement
      description: >-
        Fetch a post's comments and reactions in a single call. Bills 2 credits
        and 2 rate-limit units; all-or-nothing (0 credits on error).
      parameters:
        - name: postUrlOrUrn
          in: query
          required: true
          schema:
            type: string
          description: Professional post URL or URN
        - name: commentCount
          in: query
          required: false
          schema:
            type: integer
            default: 100
          description: Number of comments to fetch (1-100)
        - name: commentStart
          in: query
          required: false
          schema:
            type: integer
            default: 0
          description: Comments offset
        - name: commentPaginationToken
          in: query
          required: false
          schema:
            type: string
          description: Token for the next page of comments
        - name: reactionCount
          in: query
          required: false
          schema:
            type: integer
            default: 100
          description: Number of reactions to fetch (1-100)
        - name: reactionStart
          in: query
          required: false
          schema:
            type: integer
            default: 0
          description: Reactions offset
      responses:
        '200':
          description: Combined comments and reactions
          content:
            application/json:
              schema:
                type: object
                properties:
                  post:
                    type: string
                    description: The resolved post identifier
                  comments:
                    type: array
                    items:
                      type: object
                    description: Comments (same shape as GET /post/comments)
                  commentsPaginationToken:
                    type: string
                    description: Token for the next page of comments (absent when none)
                  commentsHasMore:
                    type: boolean
                  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)
                        actor:
                          type: object
                          required:
                            - urn
                            - name
                            - headline
                            - profileUrl
                            - profilePictureUrl
                          properties:
                            urn:
                              type: string
                              example: urn:li:fsd_profile:ACoAAABCDEF
                            name:
                              type: string
                              example: Jane Doe
                            headline:
                              type: string
                              example: Software Engineer at Tech Company
                            profileUrl:
                              type: string
                              example: https://www.linkedin.com/in/ACoAAABCDEF
                            profilePictureUrl:
                              type: string
                              example: https://media.licdn.com/dms/image/...
                  reactionsHasMore:
                    type: boolean
        '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

````