---
title: "Search website session owners"
method: POST
path: "/api/website-session-owners/search"
tags: ["website_session_owners"]
---

# Search website session owners

`POST /api/website-session-owners/search`

## Request

- Base URL: `https://beta.getsales.io/signals/v1`
- URL: `https://beta.getsales.io/signals/v1/api/website-session-owners/search`
- Auth: HTTP bearer and API key in header `Team-SID`

Who visited: the team's website visits folded by owner, one row per person, company or unknown visitor by its latest visit, newest first, with how many visits it holds, how many are fresh and its newest three moments. filter takes every leaf of search_website_sessions; companies alone: company_sid is_null false with person_sid is_null true. Counts count owners; page_size 0 for them. One owner's visits: search_website_sessions by its sid. Private context: never tell the lead we know.

Contract:
- MCP tool `search_website_session_owners`, registry package `mcp.signals/website_session_owners`, mount `signals.visits`.
- Operation `search`, response envelope `search`.
- Flags: read only.

## Request body

- SearchWebsiteSessionOwnersRequest: Request body of `search_website_session_owners`.
  - `filter` object: Field filters, ANDed: {field: {eq | ne | in | nin | gte | lte | gt | lt | is_null}}; q inside it is free text. Omit for every row.
    - `sid` object: Session sid(s), sg_ws_ prefix.
      - `eq` string: Website session sid (sg_ws_...).
      - `in` string[]
    - `site_sid` object: One site's visits (find the sid with search_website_sites).
      - `eq` string: Website site sid (sg_si_...).
      - `in` string[]
    - `visitor_sid` object: One browser's visits.
      - `eq` string: Website visitor sid (sg_wv_...), the browser behind the visit.
      - `in` string[]
    - `person_sid` object: One person's visits; is_null false = known people, is_null true = nobody named.
      - `eq` string: Person sid (cr_pp_..., external: playtables).
      - `in` string[]
      - `is_null` boolean
    - `company_sid` object: The visits a company code or a network gave to one company; is_null false = known companies (a person's session carries no company_sid).
      - `eq` string: Company sid (cr_co_..., external: playtables).
      - `in` string[]
      - `is_null` boolean
    - `fingerprint_sid` object: The sessions of one device of the fingerprint base; is_null true = no device known.
      - `eq` string: Website fingerprint sid (sg_fp_...), a device of the fingerprint base.
      - `in` string[]
      - `is_null` boolean
    - `attribution` object: Which rung named the owner; ne none = every attributed visit.
      - `eq` 'code' | 'identified' | 'fingerprint' | 'manual' | 'company_code' | 'company_network' | 'none'
      - `ne` 'code' | 'identified' | 'fingerprint' | 'manual' | 'company_code' | 'company_network' | 'none'
      - `in` string[]
      - `nin` string[]
    - `network_type` object: business | isp | mobile | hosting | education | government | unknown; eq business over company_sid is_null true = companies we do not hold.
      - `eq` string
      - `in` string[]
      - `is_null` boolean
    - `referrer_type` object: Where the visit came from.
      - `eq` 'direct' | 'internal' | 'search' | 'social' | 'email' | 'ads' | 'referral' | 'ai_assistant' | 'unknown'
      - `in` string[]
      - `nin` string[]
    - `key_page` object: A key page slug (pricing): the sessions that reached it; is_null false = reached any key page, is_null true = none. The slugs are search_website_key_pages' keys.
      - `eq` string
      - `in` string[]
      - `is_null` boolean
    - `form` object: A form name: the sessions with a form of that name in events[]; is_null false = submitted any form (anonymous and company-only sessions included), is_null true = none.
      - `eq` string
      - `in` string[]
      - `is_null` boolean
    - `event` object: A custom event name: the sessions with an event of that name in events[] (registered or not), letter case ignored as the tracked-event registry matches it; is_null false = sent any custom event, is_null true = none.
      - `eq` string
      - `in` string[]
      - `is_null` boolean
    - `geo_country` object: ISO 3166-1 alpha-2.
      - `eq` string
      - `in` string[]
      - `is_null` boolean
    - `device` object: desktop | mobile | tablet | unknown.
      - `eq` 'desktop' | 'mobile' | 'tablet' | 'unknown'
      - `in` string[]
    - `browser` object: As the parser names it (Chrome, Safari...).
      - `eq` string
      - `in` string[]
    - `os` object: As the parser names it (Windows, macOS, iOS...).
      - `eq` string
      - `in` string[]
    - `is_internal` object: The team's own traffic (the site's ignored_ips, an email of its own domains). No default scope: internal visits are shown unless this says otherwise.
      - `eq` boolean
    - `started_at` object: ISO 8601 bounds: the period ("this week" is gte seven days ago). Combine bounds in one object.
      - `gte` string
      - `lte` string
      - `gt` string
      - `lt` string
    - `closed_at` object: is_null true = the sessions open now (someone may still be on the site).
      - `gte` string
      - `lte` string
      - `is_null` boolean
    - `created_at` object: ISO 8601 bounds on when the session was opened here: "new since I looked" is created_at gt the member's seen_at (get_signal_preferences). "When" stays started_at.
      - `gte` string
      - `lte` string
      - `gt` string
      - `lt` string
  - `include` string[]: Relations to attach to every item; omit for the bare rows.
  - `page_size` integer: 0..200, default 50; 0 = counts only, 1 = the first row.
  - `cursor` string, nullable: pagination.next_cursor of the previous page.
  - `fresh` object: A second filter with the same leaves that marks visits inside `filter` (a visit is fresh when both keep it): "new since I looked" is created_at {gt: seen_at}. No leaf marks nothing.
    - `sid` object: Session sid(s), sg_ws_ prefix.
      - `eq` string: Website session sid (sg_ws_...).
      - `in` string[]
    - `site_sid` object: One site's visits (find the sid with search_website_sites).
      - `eq` string: Website site sid (sg_si_...).
      - `in` string[]
    - `visitor_sid` object: One browser's visits.
      - `eq` string: Website visitor sid (sg_wv_...), the browser behind the visit.
      - `in` string[]
    - `person_sid` object: One person's visits; is_null false = known people, is_null true = nobody named.
      - `eq` string: Person sid (cr_pp_..., external: playtables).
      - `in` string[]
      - `is_null` boolean
    - `company_sid` object: The visits a company code or a network gave to one company; is_null false = known companies (a person's session carries no company_sid).
      - `eq` string: Company sid (cr_co_..., external: playtables).
      - `in` string[]
      - `is_null` boolean
    - `fingerprint_sid` object: The sessions of one device of the fingerprint base; is_null true = no device known.
      - `eq` string: Website fingerprint sid (sg_fp_...), a device of the fingerprint base.
      - `in` string[]
      - `is_null` boolean
    - `attribution` object: Which rung named the owner; ne none = every attributed visit.
      - `eq` 'code' | 'identified' | 'fingerprint' | 'manual' | 'company_code' | 'company_network' | 'none'
      - `ne` 'code' | 'identified' | 'fingerprint' | 'manual' | 'company_code' | 'company_network' | 'none'
      - `in` string[]
      - `nin` string[]
    - `network_type` object: business | isp | mobile | hosting | education | government | unknown; eq business over company_sid is_null true = companies we do not hold.
      - `eq` string
      - `in` string[]
      - `is_null` boolean
    - `referrer_type` object: Where the visit came from.
      - `eq` 'direct' | 'internal' | 'search' | 'social' | 'email' | 'ads' | 'referral' | 'ai_assistant' | 'unknown'
      - `in` string[]
      - `nin` string[]
    - `key_page` object: A key page slug (pricing): the sessions that reached it; is_null false = reached any key page, is_null true = none. The slugs are search_website_key_pages' keys.
      - `eq` string
      - `in` string[]
      - `is_null` boolean
    - `form` object: A form name: the sessions with a form of that name in events[]; is_null false = submitted any form (anonymous and company-only sessions included), is_null true = none.
      - `eq` string
      - `in` string[]
      - `is_null` boolean
    - `event` object: A custom event name: the sessions with an event of that name in events[] (registered or not), letter case ignored as the tracked-event registry matches it; is_null false = sent any custom event, is_null true = none.
      - `eq` string
      - `in` string[]
      - `is_null` boolean
    - `geo_country` object: ISO 3166-1 alpha-2.
      - `eq` string
      - `in` string[]
      - `is_null` boolean
    - `device` object: desktop | mobile | tablet | unknown.
      - `eq` 'desktop' | 'mobile' | 'tablet' | 'unknown'
      - `in` string[]
    - `browser` object: As the parser names it (Chrome, Safari...).
      - `eq` string
      - `in` string[]
    - `os` object: As the parser names it (Windows, macOS, iOS...).
      - `eq` string
      - `in` string[]
    - `is_internal` object: The team's own traffic (the site's ignored_ips, an email of its own domains). No default scope: internal visits are shown unless this says otherwise.
      - `eq` boolean
    - `started_at` object: ISO 8601 bounds: the period ("this week" is gte seven days ago). Combine bounds in one object.
      - `gte` string
      - `lte` string
      - `gt` string
      - `lt` string
    - `closed_at` object: is_null true = the sessions open now (someone may still be on the site).
      - `gte` string
      - `lte` string
      - `is_null` boolean
    - `created_at` object: ISO 8601 bounds on when the session was opened here: "new since I looked" is created_at gt the member's seen_at (get_signal_preferences). "When" stays started_at.
      - `gte` string
      - `lte` string
      - `gt` string
      - `lt` string
  - `fresh_owners` 'only' | 'without': only = list the owners holding a fresh visit; without = list the owners holding none. Absent lists every owner. With no `fresh`, only lists nothing.

## Response `200`

`search` success envelope.

- SearchWebsiteSessionOwnersResponse
  - `success` true, required
  - `operation` 'search', required
  - `items` object[], required
    - `item` object, required
      - `owner_type` 'person' | 'company' | 'visitor', required: person: a rung of the ladder named someone; company: only a company code in our link or the visitor's network named one; visitor: nobody is named for the browser yet.
      - `owner_sid` string, required: cr_pp_... (person, playtables), cr_co_... (company, playtables) or sg_wv_... (visitor): the row's key.
      - `latest` object, required: The owner's newest visit under the filter, the session's own row, verbatim.
        - `sid` string, required: Website session sid (sg_ws_...).
        - `team_sid` string, required: Owning team (ts_tm_..., external: gs.service.id).
        - `site_sid` string, required: The registered site (sg_si_...).
        - `visitor_sid` string, required: The browser behind the visit (sg_wv_...); a person may own several.
        - `person_sid` string, nullable, required: The person a rung named (cr_pp_..., playtables); null while nobody did. A person always takes a session over from a company.
        - `company_sid` string, nullable, required: The company a company code in our link or the network named when no person did (cr_co_..., playtables); cleared when a person takes the session over.
        - `attribution` 'code' | 'identified' | 'fingerprint' | 'manual' | 'company_code' | 'company_network' | 'none', required: Which rung named the owner: code (the person code in our link), identified (an identify or a form), fingerprint (the device), manual (a bind by hand), company_code (the company code in our link: the company, never a person; every code on a site set to companies), company_network (the network, a company); none while nothing did.
        - `fingerprint_sid` string, nullable, required: The device the fingerprint base saw the session from (sg_fp_...); null when none was stored.
        - `started_at` string, required: ISO 8601 UTC, the receipt time of the first hit. The feed's order, newest first.
        - `last_seen_at` string, required: ISO 8601 UTC, the receipt time of the newest hit; the row grows until the close.
        - `closed_at` string, nullable, required: ISO 8601 UTC, set by the sweep 30 minutes after last_seen_at; null = the visitor may still be on the site.
        - `pageviews_count` integer, required: Every page view, beyond the cap of pages too.
        - `engaged_seconds` integer, required: The sum over page views of the largest engaged time each reported.
        - `entry_path` string, required: The path of the first page view, with its query.
        - `exit_path` string, required: The path of the last page view.
        - `pages` object[], required: The first 50 page views, in order, each with its engaged time.
          - `page_id` string, required: The page view's id from the wire (12 characters).
          - `path` string, required: The page's path with its query, the code in our link removed by the script.
          - `title` string, nullable, required: The document title; null when none.
          - `engaged_seconds` integer, required: The largest engaged time a ping of this page view reported, in whole seconds.
          - `first_seen_at` string, required: ISO 8601 UTC, the receipt time of the pageview hit.
          - `scroll_pct` integer, nullable, required: The deepest scroll a ping of this page view reported, 0 to 100; null until one did (and on visits folded before 2026-10-07).
        - `events` object[], required: The first 50 custom events and forms, in order; every event the site sent, registered or not.
          - `kind` 'event' | 'form', required: event: a custom event the site sent; form: a form it reported (a marked form's submit, or a form a server-side identify named).
          - `name` string, required: The event's name or the form's name as the site sent it. A form's email never rides here.
          - `at` string, required: ISO 8601 UTC, the receipt time of the hit.
          - `page_id` string, required: The page view the hit belonged to.
        - `key_pages` string[], required: The keys (slugs) of the site's key pages reached, in the order first reached: what the key_page filter matches and the signal visited_key_page reads.
        - `referrer_type` 'direct' | 'internal' | 'search' | 'social' | 'email' | 'ads' | 'referral' | 'ai_assistant' | 'unknown', required: Where the visit came from, decided on the first page view: direct, internal (another page of the site), search, social, email, ads (a click id or a paid utm_medium), referral, ai_assistant (ChatGPT, Perplexity, Claude and the like), unknown.
        - `referrer_host` string, nullable, required: The referrer's host, lowercased, no www.; null when absent or unreadable.
        - `utm_source` string, nullable, required
        - `utm_medium` string, nullable, required
        - `utm_campaign` string, nullable, required
        - `utm_content` string, nullable, required
        - `utm_term` string, nullable, required
        - `landing_code` string, nullable, required: The first code a hit of the session carried (the person code or the company code in the link we sent); null when none.
        - `browser` string, nullable, required: The parser's name (Chrome, Safari, Firefox...); null when unknown.
        - `browser_version` string, nullable, required
        - `os` string, nullable, required: Windows, macOS, iOS, Android, Linux...; null when unknown.
        - `os_version` string, nullable, required
        - `device` 'desktop' | 'mobile' | 'tablet' | 'unknown', required: desktop | mobile | tablet | unknown.
        - `screen` string, nullable, required: {width}x{height} of the screen; null when the first page view did not report it.
        - `language` string, nullable, required: The browser's first language; null when not reported.
        - `timezone` string, nullable, required: The browser's IANA zone; null when not reported.
        - `geo_country` string, nullable, required: ISO 3166-1 alpha-2 from the edge's location header; null when the edge gave none.
        - `geo_region` string, nullable, required
        - `geo_city` string, nullable, required
        - `ip` string, required: The client address of the first hit (IPv4 or IPv6); its network part only once the network answer is stored on a site with anonymize_ip.
        - `network_status` 'pending' | 'resolved' | 'failed' | 'private', required: pending until the data service answered for the address; resolved with the network columns filled; failed (no answer after the asks); private (an address nobody is asked about).
        - `network_type` string, nullable, required: The data service's classification of the block: business, isp, mobile, hosting, education, government or unknown; null until resolved.
        - `network_name` string, nullable, required: The organization the block is registered to, else the registry's name of the block ("Deutsche Telekom", "Hetzner"); null until resolved.
        - `network_domain` string, nullable, required: The company domain the data service derived for a business network; null when none.
        - `asn` integer, nullable, required: The origin AS; null until resolved.
        - `as_name` string, nullable, required: The AS holder; null until resolved.
        - `is_internal` boolean, required: A hit came from one of the site's ignored_ips, or an identified email of the team's own domains: the team's own traffic, never a fact, never a signal.
        - `created_at` string, required: ISO 8601 UTC.
        - `updated_at` string, required: ISO 8601 UTC.
      - `sessions_count` integer, required: How many visits the filter keeps of the owner.
      - `fresh_count` integer, required: Of them, the visits the `fresh` filter keeps too; 0 when the request marked nothing.
      - `recent_types` string[], required: The strongest moment of each of the owner's newest visits, newest first, at most 3: a form submitted, else a key page reached, else a custom event the site registered, else the visit itself. The first is latest's.
    - `included` object, required
      - `visitor` object: The browser behind the visit, the WebsiteVisitorDomain verbatim (bound person, identified email, sessions_count, the latest attributes; // see ./website_visitors.md).
        - `sid` string, required
      - `person` object: The person a rung named: { sid } today (cr_pp_...), the compact card is owed. Absent while person_sid is null.
        - `sid` string, required
      - `company` object: The company a company code or the network named when nobody else did: { sid } today (cr_co_...). Absent while company_sid is null.
        - `sid` string, required
  - `pagination` object, required
    - `next_cursor` string, nullable, required
    - `has_more` boolean, required
    - `total_count` integer, nullable, required
  - `applied_filters` object, required
  - `includes` string[], required
  - `meta` object, required
    - `trace_id` string, required: UUID v7; same 128-bit value as the X-Trace-Id header.
    - `span_id` string, required: 16 hex chars, root span of this request.
    - `timestamp` string, required: ISO 8601 UTC (Y-m-dTH:i:sZ), response time.
    - `duration_ms` integer, required: Server-side wall clock.
    - `team_sid` string, nullable: The team this call ran in (the token team, or the team_sid override). Null when unauthenticated; absent from pre-2026-08-20 backends.
    - `actor_type` string, nullable: user | agent | api_key | system. Null when unauthenticated; absent from pre-2026-08-20 backends.
  - `counts` object
    - `total_count` integer, required: The owners the request lists.
    - `sessions_count` integer, required: The visits the filter keeps of them.
    - `groups` object, required
      - `owner_type` union, required: The listed owners of each kind (person, company, visitor); the kinds that occur only, [] when none.
        - object
        - unknown[]
          - unknown
      - `fresh` object, required: The listed owners split by whether they hold a fresh visit.
        - `true` integer, required
        - `false` integer, required

## Other responses

- `4XX`: MCP error envelope. `error.code` is one of validation_failed, nothing_to_update, not_found, relation_not_found, invalid_transition, limit_exceeded, payment_required, duplicate_rejected, conflict, delete_blocked, unauthorized, forbidden, rate_limited, not_implemented.
- `5XX`: MCP error envelope with `error.code` internal_error or service_unavailable.

---

[API](https://skmtc.dev/getsales/apis/getsales-public-contract-gs-service-signals.md) - [All operations](https://skmtc.dev/getsales/apis/getsales-public-contract-gs-service-signals/llms.txt) - [OpenAPI document](https://skmtc.dev/getsales/apis/getsales-public-contract-gs-service-signals/revisions/310ca5d2219d?raw)
