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

# Call analytics.linkedin_page_analytics

> '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.



## OpenAPI

````yaml /openapi.json post /api/v1/tools/analytics.linkedin_page_analytics
openapi: 3.1.0
info:
  title: Goosy Bear API
  version: 1.0.0-beta
  summary: Manage workspace content, projects, Data tables, Pages, library and credits.
  description: >-
    BETA. This API is in beta: paths, request shapes and response envelopes may
    change, and every response carries an `x-goosy-api: beta` header for as long
    as that is true. A change is additive, or it is deprecated first: a response
    to a call that uses a deprecated feature carries `Deprecation` and `Sunset`
    headers, and nothing is removed until at least 90 days after its
    deprecation. Pin the OpenAPI document you generated against and re-generate
    when it changes.
servers:
  - url: https://app.goosybear.ai
    description: Production
security:
  - tenantApiKey: []
paths:
  /api/v1/tools/analytics.linkedin_page_analytics:
    post:
      tags:
        - analytics
      summary: Call analytics.linkedin_page_analytics
      description: >-
        '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.
      operationId: call_analytics_linkedin_page_analytics
      parameters:
        - name: x-request-id
          in: header
          required: false
          description: >-
            Your own id for this request, echoed back and recorded on the audit
            trail. 1–128 characters from `A–Z a–z 0–9 . _ : -`, starting with a
            letter or digit; anything else is replaced by a generated id.
          schema:
            type: string
            maxLength: 128
      requestBody:
        required: false
        content:
          application/json:
            schema:
              type: object
              properties:
                organization_urn:
                  type: string
                  description: >-
                    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:
                  type: integer
                  minimum: 1
                  maximum: 90
                  description: >-
                    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:
                  type: array
                  items:
                    type: string
                    enum:
                      - followers
                      - page_views
                      - shares
                  minItems: 1
                  description: >-
                    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:
                  type: string
                  minLength: 1
                  description: >-
                    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.
              additionalProperties: false
      responses:
        '200':
          description: >-
            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.
          headers:
            x-goosy-api:
              description: Present while this API is in beta; the value is `beta`.
              schema:
                type: string
                const: beta
            x-request-id:
              description: >-
                This request's id: the `x-request-id` you sent when it was well
                formed, otherwise one generated for you. Quote it to support; it
                is recorded on every audit row the call wrote.
              schema:
                type: string
            RateLimit-Limit:
              description: Requests this key may make in a rolling minute.
              schema:
                type: integer
                minimum: 1
            RateLimit-Remaining:
              description: Requests left in the current rolling minute.
              schema:
                type: integer
                minimum: 0
            RateLimit-Reset:
              description: Whole seconds until the window frees more requests.
              schema:
                type: integer
                minimum: 1
            x-goosy-tool-error:
              description: >-
                `true` when a boundary step refused the call — workspace
                resolution failed or could not be read. A tool that ran and
                returned its own typed `ok: false` reports `false` here.
                **Branch on `ok` in the body for the outcome; this header is the
                transport-level hint.**
              schema:
                type: string
                enum:
                  - 'true'
                  - 'false'
          content:
            application/json:
              schema:
                oneOf:
                  - type: object
                    description: The tool ran and answered.
                    properties:
                      ok:
                        type: boolean
                        const: true
                      source:
                        type: string
                        enum:
                          - linkedin_cmapi
                          - ghl
                          - none
                        description: >-
                          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:
                        anyOf:
                          - type: string
                            enum:
                              - platform_reported
                          - type: 'null'
                        description: >-
                          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:
                        type: string
                        description: >-
                          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:
                        type:
                          - string
                          - 'null'
                        description: >-
                          Where the operator connects LinkedIn page analytics
                          directly, when that would change the answer. Null when
                          already connected on the direct rail.
                      read_elsewhere:
                        anyOf:
                          - type: object
                            properties:
                              metric_keys:
                                type: array
                                items:
                                  type: string
                              tool:
                                type: string
                              path:
                                type: string
                            required:
                              - metric_keys
                              - tool
                              - path
                            additionalProperties: false
                          - type: 'null'
                        description: >-
                          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.
                      organization_urn:
                        type:
                          - string
                          - 'null'
                        description: >-
                          The company page these numbers are for. Null on the
                          ghl and none sources, which have no page-level read.
                      administered_organizations:
                        type: array
                        items:
                          type: string
                        description: >-
                          Every company page this connection may read. More than
                          one and organization_urn is required.
                      window:
                        type: object
                        properties:
                          kind:
                            type: string
                            enum:
                              - lifetime
                              - time_bound
                            description: >-
                              lifetime = no time restriction, and the ONLY kind
                              that carries follower demographics. time_bound = a
                              trailing window.
                          days:
                            type:
                              - number
                              - 'null'
                            description: >-
                              The window length asked for. Null on a lifetime
                              read.
                          granularity:
                            anyOf:
                              - type: string
                                enum:
                                  - DAY
                                  - MONTH
                              - type: 'null'
                            description: >-
                              The interval each row covers. Null on a lifetime
                              read. LinkedIn's page statistics accept DAY or
                              MONTH only.
                          follower_window_ends_days_ago:
                            type:
                              - number
                              - 'null'
                            description: >-
                              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:
                            type:
                              - number
                              - 'null'
                            description: >-
                              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:
                            type:
                              - number
                              - 'null'
                            description: >-
                              The ACTUAL end of the follower interval sent to
                              LinkedIn, epoch ms. Null when no follower series
                              was read.
                        required:
                          - kind
                          - days
                          - granularity
                          - follower_window_ends_days_ago
                          - follower_start_ms
                          - follower_end_ms
                        additionalProperties: false
                        description: >-
                          What was ACTUALLY read — not what was asked for. The
                          two differ whenever LinkedIn's follower publication
                          lag applies.
                      total_followers:
                        type:
                          - number
                          - 'null'
                        description: >-
                          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:
                        anyOf:
                          - type: object
                            properties:
                              by_association_type:
                                type: object
                                properties:
                                  buckets:
                                    type: array
                                    items:
                                      type: object
                                      properties:
                                        key:
                                          type: string
                                          description: >-
                                            The facet value — a LinkedIn URN or
                                            enum, e.g. urn:li:industry:4.
                                        follower_count:
                                          type: number
                                          description: >-
                                            Organic AND paid followers in this
                                            bucket, rolled together.
                                      required:
                                        - key
                                        - follower_count
                                      additionalProperties: false
                                    description: The most-followed buckets, descending.
                                  total_buckets:
                                    type: number
                                    description: >-
                                      How many buckets LinkedIn returned for
                                      this facet in total.
                                  truncated:
                                    type: boolean
                                    description: >-
                                      True when buckets is a SUBSET. Never
                                      describe a truncated facet as the complete
                                      breakdown.
                                required:
                                  - buckets
                                  - total_buckets
                                  - truncated
                                additionalProperties: false
                              by_country:
                                type: object
                                properties:
                                  buckets:
                                    type: array
                                    items:
                                      type: object
                                      properties:
                                        key:
                                          type: string
                                          description: >-
                                            The facet value — a LinkedIn URN or
                                            enum, e.g. urn:li:industry:4.
                                        follower_count:
                                          type: number
                                          description: >-
                                            Organic AND paid followers in this
                                            bucket, rolled together.
                                      required:
                                        - key
                                        - follower_count
                                      additionalProperties: false
                                    description: The most-followed buckets, descending.
                                  total_buckets:
                                    type: number
                                    description: >-
                                      How many buckets LinkedIn returned for
                                      this facet in total.
                                  truncated:
                                    type: boolean
                                    description: >-
                                      True when buckets is a SUBSET. Never
                                      describe a truncated facet as the complete
                                      breakdown.
                                required:
                                  - buckets
                                  - total_buckets
                                  - truncated
                                additionalProperties: false
                              by_function:
                                type: object
                                properties:
                                  buckets:
                                    type: array
                                    items:
                                      type: object
                                      properties:
                                        key:
                                          type: string
                                          description: >-
                                            The facet value — a LinkedIn URN or
                                            enum, e.g. urn:li:industry:4.
                                        follower_count:
                                          type: number
                                          description: >-
                                            Organic AND paid followers in this
                                            bucket, rolled together.
                                      required:
                                        - key
                                        - follower_count
                                      additionalProperties: false
                                    description: The most-followed buckets, descending.
                                  total_buckets:
                                    type: number
                                    description: >-
                                      How many buckets LinkedIn returned for
                                      this facet in total.
                                  truncated:
                                    type: boolean
                                    description: >-
                                      True when buckets is a SUBSET. Never
                                      describe a truncated facet as the complete
                                      breakdown.
                                required:
                                  - buckets
                                  - total_buckets
                                  - truncated
                                additionalProperties: false
                              by_industry:
                                type: object
                                properties:
                                  buckets:
                                    type: array
                                    items:
                                      type: object
                                      properties:
                                        key:
                                          type: string
                                          description: >-
                                            The facet value — a LinkedIn URN or
                                            enum, e.g. urn:li:industry:4.
                                        follower_count:
                                          type: number
                                          description: >-
                                            Organic AND paid followers in this
                                            bucket, rolled together.
                                      required:
                                        - key
                                        - follower_count
                                      additionalProperties: false
                                    description: The most-followed buckets, descending.
                                  total_buckets:
                                    type: number
                                    description: >-
                                      How many buckets LinkedIn returned for
                                      this facet in total.
                                  truncated:
                                    type: boolean
                                    description: >-
                                      True when buckets is a SUBSET. Never
                                      describe a truncated facet as the complete
                                      breakdown.
                                required:
                                  - buckets
                                  - total_buckets
                                  - truncated
                                additionalProperties: false
                              by_geo:
                                type: object
                                properties:
                                  buckets:
                                    type: array
                                    items:
                                      type: object
                                      properties:
                                        key:
                                          type: string
                                          description: >-
                                            The facet value — a LinkedIn URN or
                                            enum, e.g. urn:li:industry:4.
                                        follower_count:
                                          type: number
                                          description: >-
                                            Organic AND paid followers in this
                                            bucket, rolled together.
                                      required:
                                        - key
                                        - follower_count
                                      additionalProperties: false
                                    description: The most-followed buckets, descending.
                                  total_buckets:
                                    type: number
                                    description: >-
                                      How many buckets LinkedIn returned for
                                      this facet in total.
                                  truncated:
                                    type: boolean
                                    description: >-
                                      True when buckets is a SUBSET. Never
                                      describe a truncated facet as the complete
                                      breakdown.
                                required:
                                  - buckets
                                  - total_buckets
                                  - truncated
                                additionalProperties: false
                              by_seniority:
                                type: object
                                properties:
                                  buckets:
                                    type: array
                                    items:
                                      type: object
                                      properties:
                                        key:
                                          type: string
                                          description: >-
                                            The facet value — a LinkedIn URN or
                                            enum, e.g. urn:li:industry:4.
                                        follower_count:
                                          type: number
                                          description: >-
                                            Organic AND paid followers in this
                                            bucket, rolled together.
                                      required:
                                        - key
                                        - follower_count
                                      additionalProperties: false
                                    description: The most-followed buckets, descending.
                                  total_buckets:
                                    type: number
                                    description: >-
                                      How many buckets LinkedIn returned for
                                      this facet in total.
                                  truncated:
                                    type: boolean
                                    description: >-
                                      True when buckets is a SUBSET. Never
                                      describe a truncated facet as the complete
                                      breakdown.
                                required:
                                  - buckets
                                  - total_buckets
                                  - truncated
                                additionalProperties: false
                              by_staff_count_range:
                                type: object
                                properties:
                                  buckets:
                                    type: array
                                    items:
                                      type: object
                                      properties:
                                        key:
                                          type: string
                                          description: >-
                                            The facet value — a LinkedIn URN or
                                            enum, e.g. urn:li:industry:4.
                                        follower_count:
                                          type: number
                                          description: >-
                                            Organic AND paid followers in this
                                            bucket, rolled together.
                                      required:
                                        - key
                                        - follower_count
                                      additionalProperties: false
                                    description: The most-followed buckets, descending.
                                  total_buckets:
                                    type: number
                                    description: >-
                                      How many buckets LinkedIn returned for
                                      this facet in total.
                                  truncated:
                                    type: boolean
                                    description: >-
                                      True when buckets is a SUBSET. Never
                                      describe a truncated facet as the complete
                                      breakdown.
                                required:
                                  - buckets
                                  - total_buckets
                                  - truncated
                                additionalProperties: false
                            required:
                              - by_association_type
                              - by_country
                              - by_function
                              - by_industry
                              - by_geo
                              - by_seniority
                              - by_staff_count_range
                            additionalProperties: false
                          - type: 'null'
                        description: >-
                          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`.
                      follower_gains:
                        anyOf:
                          - type: array
                            items:
                              type: object
                              properties:
                                start_ms:
                                  type: number
                                end_ms:
                                  type: number
                                organic_follower_gain:
                                  type: number
                                paid_follower_gain:
                                  type: number
                              required:
                                - start_ms
                                - end_ms
                                - organic_follower_gain
                                - paid_follower_gain
                              additionalProperties: false
                          - type: 'null'
                        description: >-
                          Time-bound read only. GAINS per interval, not running
                          totals.
                      page_views:
                        anyOf:
                          - type: array
                            items:
                              type: object
                              properties:
                                start_ms:
                                  type:
                                    - number
                                    - 'null'
                                end_ms:
                                  type:
                                    - number
                                    - 'null'
                                all_page_views:
                                  type: number
                                all_desktop_page_views:
                                  type: number
                                all_mobile_page_views:
                                  type: number
                                overview_page_views:
                                  type: number
                                custom_button_clicks:
                                  type: number
                              required:
                                - start_ms
                                - end_ms
                                - all_page_views
                                - all_desktop_page_views
                                - all_mobile_page_views
                                - overview_page_views
                                - custom_button_clicks
                              additionalProperties: false
                          - type: 'null'
                        description: >-
                          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.
                      shares:
                        anyOf:
                          - type: array
                            items:
                              type: object
                              properties:
                                start_ms:
                                  type:
                                    - number
                                    - 'null'
                                end_ms:
                                  type:
                                    - number
                                    - 'null'
                                impression_count:
                                  type: number
                                unique_impressions_count:
                                  type: number
                                click_count:
                                  type: number
                                like_count:
                                  type: number
                                comment_count:
                                  type: number
                                share_count:
                                  type: number
                                engagement:
                                  type: number
                              required:
                                - start_ms
                                - end_ms
                                - impression_count
                                - unique_impressions_count
                                - click_count
                                - like_count
                                - comment_count
                                - share_count
                                - engagement
                              additionalProperties: false
                          - type: 'null'
                        description: >-
                          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.
                      unavailable:
                        type: array
                        items:
                          type: object
                          properties:
                            section:
                              type: string
                            reason:
                              type: string
                          required:
                            - section
                            - reason
                          additionalProperties: false
                        description: >-
                          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.
                      workspace:
                        type: string
                        description: The slug of the workspace this call ran in.
                      working_in:
                        type: object
                        properties:
                          label:
                            type: string
                            description: 'The chip words — e.g. "working in: Acme Main".'
                          note:
                            type: string
                            description: >-
                              Why this workspace — e.g. "your default", "this
                              call only".
                          workspace:
                            type: string
                            description: The resolved workspace's slug.
                          source:
                            type: string
                            enum:
                              - call-override
                              - key-pin
                              - stored-default
                              - sole-reachable
                            description: >-
                              Which rung of the R7 precedence resolved the
                              workspace.
                        required:
                          - label
                          - note
                          - workspace
                          - source
                        additionalProperties: false
                        description: >-
                          Which workspace this call ran in, and how that was
                          decided. Present on every workspace-scoped result.
                    required:
                      - ok
                      - administered_organizations
                      - connect_path
                      - follower_demographics
                      - follower_gains
                      - organization_urn
                      - page_views
                      - provenance
                      - read_elsewhere
                      - shares
                      - source
                      - source_note
                      - total_followers
                      - unavailable
                      - window
                      - working_in
                      - workspace
                  - $ref: '#/components/schemas/ToolRefusal'
        '400':
          description: >-
            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.
          headers:
            x-goosy-api:
              description: Present while this API is in beta; the value is `beta`.
              schema:
                type: string
                const: beta
            x-request-id:
              description: >-
                This request's id: the `x-request-id` you sent when it was well
                formed, otherwise one generated for you. Quote it to support; it
                is recorded on every audit row the call wrote.
              schema:
                type: string
            Deprecation:
              description: >-
                RFC 9745: this refusal's nested `error` object is deprecated,
                since this instant (`@<unix seconds>`).
              schema:
                type: string
            Sunset:
              description: >-
                RFC 8594: the nested `error` object may be removed after this
                date (2026-12-31).
              schema:
                type: string
            Link:
              description: The page that says what to read instead (`rel="deprecation"`).
              schema:
                type: string
            RateLimit-Limit:
              description: Requests this key may make in a rolling minute.
              schema:
                type: integer
                minimum: 1
            RateLimit-Remaining:
              description: Requests left in the current rolling minute.
              schema:
                type: integer
                minimum: 0
            RateLimit-Reset:
              description: Whole seconds until the window frees more requests.
              schema:
                type: integer
                minimum: 1
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '401':
          description: >-
            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.
          headers:
            x-goosy-api:
              description: Present while this API is in beta; the value is `beta`.
              schema:
                type: string
                const: beta
            x-request-id:
              description: >-
                This request's id: the `x-request-id` you sent when it was well
                formed, otherwise one generated for you. Quote it to support; it
                is recorded on every audit row the call wrote.
              schema:
                type: string
            Deprecation:
              description: >-
                RFC 9745: this refusal's nested `error` object is deprecated,
                since this instant (`@<unix seconds>`).
              schema:
                type: string
            Sunset:
              description: >-
                RFC 8594: the nested `error` object may be removed after this
                date (2026-12-31).
              schema:
                type: string
            Link:
              description: The page that says what to read instead (`rel="deprecation"`).
              schema:
                type: string
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '403':
          description: >-
            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.
          headers:
            x-goosy-api:
              description: Present while this API is in beta; the value is `beta`.
              schema:
                type: string
                const: beta
            x-request-id:
              description: >-
                This request's id: the `x-request-id` you sent when it was well
                formed, otherwise one generated for you. Quote it to support; it
                is recorded on every audit row the call wrote.
              schema:
                type: string
            Deprecation:
              description: >-
                RFC 9745: this refusal's nested `error` object is deprecated,
                since this instant (`@<unix seconds>`).
              schema:
                type: string
            Sunset:
              description: >-
                RFC 8594: the nested `error` object may be removed after this
                date (2026-12-31).
              schema:
                type: string
            Link:
              description: The page that says what to read instead (`rel="deprecation"`).
              schema:
                type: string
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '404':
          description: >-
            No such tool. The body names no tool and is identical for every
            unrecognised name.
          headers:
            x-goosy-api:
              description: Present while this API is in beta; the value is `beta`.
              schema:
                type: string
                const: beta
            x-request-id:
              description: >-
                This request's id: the `x-request-id` you sent when it was well
                formed, otherwise one generated for you. Quote it to support; it
                is recorded on every audit row the call wrote.
              schema:
                type: string
            Deprecation:
              description: >-
                RFC 9745: this refusal's nested `error` object is deprecated,
                since this instant (`@<unix seconds>`).
              schema:
                type: string
            Sunset:
              description: >-
                RFC 8594: the nested `error` object may be removed after this
                date (2026-12-31).
              schema:
                type: string
            Link:
              description: The page that says what to read instead (`rel="deprecation"`).
              schema:
                type: string
            RateLimit-Limit:
              description: Requests this key may make in a rolling minute.
              schema:
                type: integer
                minimum: 1
            RateLimit-Remaining:
              description: Requests left in the current rolling minute.
              schema:
                type: integer
                minimum: 0
            RateLimit-Reset:
              description: Whole seconds until the window frees more requests.
              schema:
                type: integer
                minimum: 1
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '429':
          description: >-
            Over this key's per-minute cap. Carries `Retry-After` and
            `error.retry_after_seconds`.
          headers:
            x-goosy-api:
              description: Present while this API is in beta; the value is `beta`.
              schema:
                type: string
                const: beta
            x-request-id:
              description: >-
                This request's id: the `x-request-id` you sent when it was well
                formed, otherwise one generated for you. Quote it to support; it
                is recorded on every audit row the call wrote.
              schema:
                type: string
            Deprecation:
              description: >-
                RFC 9745: this refusal's nested `error` object is deprecated,
                since this instant (`@<unix seconds>`).
              schema:
                type: string
            Sunset:
              description: >-
                RFC 8594: the nested `error` object may be removed after this
                date (2026-12-31).
              schema:
                type: string
            Link:
              description: The page that says what to read instead (`rel="deprecation"`).
              schema:
                type: string
            RateLimit-Limit:
              description: Requests this key may make in a rolling minute.
              schema:
                type: integer
                minimum: 1
            RateLimit-Remaining:
              description: Requests left in the current rolling minute.
              schema:
                type: integer
                minimum: 0
            RateLimit-Reset:
              description: Whole seconds until the window frees more requests.
              schema:
                type: integer
                minimum: 1
            Retry-After:
              description: Whole seconds to wait before retrying.
              schema:
                type: integer
                minimum: 1
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
components:
  schemas:
    ToolRefusal:
      type: object
      properties:
        ok:
          type: boolean
          const: false
        code:
          type: string
          description: >-
            The typed reason — e.g. `workspace_ambiguous`, `invalid_arguments`,
            or the tool's own failure code.
        message:
          type: string
          description: A sentence a person can act on.
        workspaces:
          type: array
          items:
            type: string
          description: 'On a workspace refusal: the slugs this key may pass as `workspace`.'
        issues:
          type: array
          items:
            type: object
            properties:
              path:
                type: string
              message:
                type: string
            required:
              - path
              - message
            additionalProperties: false
          description: 'On `invalid_arguments`: which fields failed, and why.'
      required:
        - ok
        - code
        - message
      additionalProperties: false
      description: A call that was admitted and dispatched, and did not succeed.
    Error:
      type: object
      properties:
        ok:
          type: boolean
          const: false
        code:
          type: string
          description: >-
            The typed refusal code — e.g. `tenant_mcp.surface_disabled`,
            `tenant_mcp.rate_limited`.
        message:
          type: string
          description: A sentence a person can act on.
        retry_after_seconds:
          type: number
          description: 'On a 429: whole seconds to wait. Mirrors `Retry-After`.'
        error:
          type: object
          properties:
            code:
              type: string
            message:
              type: string
            retry_after_seconds:
              type: number
          required:
            - code
            - message
          additionalProperties: false
          description: >-
            Deprecated: the same values as the top-level fields, kept until
            2026-12-31. Read `code` and `message` at the top level.
      required:
        - ok
        - code
        - message
        - error
      additionalProperties: false
      description: >-
        A request the boundary refused before dispatching anything. The same
        shape the MCP endpoint answers its own refusals with, and the same
        top-level fields a dispatched call's refusal carries, so one client
        branch covers both.
  securitySchemes:
    tenantApiKey:
      type: http
      scheme: bearer
      description: >-
        An API key minted at Settings › API & MCP. Send it as `Authorization:
        Bearer <key>`. A key carries its holder's own permissions, resolved on
        every call — revoking a membership closes the key's reach immediately.
        Keep it in an environment variable (`GOOSY_API_KEY`), never in a
        committed file.

````