---
title: "Unlink website visitor"
method: POST
path: "/api/website-visitors/{sid}/unlink"
tags: ["website_visitors"]
---

# Unlink website visitor

`POST /api/website-visitors/{sid}/unlink`

## Request

- Base URL: `https://beta.getsales.io/signals/v1`
- URL: `https://beta.getsales.io/signals/v1/api/website-visitors/{sid}/unlink`
- Auth: HTTP bearer and API key in header `Team-SID`

Clear a visitor's bind: person_sid, bound_by, bound_at and identified_email. Sessions already attributed keep their person and the facts written stay. Already unbound answers was_bound false.

Contract:
- MCP tool `unlink_website_visitor`, registry package `mcp.signals/website_visitors`, mount `signals.visits`.
- Operation `action`, response envelope `action`.
- Flags: dangerous: the MCP layer gates it behind a preview/commit token, and the effect cannot be undone through this API.

## Path parameters

- `sid` string, required: Website visitor sid (sg_wv_...).

## Response `200`

`action` success envelope.

- UnlinkWebsiteVisitorResponse
  - `success` true, required
  - `operation` 'action', required
  - `action` string, required: kebab-case verb; matches the route segment.
  - `item` object, nullable, required
    - `sid` string, required: Website visitor sid (sg_wv_...).
    - `team_sid` string, required: Owning team (ts_tm_..., external: gs.service.id).
    - `site_sid` string, required: The site the browser visited (sg_si_...): the same browser on two sites is two rows.
    - `visitor_id` string, required: The first-party visitor id the script stores (_gs_vid, a lowercase UUID v4), or eph_ plus 40 hex characters for a hit that carried none.
    - `is_ephemeral` boolean, required: The row belongs to a day, not to a browser (consent not given, storage blocked): a stranger the next day, never bound.
    - `person_sid` string, nullable, required: The person the visitor is bound to (cr_pp_..., playtables); null while unbound.
    - `identified_email` string, nullable, required: The email an identify or a form gave when no person matched: the "Add to table" rows of the feed. Null otherwise.
    - `bound_by` 'code' | 'identify' | 'fingerprint' | 'manual', nullable, required: Which rung bound the visitor: code (the person code in our link), identify (an email a person matched), fingerprint (the device), manual (a bind by hand). Null while unbound.
    - `bound_at` string, nullable, required: ISO 8601 UTC, when the bind was written; null while unbound.
    - `first_seen_at` string, required: ISO 8601 UTC, the receipt time of the first hit.
    - `last_seen_at` string, required: ISO 8601 UTC, the receipt time of the newest hit.
    - `sessions_count` integer, required: Sessions opened for this visitor: the returning visitors.
    - `browser` string, nullable, required: From the newest session; null when unknown.
    - `browser_version` string, nullable, required
    - `os` string, nullable, required
    - `os_version` string, nullable, required
    - `device` 'desktop' | 'mobile' | 'tablet' | 'unknown', required: desktop | mobile | tablet | unknown, from the newest session.
    - `screen` string, nullable, required
    - `language` string, nullable, required
    - `timezone` string, nullable, required
    - `geo_country` string, nullable, required: ISO 3166-1 alpha-2 of the newest session; null when the edge gave none.
    - `geo_region` string, nullable, required
    - `geo_city` string, nullable, required
    - `network_type` string, nullable, required: The newest resolved session's classification: business, isp, mobile, hosting, education, government or unknown; null until one resolved.
    - `network_name` string, nullable, required: The organization behind the newest resolved session's address; null until one resolved.
    - `network_domain` string, nullable, required: The company domain the data service derived; null when none.
    - `asn` integer, nullable, required
    - `as_name` string, nullable, required
    - `is_internal` boolean, required: The newest session was internal (the site's ignored_ips, or an identified email of the team's own domains).
    - `created_at` string, required: ISO 8601 UTC.
    - `updated_at` string, required: ISO 8601 UTC.
  - `result` object, required
    - `was_bound` boolean, required: A bind was cleared; false on a visitor that was already unbound.
  - `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.

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