---
title: "Call analytics.linkedin_page_analytics"
method: POST
path: "/api/v1/tools/analytics.linkedin_page_analytics"
tags: ["analytics"]
---

# Call analytics.linkedin_page_analytics

`POST /api/v1/tools/analytics.linkedin_page_analytics`

## Request

- Base URL: `https://app.goosybear.ai`
- URL: `https://app.goosybear.ai/api/v1/tools/analytics.linkedin_page_analytics`
- Auth: HTTP bearer

'how is our LinkedIn page doing?', 'who follows us on LinkedIn?' — read this workspace's LinkedIn company-page statistics over the grant the workspace connected: followers and their demographics, page views and clicks, and organic post engagement, optionally over a window of days. The answer names the source it read; when LinkedIn is reached only through the workspace's CRM connection it says so and returns no LinkedIn figures. It changes nothing. Not for the cross-platform social totals — that is `analytics.query_metrics`.

Every result names the workspace it ran in. Say which workspace the answer is about. When the account has more than one workspace and none is selected, this tool refuses with `workspace_ambiguous` and lists the choices — offer them, never pick one.

## Headers

- `x-request-id` string

## Request body

- object
  - `organization_urn` string: The company page to read, as its LinkedIn page URN — the urn:li:… identifier carried on the connected grant. Omit when the connection administers exactly one page — it is then chosen automatically. If several are administered, this is required and the answer lists them.
  - `days` integer: Read a trailing window of this many days instead of lifetime totals. OMIT for the lifetime read, which is the only one that carries follower DEMOGRAPHICS (industry, seniority, function, geography) — LinkedIn drops every demographic facet from a time-bound follower query, so a window and a breakdown are two different questions.
  - `include` string[]: Which sections to read: followers (count + demographics or gains), page_views (views and custom-button clicks), shares (organic impressions, clicks, reactions, comments, engagement rate). Omit for all three. Each section is a separate LinkedIn call, so narrowing this spends less of the page's rate budget.
  - `workspace` string: Which workspace to run in — its slug. Omit to use your default. With more than one reachable workspace and no default, the call is refused and the choices are listed.

## Response `200`

The call was admitted and dispatched. `ok` says whether the tool succeeded — a refusal the tool itself produced is still a 200, exactly as it is a successful JSON-RPC result over MCP.

- union
  - object: The tool ran and answered.
    - `ok` true, required
    - `source` 'linkedin_cmapi' | 'ghl' | 'none', required: Which rail these numbers came from. linkedin_cmapi = LinkedIn's own page analytics; ghl = the workspace posts through GoHighLevel, which reports no LinkedIn-specific numbers; none = neither is connected.
    - `provenance` 'platform_reported', nullable, required: The trust class, on the metric dictionary's own axis. Both connected rails are platform_reported — the platform's number, subject to the platform's methodology. Null when there is no number.
    - `source_note` string, required: The plain-language sentence to tell the operator about where these numbers come from. Say it — never paraphrase it into a stronger claim.
    - `connect_path` string, nullable, required: Where the operator connects LinkedIn page analytics directly, when that would change the answer. Null when already connected on the direct rail.
    - `read_elsewhere` object, nullable, required: On the ghl source ONLY: the cross-platform social metric keys LinkedIn activity is counted inside, and the tool/page that reads them. There is no LinkedIn breakdown to give — offer these instead of guessing one.
      - `metric_keys` string[], required
      - `tool` string, required
      - `path` string, required
    - `organization_urn` string, nullable, required: The company page these numbers are for. Null on the ghl and none sources, which have no page-level read.
    - `administered_organizations` string[], required: Every company page this connection may read. More than one and organization_urn is required.
    - `window` object, required: What was ACTUALLY read — not what was asked for. The two differ whenever LinkedIn's follower publication lag applies.
      - `kind` 'lifetime' | 'time_bound', required: lifetime = no time restriction, and the ONLY kind that carries follower demographics. time_bound = a trailing window.
      - `days` number, nullable, required: The window length asked for. Null on a lifetime read.
      - `granularity` 'DAY' | 'MONTH', nullable, required: The interval each row covers. Null on a lifetime read. LinkedIn's page statistics accept DAY or MONTH only.
      - `follower_window_ends_days_ago` number, nullable, required: LinkedIn publishes time-bound follower data only up to this many days before today, so the follower series legitimately stops short of the rest of the window. Null when no follower series was read.
      - `follower_start_ms` number, nullable, required: The ACTUAL start of the follower interval sent to LinkedIn, epoch ms. Report this rather than inferring it from `days` — the two differ whenever the publication lag applies.
      - `follower_end_ms` number, nullable, required: The ACTUAL end of the follower interval sent to LinkedIn, epoch ms. Null when no follower series was read.
    - `total_followers` number, nullable, required: The page's total follower count, from LinkedIn's networkSizes read. It is a SEPARATE call from the follower statistics and carries no publication lag. Null when the followers section was not read or its call failed.
    - `follower_demographics` object, nullable, required: Lifetime read only. Bucket keys are LinkedIn URNs or enums, and each count rolls organic AND paid followers together — LinkedIn's own instruction, not an approximation. Each facet reports its FULL bucket count alongside the top few it carries; see `truncated`.
      - `by_association_type` object, required
        - `buckets` object[], required: The most-followed buckets, descending.
          - `key` string, required: The facet value — a LinkedIn URN or enum, e.g. urn:li:industry:4.
          - `follower_count` number, required: Organic AND paid followers in this bucket, rolled together.
        - `total_buckets` number, required: How many buckets LinkedIn returned for this facet in total.
        - `truncated` boolean, required: True when buckets is a SUBSET. Never describe a truncated facet as the complete breakdown.
      - `by_country` object, required
        - `buckets` object[], required: The most-followed buckets, descending.
          - `key` string, required: The facet value — a LinkedIn URN or enum, e.g. urn:li:industry:4.
          - `follower_count` number, required: Organic AND paid followers in this bucket, rolled together.
        - `total_buckets` number, required: How many buckets LinkedIn returned for this facet in total.
        - `truncated` boolean, required: True when buckets is a SUBSET. Never describe a truncated facet as the complete breakdown.
      - `by_function` object, required
        - `buckets` object[], required: The most-followed buckets, descending.
          - `key` string, required: The facet value — a LinkedIn URN or enum, e.g. urn:li:industry:4.
          - `follower_count` number, required: Organic AND paid followers in this bucket, rolled together.
        - `total_buckets` number, required: How many buckets LinkedIn returned for this facet in total.
        - `truncated` boolean, required: True when buckets is a SUBSET. Never describe a truncated facet as the complete breakdown.
      - `by_industry` object, required
        - `buckets` object[], required: The most-followed buckets, descending.
          - `key` string, required: The facet value — a LinkedIn URN or enum, e.g. urn:li:industry:4.
          - `follower_count` number, required: Organic AND paid followers in this bucket, rolled together.
        - `total_buckets` number, required: How many buckets LinkedIn returned for this facet in total.
        - `truncated` boolean, required: True when buckets is a SUBSET. Never describe a truncated facet as the complete breakdown.
      - `by_geo` object, required
        - `buckets` object[], required: The most-followed buckets, descending.
          - `key` string, required: The facet value — a LinkedIn URN or enum, e.g. urn:li:industry:4.
          - `follower_count` number, required: Organic AND paid followers in this bucket, rolled together.
        - `total_buckets` number, required: How many buckets LinkedIn returned for this facet in total.
        - `truncated` boolean, required: True when buckets is a SUBSET. Never describe a truncated facet as the complete breakdown.
      - `by_seniority` object, required
        - `buckets` object[], required: The most-followed buckets, descending.
          - `key` string, required: The facet value — a LinkedIn URN or enum, e.g. urn:li:industry:4.
          - `follower_count` number, required: Organic AND paid followers in this bucket, rolled together.
        - `total_buckets` number, required: How many buckets LinkedIn returned for this facet in total.
        - `truncated` boolean, required: True when buckets is a SUBSET. Never describe a truncated facet as the complete breakdown.
      - `by_staff_count_range` object, required
        - `buckets` object[], required: The most-followed buckets, descending.
          - `key` string, required: The facet value — a LinkedIn URN or enum, e.g. urn:li:industry:4.
          - `follower_count` number, required: Organic AND paid followers in this bucket, rolled together.
        - `total_buckets` number, required: How many buckets LinkedIn returned for this facet in total.
        - `truncated` boolean, required: True when buckets is a SUBSET. Never describe a truncated facet as the complete breakdown.
    - `follower_gains` object[], nullable, required: Time-bound read only. GAINS per interval, not running totals.
      - `start_ms` number, required
      - `end_ms` number, required
      - `organic_follower_gain` number, required
      - `paid_follower_gain` number, required
    - `page_views` object[], nullable, required: all_page_views counts every page tab across desktop and mobile; overview_page_views counts the overview tab only, so all_* is legitimately the larger number.
      - `start_ms` number, nullable, required
      - `end_ms` number, nullable, required
      - `all_page_views` number, required
      - `all_desktop_page_views` number, required
      - `all_mobile_page_views` number, required
      - `overview_page_views` number, required
      - `custom_button_clicks` number, required
    - `shares` object[], nullable, required: ORGANIC only — sponsored activity is not counted here and lives on the ads rail. like_count can be negative when a member unlikes a sponsored share; that is LinkedIn's number, not a bug.
      - `start_ms` number, nullable, required
      - `end_ms` number, nullable, required
      - `impression_count` number, required
      - `unique_impressions_count` number, required
      - `click_count` number, required
      - `like_count` number, required
      - `comment_count` number, required
      - `share_count` number, required
      - `engagement` number, required
    - `unavailable` object[], required: Sections that were asked for and could not be read, each with why. A section listed here has NO number — never report it as zero.
      - `section` string, required
      - `reason` string, required
    - `workspace` string, required: The slug of the workspace this call ran in.
    - `working_in` object, required: Which workspace this call ran in, and how that was decided. Present on every workspace-scoped result.
      - `label` string, required: The chip words — e.g. "working in: Acme Main".
      - `note` string, required: Why this workspace — e.g. "your default", "this call only".
      - `workspace` string, required: The resolved workspace's slug.
      - `source` 'call-override' | 'key-pin' | 'stored-default' | 'sole-reachable', required: Which rung of the R7 precedence resolved the workspace.
  - ToolRefusal: A call that was admitted and dispatched, and did not succeed.
    - `ok` false, required
    - `code` string, required: The typed reason — e.g. `workspace_ambiguous`, `invalid_arguments`, or the tool's own failure code.
    - `message` string, required: A sentence a person can act on.
    - `workspaces` string[]: On a workspace refusal: the slugs this key may pass as `workspace`.
    - `issues` object[]: On `invalid_arguments`: which fields failed, and why.
      - `path` string, required
      - `message` string, required
    - `path` string: On an authoring refusal: where in your call's input it points, e.g. `steps.<key>.params.<field>`.
    - `fix` string: On an authoring refusal: the change to your call that would pass.
    - `instruction` string: On an authoring refusal: what to do next with it.

## Other responses

- `400`: The request could not be used: the body is present but not a JSON object (`tenant_api.malformed_body`); it is a top-level array carrying more messages than this endpoint accepts (`tenant_mcp.batch_too_large`); or the `Idempotency-Key` header is malformed (`tenant_api.idempotency_key_invalid`), disagrees with the body's `idempotency_key` (`tenant_api.idempotency_key_conflict`), or was sent to an action that cannot replay a retry (`tenant_api.idempotency_unsupported`). Nothing ran.
- `401`: No bearer credential, or one that did not resolve. Deliberately ONE undifferentiated answer for absent / unknown / revoked / expired, so the endpoint is never an oracle over the key space.
- `403`: The credential is good but the surface is not open to it — the platform or account API switch is off, or the holder lacks the `api.access` capability. The `code` says which.
- `404`: No such tool. The body names no tool and is identical for every unrecognised name.
- `429`: Over this key's per-minute cap. Carries `Retry-After` and `error.retry_after_seconds`.

---

[API](https://skmtc.dev/goosybear/apis/goosy-bear-api.md) · [All operations](https://skmtc.dev/goosybear/apis/goosy-bear-api/llms.txt) · [OpenAPI document](https://skmtc.dev/goosybear/apis/goosy-bear-api/revisions/6d82fb124064?raw)
