---
title: "Search website sessions"
method: POST
path: "/api/website-sessions/search"
tags: ["website_sessions"]
---

# Search website sessions

`POST /api/website-sessions/search`

## Request

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

The visitor feed: every visit to the team's sites, newest first, as one session: who it belongs to when a rung named someone (person_sid, or company_sid when only a company code or the network did; attribution says which), what was seen (pages with engaged time, key_pages, events: forms and custom events), where it came from (referrer_type, the utm set, landing_code), the browser and the network (network_type business, isp, mobile, hosting, education, government or unknown; network_name, network_domain). Scope with site_sid, started_at (the period) and the sids of a person, a company or a visitor; key_page, form and event take a slug or a name (eq or in), and is_null false = any whatever the name (every session that submitted a form, anonymous ones included), true = none; person_sid is_null false = known people, closed_at is_null true = on the site now, is_internal eq true = the team's own traffic. page_size 0 returns the counts by attribution, network type, referrer type, device and key page. "Who visited pricing this week and has not replied": this with key_page pricing and a started_at window, then search_people or search_conversations by the signals visited_key_page and visited_not_replied. What a session saw is private context: use it to decide when to write and what to offer, never tell the lead we know.

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

## Request body

- SearchWebsiteSessionsRequest: Request body of `search_website_sessions`.
  - `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.
  - `sort` object: One column and its direction; omit for the default order.
    - `field` 'started_at' | 'last_seen_at' | 'engaged_seconds' | 'pageviews_count', required: The column to order by.
    - `direction` 'asc' | 'desc': asc or desc; default desc.
  - `page_size` integer: 0..500, default 50; 0 = counts only, 1 = the first row.
  - `cursor` string, nullable: pagination.next_cursor of the previous page.

## Response `200`

`search` success envelope.

- SearchWebsiteSessionsResponse
  - `success` true, required
  - `operation` 'search', required
  - `items` object[], required
    - `item` object, required
      - `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.
    - `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: Sessions matching the filter (full filter scope, not the page).
    - `groups` object, required
      - `attribution` union, required: Sessions per attribution (code, identified, fingerprint, manual, company_code, company_network, none); the values that occur only, [] when none.
        - object
        - unknown[]
          - unknown
      - `network_type` union, required: Sessions per network classification (business, isp, mobile, hosting, education, government, unknown); unresolved sessions are not a group.
        - object
        - unknown[]
          - unknown
      - `referrer_type` union, required: Sessions per referrer type.
        - object
        - unknown[]
          - unknown
      - `device` union, required: Sessions per device class.
        - object
        - unknown[]
          - unknown
      - `key_page` union, required: Sessions per key page slug reached; a session that reached two pages counts in both.
        - object
        - unknown[]
          - unknown

## 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)
