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

# Broadcasting app metadata

<View title="macOS" icon="apple">
  If you've [enabled the setting](/application-preferences/macos-preferences-screen-share#broadcast-app-metadata), Tuple will broadcast the window title and content URL of whatever app you have focused while you're sharing your screen. Participants who are [capturing the call](/pairing-with-tuple/capturing-calls) keep that metadata alongside the recording, so they end up with a history of the files and URLs you looked at. This also gives connected agents a quick way to understand what's on screen.

  ## Turning it on and off

  The setting is **Broadcast app metadata**, in [Screen share preferences](/application-preferences/macos-preferences-screen-share#broadcast-app-metadata). Tuple asks whether you want it on the first time you share your screen. This setting governs what leaves *your* machine; other participants control for themselves whether they want to capture this information or not.

  ## When metadata gets sent

  Tuple samples the focused window once a second, and broadcasts what it finds only after the same content survives two consecutive samples. A window you flick past is never sent, and content that stays put is normally sent one to two seconds after it appears.

  A separate 60-second window keeps content that flips back and forth from being sent over and over.

  ## What gets broadcast

  Each broadcast describes the focused window:

  * **`app`**: the app the window belongs to, as `id` (the bundle id) and `name` (what you'd see in the Dock).
  * **`title`**: the window's title.
  * **`url`**: what the window is showing, as a scheme'd URL. `http(s)://` for a web page, `file://` for a document.
  * **`window_id`**: an identifier for the window itself. It's only meaningful within one sharer's stream, where it tells "moved to a different window" apart from "same window, the title changed".

  ```json theme={null}
  {
    "app": { "id": "com.google.Chrome", "name": "Google Chrome" },
    "title": { "value": "PR #4212 · tupleapp/tuple" },
    "url": { "value": "https://github.com/tupleapp/tuple/pull/4212" },
    "window_id": 41235
  }
  ```

  `title` and `url` are objects rather than bare strings, because each one carries whether Tuple modified it before sending:

  | Shape                               | Meaning                                                                                                                                                        |
  | ----------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------- |
  | `{"value": "…"}`                    | Broadcast exactly as captured.                                                                                                                                 |
  | `{"value": "…", "redacted": true}`  | Something was removed from inside the value.                                                                                                                   |
  | `{"redacted": true}`                | The value was dropped entirely, as with a sign-in URL. This is distinct from the field being absent, which means there was nothing to send in the first place. |
  | `{"value": "…", "truncated": true}` | A title past 256 characters, clamped and ending in `…`.                                                                                                        |

  ### Veiled apps

  Apps hidden by [App Veil](/application-preferences/macos-preferences-app-veil) broadcast no **metadata at all**. A veiled app sends `{"veiled": true}` and nothing else.

  ### URL sanitization

  For an `http(s)` URL, Tuple drops the value entirely, broadcasts a scrubbed version, or broadcasts it unchanged.

  The value is **dropped entirely** — participants see that a URL was there and was redacted, with no value — when:

  * The host is a known identity provider, or a subdomain of one: Google Accounts, Microsoft login, Apple ID, Auth0, Okta, OneLogin, Ping, Duo, Atlassian ID, AWS sign-in and Cognito, Salesforce login, or Yahoo login. Matching respects domain boundaries, so `tuple.okta.com` matches `okta.com` but `notokta.com` doesn't.
  * The path contains an auth-related segment: variants of `login`, `signin`, `signup`, `register`, `oauth`, `auth`, `authorize`, `callback`, `sso`, `saml`, `verify`, `magic-link`, `reset-password`, `invite`, `activate`, `confirm`, `otp`, `2fa`, `mfa`, or `token`. Whole segments only, so `/auth/` matches and `/author/` doesn't.
  * The query or a parameter-shaped fragment carries `response_type`, `client_id`, and `redirect_uri` together, which is the signature of an OAuth authorization request.
  * The URL can't be parsed or safely re-serialized.

  Every other `http(s)` URL is **broadcast with credentials removed**:

  * Inline credentials get removed, as in `https://user:password@example.com/`.
  * Credential-shaped query parameters and fragment parameters go: OAuth codes and tokens, `state`, `nonce`, OTPs, tickets, SAML assertions, session IDs, signatures, API keys, passwords, JWT and auth fields, and S3 or GCS signed-URL credentials.
  * A signed S3 or GCS URL keeps its object path and its harmless metadata (algorithm, date, expiry) while losing the credential, session token, and signature.

  A URL that trips none of these rules is broadcast with its scheme, host, port, path, query, and fragment intact. Unrelated parameters stay, such as YouTube's `v` or `tab=overview`, and so do non-parameter fragments such as Gmail's `#inbox/<id>`. Non-`http(s)` URLs, `file://` among them, aren't scrubbed.

  ### Window title sanitization

  Titles get a similar treatment:

  * `KEY=value` and `KEY: value` assignments whose key names a credential — `PGPASSWORD`, `GITHUB_TOKEN`, `AWS_SECRET_ACCESS_KEY` — keep the key and replace the value with `•••`.
  * `Bearer <token>` headers and `scheme://user:password@host` connection strings are replaced the same way.
  * Tokens recognized by their shape alone are replaced whole: GitHub, GitLab, Slack, AWS, Stripe, npm, OpenAI, and Anthropic key prefixes, plus JWTs.
  * Titles longer than 256 characters are truncated, with a trailing `…` marking the cut.

  <Warning>
    Scrubbing is a curated set of heuristics, not a complete authentication detector. A secret can still get through: in an ordinary-looking path, under a parameter name Tuple doesn't recognize, on a company identity provider with an unfamiliar domain and path, or in a non-`http(s)` URL. For windows that should never be shared at all, use [App Veil](/application-preferences/macos-preferences-app-veil).
  </Warning>
</View>
