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

# List businesses

> Reads businesses in the selected workspace. Filter with `q`, a JSON object of field matches. Reads only: writes through this route are refused for every entity and every credential.



## OpenAPI

````yaml /openapi.json get /api/entities/BusinessLocation
openapi: 3.1.0
info:
  title: Reputably API
  version: 1.0.0
  description: >-
    The HTTP surface an agent credential can reach. It is read plus safe writes:
    you can read your reputation data, generate drafts, queue reports and run
    first-time tracking setup. You cannot send anything to an external platform,
    trigger syncs, touch billing or manage credentials.


    The same endpoints back the MCP server, so anything documented here is
    reachable both ways.
servers:
  - url: https://app.reputably.net
    description: Reputably
  - url: https://your-domain.example
    description: Your own verified white-label domain
security:
  - agentKey: []
tags:
  - name: Businesses
    description: The locations you track, their plan usage and AI-generated insights.
  - name: Reviews
    description: Google and Facebook reviews, including which still need a reply.
  - name: Brand mentions
    description: Mentions across X, Reddit, YouTube, Facebook communities and the open web.
  - name: Brand tracking
    description: The trackers that find mentions, and competitor share of voice.
  - name: Leads
    description: Buying signals detected in mentions, with the public post to reply to.
  - name: AI Visibility
    description: >-
      Whether AI assistants recommend the business, what they cite, and how it
      moves.
  - name: AI Traffic
    description: Which AI crawlers read the website, and who arrives from an AI answer.
  - name: Posts
    description: Google Business Profile posts and drafts.
  - name: Reports
    description: Queued report renders and their CSV output.
  - name: Setup
    description: First-time tracking configuration.
  - name: Account
    description: Workspaces, notifications, sync status and prospect audits.
paths:
  /api/entities/BusinessLocation:
    get:
      tags:
        - Businesses
      summary: List businesses
      description: >-
        Reads businesses in the selected workspace. Filter with `q`, a JSON
        object of field matches. Reads only: writes through this route are
        refused for every entity and every credential.
      operationId: listBusinessLocation
      parameters:
        - name: q
          in: query
          required: false
          schema:
            type: string
          description: JSON filter object, for example {"needs_response":true}.
        - name: sort_by
          in: query
          required: false
          schema:
            type: string
          description: Field to sort on.
        - name: limit
          in: query
          required: false
          schema:
            type: integer
          description: Maximum rows to return.
        - name: skip
          in: query
          required: false
          schema:
            type: integer
          description: Rows to skip, for paging.
        - name: X-Workspace-Id
          in: header
          required: false
          schema:
            type: string
          description: >-
            Which workspace to read. Omit it and you get the account’s home
            workspace, which on an agency account is often not where the live
            businesses are. A workspace this credential cannot read is refused
            with 403 rather than quietly answered from the default.
      responses:
        '200':
          description: Matching businesses.
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/BusinessLocation'
        '401':
          description: Missing or invalid credential.
        '403':
          description: Not readable by this credential, or not in this workspace.
components:
  schemas:
    BusinessLocation:
      type: object
      title: BusinessLocation
      properties:
        id:
          type: string
          description: Unique id.
        google_place_id:
          type: string
        google_account_id:
          type: string
        google_location_id:
          type: string
        facebook_page_id:
          type: string
          description: >-
            Set when this BusinessLocation was created from a Facebook Page
            connected in Settings. Mutually exclusive with google_location_id in
            practice — a chain's GBP listing and its Facebook Page get separate
            BusinessLocation rows.
        youtube_channel_id:
          type: string
          description: >-
            External YouTube channel id (UC…) bound to this location. Set from
            the Connections panel on BusinessDetail. The reply resolver joins
            this against OAuthIntegration.provider_account_id to pick which
            connected channel posts the comment.
        reddit_account_id:
          type: string
          description: >-
            Reddit account fullname (t2_…) bound to this location. Same role as
            youtube_channel_id — the reply resolver joins this against
            OAuthIntegration.provider_account_id to pick which connected Reddit
            account authors the comment.
        reddit_username:
          type: string
          description: >-
            Denormalised display name for the bound Reddit account. The stable
            identifier is reddit_account_id (t2_…); this is just for UI
            affordances since usernames can change.
        source:
          type: string
          enum:
            - google
            - facebook
        added_via:
          type: string
          enum:
            - gbp_oauth
            - places
            - website
            - dfs_keyword
          description: How this business was added, which decides how its reviews are read.
        business_name:
          type: string
        business_category:
          type: string
        address_line1:
          type: string
        address_line2:
          type: string
        city:
          type: string
        state:
          type: string
        postal_code:
          type: string
        country:
          type: string
        phone:
          type: string
        website:
          type: string
        google_maps_url:
          type: string
        latitude:
          type: number
        longitude:
          type: number
        cover_photo_url:
          type: string
        logo_url:
          type: string
        average_rating:
          type: number
        total_reviews:
          type: integer
        is_verified:
          type: boolean
        is_active:
          type: boolean
        is_prospect:
          type: boolean
          description: >-
            Created by generateProspectAudit for a business the agency is
            pitching, not a client. Always paired with is_active=false. Filtered
            out of every business picker/list via useBusinessLocations' default
            exclusion; surfaces only on the Prospect Audits page. Conversion
            path: clear the flag (or just activate the location) when the
            prospect signs.
        billing_exempt:
          type: boolean
          description: >-
            Comp/internal location — excluded from plan capacity math and
            over-capacity checks.
        trial_state:
          type: string
          enum:
            - trialing
            - converted
            - ended
          description: >-
            Per-location trial discriminator for agency-onboarded clients added
            BEYOND paid capacity. 'trialing' = free now, excluded from capacity,
            will auto-convert at trial_end; 'converted' = trial billed and now
            counts as a normal paid location; 'ended' = trial canceled/expired
            without converting (the row is deactivated but kept, which blocks a
            repeat trial). Distinct from billing_exempt (comp = forever-free,
            never counts). Absent on rows that never trialed.
        trial_started_at:
          type: string
          description: >-
            Set once when a trial is first started. Its presence (keyed on
            stable location identity) is the anti-abuse signal — a location that
            has ever trialed can't trial again.
        trial_end:
          type: string
          description: >-
            Conversion deadline. The trialScheduler converts the location
            at/after this instant.
        trial_converted_at:
          type: string
        trial_ended_at:
          type: string
          description: >-
            Set when a trial ends without converting (scheduler expiry or user
            cancel-during-trial). Feeds the 'Free trial ended on <date>' note on
            the business card and its trial_ended notification. Absent on rows
            ended before this field existed — falls back to trial_end for
            display.
        trial_charge_amount:
          type: number
          description: >-
            Add-on rate captured at trial start, for display only ('converts to
            $X/mo on <date>'). Conversion always recomputes the real charge from
            live Stripe.
        trial_charge_interval:
          type: string
          enum:
            - month
            - year
        last_synced_at:
          type: string
        last_full_review_sync_at:
          type: string
          description: >-
            When the GBP v4 reviews endpoint was last paged to completion for
            this location. The scheduler's blanket sync is incremental (1
            call/location/tick); this drives the daily forced full sweep, which
            is the only thing that catches an owner reply typed into Google's
            own UI — a reply does not move the review's updateTime, so it never
            floats back to page 1.
        review_count_recheck_after:
          type: string
          description: >-
            Set when a full re-page failed to resolve a totalReviewCount vs
            stored-row-count disagreement — i.e. Google counts reviews its own
            list endpoint won't return. Suppresses the reconciliation guard
            until this time so a permanently-off-by-N location can't force a
            full page-through on every 15-min tick. Cleared by any successful
            reconciliation or manual Sync.
        review_link:
          type: string
        ai_insights:
          type: object
        ai_insights_updated_at:
          type: string
        ai_insights_review_count:
          type: integer
        is_online_only:
          type: boolean
          description: >-
            True for businesses with no physical location. Auto-inferred during
            enrichment from address fields + business_category. Manually
            overridable from /businesses/:id (PR-23). Online-only businesses
            always search globally; a tracker's explicit geo_scope still applies
            analysis-time filtering when the profile has country/state/city or
            serves_areas on file.
        is_online_only_overridden:
          type: boolean
          description: >-
            True if a user manually set is_online_only. Enrichment will not
            overwrite the value when this is true.
        enrichment:
          type: object
          description: >-
            Structured business profile derived from website scrape + extended
            GBP fetch + LLM extraction. Populated by businessEnrichment.js.
            Empty until enrichment runs successfully.
        enrichment_overrides:
          type: object
          description: >-
            Per-field user edits that shadow the auto-generated enrichment.
            Stored separately from `enrichment` so a manual refresh doesn't
            clobber them. When an override key is present,
            getEffectiveEnrichment uses it in place of the enrichment value.
            Keys: about (string), services (string[]), attributes (string[]).
        manual_notes:
          type: string
          description: >-
            Free-form context the user wants the AI to know about this business.
            Appended to the mention-analysis prompt alongside the enrichment
            summary. No auto-generated counterpart — pure user input.
        enrichment_updated_at:
          type: string
        enrichment_source:
          type: string
          enum:
            - first-add
            - manual-refresh
        enrichment_status:
          type: string
          enum:
            - pending
            - success
            - partial
            - failed
          description: >-
            'partial' = website scrape failed but GBP succeeded (or vice versa);
            the profile is still useful.
        enrichment_error:
          type: string
        auto_response_enabled:
          type: boolean
          description: >-
            Per-business opt-in for the AI review-reply worker. When the agency
            has configured rules in auto_response_settings, only locations with
            this flag set to true will get auto-replies queued. Default false —
            owners must opt in each business explicitly so a chain isn't
            bulk-enrolled.
  securitySchemes:
    agentKey:
      type: http
      scheme: bearer
      description: >-
        An agent key (`rpk_...`) created in Settings → API & MCP, sent as
        `Authorization: Bearer rpk_...`. Bearer only: a cookie session can never
        drive this API. An OAuth 2.1 access token obtained from the same host
        works identically and lands on the same ceiling.

````